ia64/xen-unstable

changeset 12774:d603aed5ad6d

merge with xen-unstable.hg
author awilliam@xenbuild.aw
date Mon Dec 04 08:24:41 2006 -0700 (2006-12-04)
parents 6fdbf173142d 275a8f9a0710
children e729184b5c0e
files xen/arch/ia64/xen/Makefile xen/arch/x86/hvm/vmx/io.c xen/include/xen/softirq.h
line diff
     1.1 --- a/.hgignore	Sat Dec 02 15:19:50 2006 -0700
     1.2 +++ b/.hgignore	Mon Dec 04 08:24:41 2006 -0700
     1.3 @@ -158,6 +158,8 @@
     1.4  ^tools/xcutils/xc_restore$
     1.5  ^tools/xcutils/xc_save$
     1.6  ^tools/xcutils/readnotes$
     1.7 +^tools/xenfb/sdlfb$
     1.8 +^tools/xenfb/vncfb$
     1.9  ^tools/xenmon/xentrace_setmask$
    1.10  ^tools/xenmon/xenbaked$
    1.11  ^tools/xenstat/xentop/xentop$
     2.1 --- a/Config.mk	Sat Dec 02 15:19:50 2006 -0700
     2.2 +++ b/Config.mk	Mon Dec 04 08:24:41 2006 -0700
     2.3 @@ -69,8 +69,8 @@ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_
     2.4  
     2.5  # Optional components
     2.6  XENSTAT_XENTOP ?= y
     2.7 -
     2.8  VTPM_TOOLS ?= n
     2.9  LIBXENAPI_BINDINGS ?= n
    2.10 +XENFB_TOOLS ?= n
    2.11  
    2.12  -include $(XEN_ROOT)/.config
     3.1 --- a/buildconfigs/linux-defconfig_xen0_x86_32	Sat Dec 02 15:19:50 2006 -0700
     3.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_32	Mon Dec 04 08:24:41 2006 -0700
     3.3 @@ -179,6 +179,7 @@ CONFIG_HZ_100=y
     3.4  # CONFIG_HZ_250 is not set
     3.5  # CONFIG_HZ_1000 is not set
     3.6  CONFIG_HZ=100
     3.7 +CONFIG_KEXEC=y
     3.8  # CONFIG_CRASH_DUMP is not set
     3.9  CONFIG_PHYSICAL_START=0x100000
    3.10  
     4.1 --- a/buildconfigs/linux-defconfig_xen0_x86_64	Sat Dec 02 15:19:50 2006 -0700
     4.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_64	Mon Dec 04 08:24:41 2006 -0700
     4.3 @@ -126,6 +126,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
     4.4  # CONFIG_SPARSEMEM_STATIC is not set
     4.5  CONFIG_SPLIT_PTLOCK_CPUS=4096
     4.6  CONFIG_SWIOTLB=y
     4.7 +CONFIG_KEXEC=y
     4.8  # CONFIG_CRASH_DUMP is not set
     4.9  CONFIG_PHYSICAL_START=0x100000
    4.10  CONFIG_SECCOMP=y
     5.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Sat Dec 02 15:19:50 2006 -0700
     5.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Mon Dec 04 08:24:41 2006 -0700
     5.3 @@ -184,6 +184,7 @@ CONFIG_MTRR=y
     5.4  CONFIG_REGPARM=y
     5.5  CONFIG_SECCOMP=y
     5.6  CONFIG_HZ_100=y
     5.7 +CONFIG_KEXEC=y
     5.8  # CONFIG_HZ_250 is not set
     5.9  # CONFIG_HZ_1000 is not set
    5.10  CONFIG_HZ=100
    5.11 @@ -2776,6 +2777,7 @@ CONFIG_NTFS_FS=m
    5.12  #
    5.13  CONFIG_PROC_FS=y
    5.14  CONFIG_PROC_KCORE=y
    5.15 +# CONFIG_PROC_VMCORE is not set
    5.16  CONFIG_SYSFS=y
    5.17  CONFIG_TMPFS=y
    5.18  # CONFIG_HUGETLB_PAGE is not set
     6.1 --- a/buildconfigs/linux-defconfig_xen_x86_64	Sat Dec 02 15:19:50 2006 -0700
     6.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64	Mon Dec 04 08:24:41 2006 -0700
     6.3 @@ -139,6 +139,7 @@ CONFIG_SWIOTLB=y
     6.4  CONFIG_PHYSICAL_START=0x100000
     6.5  CONFIG_SECCOMP=y
     6.6  CONFIG_HZ_100=y
     6.7 +CONFIG_KEXEC=y
     6.8  # CONFIG_HZ_250 is not set
     6.9  # CONFIG_HZ_1000 is not set
    6.10  CONFIG_HZ=100
     7.1 --- a/docs/xen-api/presentation.tex	Sat Dec 02 15:19:50 2006 -0700
     7.2 +++ b/docs/xen-api/presentation.tex	Mon Dec 04 08:24:41 2006 -0700
     7.3 @@ -131,9 +131,6 @@ of that class that has the specified {\t
     7.4  ``{\tt get\_by\_name\_label(name)}'' RPC that returns a set of objects of that
     7.5  class that have the specified {\tt label}.
     7.6  
     7.7 -\item Each class has a ``{\tt to\_XML()}'' RPC that serialises the
     7.8 -state of all fields as an XML string.
     7.9 -
    7.10  \item Each class has a ``{\tt destroy(Ref x)}'' RPC that explicitly deletes
    7.11  the persistent object specified by {\tt x} from the system.  This is a
    7.12  non-cascading delete -- if the object being removed is referenced by another
    7.13 @@ -144,6 +141,6 @@ object then the {\tt destroy} call will 
    7.14  \subsection{Additional RPCs}
    7.15  
    7.16  As well as the RPCs enumerated above, some classes have additional RPCs
    7.17 -associated with them. For example, the {\tt VM} class have RPCs for cloning,
    7.18 +associated with them. For example, the {\tt VM} class has RPCs for cloning,
    7.19  suspending, starting etc. Such additional RPCs are described explicitly
    7.20  in the API reference.
     8.1 --- a/docs/xen-api/todo.tex	Sat Dec 02 15:19:50 2006 -0700
     8.2 +++ b/docs/xen-api/todo.tex	Mon Dec 04 08:24:41 2006 -0700
     8.3 @@ -35,6 +35,8 @@ code, potential error description, but o
     8.4  \item Clarify behaviour of progress field on asyncrhonous request polling when
     8.5  that request fails.
     8.6  
     8.7 +\item Clarify which calls have asynchronous counterparts by marking them as such in the reference. (Individual getters and setters are too small and quick to justify having async versions)
     8.8 +
     8.9  \end{itemize}
    8.10  
    8.11  \subsection{Content}
     9.1 --- a/docs/xen-api/wire-protocol.tex	Sat Dec 02 15:19:50 2006 -0700
     9.2 +++ b/docs/xen-api/wire-protocol.tex	Mon Dec 04 08:24:41 2006 -0700
     9.3 @@ -21,9 +21,9 @@ primitive XML-RPC types.
     9.4  In our API Reference we specify the signatures of API functions in the following
     9.5  style:
     9.6  \begin{verbatim}
     9.7 -    (ref_vm Set)   Host.ListAllVMs()
     9.8 +    (ref_vm Set)   VM.get_all()
     9.9  \end{verbatim}
    9.10 -This specifies that the function with name {\tt Host.ListAllVMs} takes
    9.11 +This specifies that the function with name {\tt VM.get\_all} takes
    9.12  no parameters and returns a Set of {\tt ref\_vm}s.
    9.13  These types are mapped onto XML-RPC types in a straight-forward manner:
    9.14  \begin{itemize}
    9.15 @@ -105,8 +105,8 @@ In the case where {\tt Status} is set to
    9.16  the struct contains a second element named {\tt ErrorDescription}:
    9.17  \begin{itemize}
    9.18  \item The element of the struct named {\tt ErrorDescription} contains
    9.19 -an array of string values. The first element of the array represents an error code;
    9.20 -the remainder of the array represents error parameters relating to that code.
    9.21 +an array of string values. The first element of the array is an XML-RPC 32-bit {\tt i4} and represents an error code;
    9.22 +the remainder of the array are strings representing error parameters relating to that code.
    9.23  \end{itemize}
    9.24  
    9.25  For example, an XML-RPC return value from the {\tt Host.ListAllVMs} function above
    9.26 @@ -161,19 +161,19 @@ A session can be terminated with the {\t
    9.27  
    9.28  \subsection{Synchronous and Asynchronous invocation}
    9.29  
    9.30 -Each method call (apart from those on ``Session'' and ``Task'' objects)
    9.31 +Each method call (apart from methods on ``Session'' and ``Task'' objects 
    9.32 +and ``getters'' and ``setters'' derived from fields)
    9.33  can be made either synchronously or asynchronously.
    9.34  A synchronous RPC call blocks until the
    9.35  return value is received; the return value of a synchronous RPC call is
    9.36  exactly as specified in Section~\ref{synchronous-result}.
    9.37  
    9.38 -Each of the methods specified in the API Reference is synchronous.
    9.39 -However, although not listed explicitly in this document, each
    9.40 -method call has an asynchronous analogue in the {\tt Async}
    9.41 -namespace. For example, synchronous call {\tt VM.Install(...)}
    9.42 +Only synchronous API calls are listed explicitly in this document. 
    9.43 +All asynchronous versions are in the special {\tt Async} namespace.
    9.44 +For example, synchronous call {\tt VM.clone(...)}
    9.45  (described in Chapter~\ref{api-reference})
    9.46  has an asynchronous counterpart, {\tt
    9.47 -Async.VM.Install(...)}, that is non-blocking.
    9.48 +Async.VM.clone(...)}, that is non-blocking.
    9.49  
    9.50  Instead of returning its result directly, an asynchronous RPC call
    9.51  returns a {\tt task-id}; this identifier is subsequently used
    9.52 @@ -186,39 +186,14 @@ is wrapped in an XML-RPC struct with a {
    9.53  The {\tt task-id} is provided in the {\tt Value} field if {\tt Status} is set to
    9.54  {\tt Success}.
    9.55  
    9.56 -Two special RPC calls are provided to poll the status of
    9.57 -asynchronous calls:
    9.58 +The RPC call
    9.59  \begin{verbatim}
    9.60 -    Array<task_id>  Async.Task.GetAllTasks (session_id s)
    9.61 -    task_status     Async.Task.GetStatus   (session_id s, task_id t)
    9.62 -\end{verbatim}
    9.63 -
    9.64 -{\tt Async.Task.GetAllTasks} returns a set of the currently
    9.65 -executing asynchronous tasks belong to the current user\footnote{
    9.66 -%
    9.67 -The current user is determined by the username that was provided
    9.68 -to {\tt Session.Login}.
    9.69 -%
    9.70 -}.
    9.71 -
    9.72 -{\tt Async.Task.GetStatus} returns a {\tt task\_status} result.
    9.73 -This is an XML-RPC struct with three elements:
    9.74 -\begin{itemize}
    9.75 -  \item The first element is named {\tt Progress} and contains
    9.76 -an {\tt Integer} between 0 and 100 representing the estimated percentage of
    9.77 -the task currently completed.
    9.78 -  \item The second element is named {\tt ETA} and contains a {\tt DateTime} 
    9.79 -representing the estimated time the task will be complete.
    9.80 -  \item The third element is named {\tt Result}. If {\tt Progress}
    9.81 -is not 100 then {\tt Result} contains the empty string. If {\tt Progress}
    9.82 -{\em is\/} set to 100, then {\tt Result} contains the function's return
    9.83 -result (as specified in Section~\ref{synchronous-result})\footnote{
    9.84 -%
    9.85 -Recall that this itself is a struct potentially containing status, errorcode,
    9.86 -value fields etc.
    9.87 -%
    9.88 -}.
    9.89 -\end{itemize}
    9.90 +    (ref_task Set)   Task.get_all(session_id s)
    9.91 +\end{verbatim} 
    9.92 +returns a set of all task IDs known to the system. The status (including any
    9.93 +returned result and error codes) of these tasks
    9.94 +can then be queried by accessing the fields of the Task object in the usual way. 
    9.95 +Note that, in order to get a consistent snapshot of a task's state, it is advisable to call the ``get\_record'' function.
    9.96  
    9.97  \section{Example interactive session}
    9.98  
    9.99 @@ -267,7 +242,8 @@ Next, the user may acquire a list of all
   9.100  \begin{verbatim}
   9.101  >>> all_vms = xen.VM.do_list(session)['Value']
   9.102  >>> all_vms
   9.103 -['b7b92d9e-d442-4710-92a5-ab039fd7d89b', '23e1e837-abbf-4675-b077-d4007989b0cc', '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2', '3202ae18-a046-4c32-9fda-e32e9631866e']
   9.104 +['b7b92d9e-d442-4710-92a5-ab039fd7d89b', '23e1e837-abbf-4675-b077-d4007989b0cc',
   9.105 +  '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2', '3202ae18-a046-4c32-9fda-e32e9631866e']
   9.106  \end{verbatim}
   9.107  
   9.108  Note the VM references are internally UUIDs. Once a reference to a VM has been acquired a lifecycle operation may be invoked:
    10.1 --- a/docs/xen-api/xenapi-datamodel-graph.dot	Sat Dec 02 15:19:50 2006 -0700
    10.2 +++ b/docs/xen-api/xenapi-datamodel-graph.dot	Mon Dec 04 08:24:41 2006 -0700
    10.3 @@ -1,5 +1,5 @@
    10.4  digraph g{
    10.5 -node [ shape=box ]; session [ URL="session.html" ] task [ URL="task.html" ] VM [ URL="VM.html" ] host [ URL="host.html" ] host_cpu [ URL="host_cpu.html" ] network [ URL="network.html" ] VIF [ URL="VIF.html" ] PIF [ URL="PIF.html" ] SR [ URL="SR.html" ] VDI [ URL="VDI.html" ] VBD [ URL="VBD.html" ] VTPM [ URL="VTPM.html" ] user [ URL="user.html" ] debug [ URL="debug.html" ];
    10.6 +node [ shape=box ]; session [ URL="session.html" ] task [ URL="task.html" ] VM [ URL="VM.html" ] host [ URL="host.html" ] host_cpu [ URL="host_cpu.html" ] network [ URL="network.html" ] VIF [ URL="VIF.html" ] PIF [ URL="PIF.html" ] SR [ URL="SR.html" ] VDI [ URL="VDI.html" ] VBD [ URL="VBD.html" ] VTPM [ URL="VTPM.html" ] console [ URL="console.html" ] user [ URL="user.html" ] debug [ URL="debug.html" ];
    10.7  session -> host [ label="this_host(1)" ]
    10.8  session -> user [ label="this_user(1)" ]
    10.9  host -> VM [ color="blue", arrowhead="crow", arrowtail="none" ]
   10.10 @@ -14,4 +14,5 @@ VDI -> VDI [ color="blue", arrowhead="no
   10.11  VBD -> VM [ color="blue", arrowhead="none", arrowtail="crow" ]
   10.12  VTPM -> VM [ label="backend(1)" ]
   10.13  VTPM -> VM [ color="blue", arrowhead="none", arrowtail="crow" ]
   10.14 +console -> VM [ color="blue", arrowhead="none", arrowtail="crow" ]
   10.15  }
    11.1 --- a/docs/xen-api/xenapi-datamodel.tex	Sat Dec 02 15:19:50 2006 -0700
    11.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Mon Dec 04 08:24:41 2006 -0700
    11.3 @@ -34,6 +34,7 @@ Name & Description \\
    11.4  {\tt VDI} & A virtual disk image \\
    11.5  {\tt VBD} & A virtual block device \\
    11.6  {\tt VTPM} & A virtual TPM device \\
    11.7 +{\tt console} & A console \\
    11.8  {\tt user} & A user of the system \\
    11.9  {\tt debug} & A basic class for testing \\
   11.10  \hline
   11.11 @@ -54,6 +55,7 @@ PIF.host & host.PIFs & one-to-many\\
   11.12  PIF.network & network.PIFs & one-to-many\\
   11.13  SR.VDIs & VDI.SR & many-to-one\\
   11.14  VTPM.VM & VM.VTPMs & one-to-many\\
   11.15 +console.VM & VM.consoles & one-to-many\\
   11.16  host.resident\_VMs & VM.resident\_on & many-to-one\\
   11.17  host.host\_CPUs & host\_cpu.host & many-to-one\\
   11.18  \hline
   11.19 @@ -99,6 +101,16 @@ The following enumeration types are used
   11.20  
   11.21  \begin{longtable}{|ll|}
   11.22  \hline
   11.23 +{\tt enum console\_protocol} & \\
   11.24 +\hline
   11.25 +\hspace{0.5cm}{\tt vt100} & VT100 terminal \\
   11.26 +\hspace{0.5cm}{\tt rfb} & Remote FrameBuffer protocol (as used in VNC) \\
   11.27 +\hspace{0.5cm}{\tt rdp} & Remote Desktop Protocol \\
   11.28 +\hline
   11.29 +\end{longtable}
   11.30 +
   11.31 +\begin{longtable}{|ll|}
   11.32 +\hline
   11.33  {\tt enum vdi\_type} & \\
   11.34  \hline
   11.35  \hspace{0.5cm}{\tt system} & a disk that may be replaced on upgrade \\
   11.36 @@ -947,6 +959,7 @@ Quals & Field & Type & Description \\
   11.37  $\mathit{RW}$ &  {\tt actions/after\_reboot} & on\_normal\_exit & action to take after the guest has rebooted itself \\
   11.38  $\mathit{RW}$ &  {\tt actions/after\_suspend} & on\_normal\_exit & action to take after the guest has suspended itself \\
   11.39  $\mathit{RW}$ &  {\tt actions/after\_crash} & on\_crash\_behaviour & action to take if the guest crashes \\
   11.40 +$\mathit{RO}_\mathit{run}$ &  {\tt consoles} & (console ref) Set & virtual console devices \\
   11.41  $\mathit{RO}_\mathit{run}$ &  {\tt VIFs} & (VIF ref) Set & virtual network interfaces \\
   11.42  $\mathit{RO}_\mathit{run}$ &  {\tt VBDs} & (VBD ref) Set & virtual block devices \\
   11.43  $\mathit{RO}_\mathit{run}$ &  {\tt VTPMs} & (VTPM ref) Set & virtual TPMs \\
   11.44 @@ -2631,6 +2644,38 @@ void
   11.45  \vspace{0.3cm}
   11.46  \vspace{0.3cm}
   11.47  \vspace{0.3cm}
   11.48 +\subsubsection{RPC name:~get\_consoles}
   11.49 +
   11.50 +{\bf Overview:} 
   11.51 +Get the consoles field of the given VM.
   11.52 +
   11.53 + \noindent {\bf Signature:} 
   11.54 +\begin{verbatim} ((console ref) Set) get_consoles (session_id s, VM ref self)\end{verbatim}
   11.55 +
   11.56 +
   11.57 +\noindent{\bf Arguments:}
   11.58 +
   11.59 + 
   11.60 +\vspace{0.3cm}
   11.61 +\begin{tabular}{|c|c|p{7cm}|}
   11.62 + \hline
   11.63 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   11.64 +{\tt VM ref } & self & object instance \\ \hline 
   11.65 +
   11.66 +\end{tabular}
   11.67 +
   11.68 +\vspace{0.3cm}
   11.69 +
   11.70 + \noindent {\bf Return Type:} 
   11.71 +{\tt 
   11.72 +(console ref) Set
   11.73 +}
   11.74 +
   11.75 +
   11.76 +value of the field
   11.77 +\vspace{0.3cm}
   11.78 +\vspace{0.3cm}
   11.79 +\vspace{0.3cm}
   11.80  \subsubsection{RPC name:~get\_VIFs}
   11.81  
   11.82  {\bf Overview:} 
   11.83 @@ -9187,6 +9232,281 @@ all fields from the object
   11.84  
   11.85  \vspace{1cm}
   11.86  \newpage
   11.87 +\section{Class: console}
   11.88 +\subsection{Fields for class: console}
   11.89 +\begin{longtable}{|lllp{0.38\textwidth}|}
   11.90 +\hline
   11.91 +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf console} \\
   11.92 +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A console}} \\
   11.93 +\hline
   11.94 +Quals & Field & Type & Description \\
   11.95 +\hline
   11.96 +$\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
   11.97 +$\mathit{RO}_\mathit{run}$ &  {\tt protocol} & console\_protocol & the protocol used by this console \\
   11.98 +$\mathit{RO}_\mathit{run}$ &  {\tt uri} & string & URI for the console service \\
   11.99 +$\mathit{RO}_\mathit{run}$ &  {\tt VM} & VM ref & VM to which this console is attached \\
  11.100 +\hline
  11.101 +\end{longtable}
  11.102 +\subsection{Additional RPCs associated with class: console}
  11.103 +\subsubsection{RPC name:~get\_record}
  11.104 +
  11.105 +{\bf Overview:} 
  11.106 +Get the current state of the given console.
  11.107 +
  11.108 + \noindent {\bf Signature:} 
  11.109 +\begin{verbatim} (console record) get_record (session_id s, console ref self)\end{verbatim}
  11.110 +
  11.111 +
  11.112 +\noindent{\bf Arguments:}
  11.113 +
  11.114 + 
  11.115 +\vspace{0.3cm}
  11.116 +\begin{tabular}{|c|c|p{7cm}|}
  11.117 + \hline
  11.118 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  11.119 +{\tt console ref } & self & reference to the object \\ \hline 
  11.120 +
  11.121 +\end{tabular}
  11.122 +
  11.123 +\vspace{0.3cm}
  11.124 +
  11.125 + \noindent {\bf Return Type:} 
  11.126 +{\tt 
  11.127 +console record
  11.128 +}
  11.129 +
  11.130 +
  11.131 +all fields from the object
  11.132 +\vspace{0.3cm}
  11.133 +\vspace{0.3cm}
  11.134 +\vspace{0.3cm}
  11.135 +\subsubsection{RPC name:~get\_by\_uuid}
  11.136 +
  11.137 +{\bf Overview:} 
  11.138 +Get a reference to the object with the specified UUID.
  11.139 +
  11.140 + \noindent {\bf Signature:} 
  11.141 +\begin{verbatim} (console ref) get_by_uuid (session_id s, string uuid)\end{verbatim}
  11.142 +
  11.143 +
  11.144 +\noindent{\bf Arguments:}
  11.145 +
  11.146 + 
  11.147 +\vspace{0.3cm}
  11.148 +\begin{tabular}{|c|c|p{7cm}|}
  11.149 + \hline
  11.150 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  11.151 +{\tt string } & uuid & UUID of object to return \\ \hline 
  11.152 +
  11.153 +\end{tabular}
  11.154 +
  11.155 +\vspace{0.3cm}
  11.156 +
  11.157 + \noindent {\bf Return Type:} 
  11.158 +{\tt 
  11.159 +console ref
  11.160 +}
  11.161 +
  11.162 +
  11.163 +reference to the object
  11.164 +\vspace{0.3cm}
  11.165 +\vspace{0.3cm}
  11.166 +\vspace{0.3cm}
  11.167 +\subsubsection{RPC name:~create}
  11.168 +
  11.169 +{\bf Overview:} 
  11.170 +Create a new console instance, and return its handle.
  11.171 +
  11.172 + \noindent {\bf Signature:} 
  11.173 +\begin{verbatim} (console ref) create (session_id s, console record args)\end{verbatim}
  11.174 +
  11.175 +
  11.176 +\noindent{\bf Arguments:}
  11.177 +
  11.178 + 
  11.179 +\vspace{0.3cm}
  11.180 +\begin{tabular}{|c|c|p{7cm}|}
  11.181 + \hline
  11.182 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  11.183 +{\tt console record } & args & All constructor arguments \\ \hline 
  11.184 +
  11.185 +\end{tabular}
  11.186 +
  11.187 +\vspace{0.3cm}
  11.188 +
  11.189 + \noindent {\bf Return Type:} 
  11.190 +{\tt 
  11.191 +console ref
  11.192 +}
  11.193 +
  11.194 +
  11.195 +reference to the newly created object
  11.196 +\vspace{0.3cm}
  11.197 +\vspace{0.3cm}
  11.198 +\vspace{0.3cm}
  11.199 +\subsubsection{RPC name:~destroy}
  11.200 +
  11.201 +{\bf Overview:} 
  11.202 +Destroy the specified console instance.
  11.203 +
  11.204 + \noindent {\bf Signature:} 
  11.205 +\begin{verbatim} void destroy (session_id s, console ref self)\end{verbatim}
  11.206 +
  11.207 +
  11.208 +\noindent{\bf Arguments:}
  11.209 +
  11.210 + 
  11.211 +\vspace{0.3cm}
  11.212 +\begin{tabular}{|c|c|p{7cm}|}
  11.213 + \hline
  11.214 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  11.215 +{\tt console ref } & self & object instance \\ \hline 
  11.216 +
  11.217 +\end{tabular}
  11.218 +
  11.219 +\vspace{0.3cm}
  11.220 +
  11.221 + \noindent {\bf Return Type:} 
  11.222 +{\tt 
  11.223 +void
  11.224 +}
  11.225 +
  11.226 +
  11.227 +
  11.228 +\vspace{0.3cm}
  11.229 +\vspace{0.3cm}
  11.230 +\vspace{0.3cm}
  11.231 +\subsubsection{RPC name:~get\_uuid}
  11.232 +
  11.233 +{\bf Overview:} 
  11.234 +Get the uuid field of the given console.
  11.235 +
  11.236 + \noindent {\bf Signature:} 
  11.237 +\begin{verbatim} string get_uuid (session_id s, console ref self)\end{verbatim}
  11.238 +
  11.239 +
  11.240 +\noindent{\bf Arguments:}
  11.241 +
  11.242 + 
  11.243 +\vspace{0.3cm}
  11.244 +\begin{tabular}{|c|c|p{7cm}|}
  11.245 + \hline
  11.246 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  11.247 +{\tt console ref } & self & object instance \\ \hline 
  11.248 +
  11.249 +\end{tabular}
  11.250 +
  11.251 +\vspace{0.3cm}
  11.252 +
  11.253 + \noindent {\bf Return Type:} 
  11.254 +{\tt 
  11.255 +string
  11.256 +}
  11.257 +
  11.258 +
  11.259 +value of the field
  11.260 +\vspace{0.3cm}
  11.261 +\vspace{0.3cm}
  11.262 +\vspace{0.3cm}
  11.263 +\subsubsection{RPC name:~get\_protocol}
  11.264 +
  11.265 +{\bf Overview:} 
  11.266 +Get the protocol field of the given console.
  11.267 +
  11.268 + \noindent {\bf Signature:} 
  11.269 +\begin{verbatim} (console_protocol) get_protocol (session_id s, console ref self)\end{verbatim}
  11.270 +
  11.271 +
  11.272 +\noindent{\bf Arguments:}
  11.273 +
  11.274 + 
  11.275 +\vspace{0.3cm}
  11.276 +\begin{tabular}{|c|c|p{7cm}|}
  11.277 + \hline
  11.278 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  11.279 +{\tt console ref } & self & object instance \\ \hline 
  11.280 +
  11.281 +\end{tabular}
  11.282 +
  11.283 +\vspace{0.3cm}
  11.284 +
  11.285 + \noindent {\bf Return Type:} 
  11.286 +{\tt 
  11.287 +console\_protocol
  11.288 +}
  11.289 +
  11.290 +
  11.291 +value of the field
  11.292 +\vspace{0.3cm}
  11.293 +\vspace{0.3cm}
  11.294 +\vspace{0.3cm}
  11.295 +\subsubsection{RPC name:~get\_uri}
  11.296 +
  11.297 +{\bf Overview:} 
  11.298 +Get the uri field of the given console.
  11.299 +
  11.300 + \noindent {\bf Signature:} 
  11.301 +\begin{verbatim} string get_uri (session_id s, console ref self)\end{verbatim}
  11.302 +
  11.303 +
  11.304 +\noindent{\bf Arguments:}
  11.305 +
  11.306 + 
  11.307 +\vspace{0.3cm}
  11.308 +\begin{tabular}{|c|c|p{7cm}|}
  11.309 + \hline
  11.310 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  11.311 +{\tt console ref } & self & object instance \\ \hline 
  11.312 +
  11.313 +\end{tabular}
  11.314 +
  11.315 +\vspace{0.3cm}
  11.316 +
  11.317 + \noindent {\bf Return Type:} 
  11.318 +{\tt 
  11.319 +string
  11.320 +}
  11.321 +
  11.322 +
  11.323 +value of the field
  11.324 +\vspace{0.3cm}
  11.325 +\vspace{0.3cm}
  11.326 +\vspace{0.3cm}
  11.327 +\subsubsection{RPC name:~get\_VM}
  11.328 +
  11.329 +{\bf Overview:} 
  11.330 +Get the VM field of the given console.
  11.331 +
  11.332 + \noindent {\bf Signature:} 
  11.333 +\begin{verbatim} (VM ref) get_VM (session_id s, console ref self)\end{verbatim}
  11.334 +
  11.335 +
  11.336 +\noindent{\bf Arguments:}
  11.337 +
  11.338 + 
  11.339 +\vspace{0.3cm}
  11.340 +\begin{tabular}{|c|c|p{7cm}|}
  11.341 + \hline
  11.342 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  11.343 +{\tt console ref } & self & object instance \\ \hline 
  11.344 +
  11.345 +\end{tabular}
  11.346 +
  11.347 +\vspace{0.3cm}
  11.348 +
  11.349 + \noindent {\bf Return Type:} 
  11.350 +{\tt 
  11.351 +VM ref
  11.352 +}
  11.353 +
  11.354 +
  11.355 +value of the field
  11.356 +\vspace{0.3cm}
  11.357 +\vspace{0.3cm}
  11.358 +\vspace{0.3cm}
  11.359 +
  11.360 +\vspace{1cm}
  11.361 +\newpage
  11.362  \section{Class: user}
  11.363  \subsection{Fields for class: user}
  11.364  \begin{longtable}{|lllp{0.38\textwidth}|}
    12.1 --- a/extras/mini-os/events.c	Sat Dec 02 15:19:50 2006 -0700
    12.2 +++ b/extras/mini-os/events.c	Mon Dec 04 08:24:41 2006 -0700
    12.3 @@ -31,26 +31,27 @@ typedef struct _ev_action_t {
    12.4      u32 count;
    12.5  } ev_action_t;
    12.6  
    12.7 -
    12.8  static ev_action_t ev_actions[NR_EVS];
    12.9  void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);
   12.10  
   12.11 +static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))];
   12.12 +
   12.13  void unbind_all_ports(void)
   12.14  {
   12.15      int i;
   12.16  
   12.17 -	for(i=0;i<NR_EVS;i++)
   12.18 -	{
   12.19 -		if(ev_actions[i].handler != default_handler)
   12.20 -		{
   12.21 -			struct evtchn_close close;
   12.22 -			mask_evtchn(i);
   12.23 -			close.port = i;
   12.24 -			HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
   12.25 -		}
   12.26 -	}
   12.27 +    for (i = 0; i < NR_EVS; i++)
   12.28 +    {
   12.29 +        if (test_and_clear_bit(i, bound_ports))
   12.30 +        {
   12.31 +            struct evtchn_close close;
   12.32 +            mask_evtchn(i);
   12.33 +            close.port = i;
   12.34 +            HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
   12.35 +        }
   12.36 +    }
   12.37  }
   12.38 -
   12.39 +  
   12.40  /*
   12.41   * Demux events to different handlers.
   12.42   */
   12.43 @@ -114,6 +115,7 @@ int bind_virq(uint32_t virq, evtchn_hand
   12.44  		printk("Failed to bind virtual IRQ %d\n", virq);
   12.45  		return 1;
   12.46      }
   12.47 +    set_bit(op.port,bound_ports);
   12.48      bind_evtchn(op.port, handler, data);
   12.49  	return 0;
   12.50  }
   12.51 @@ -188,6 +190,7 @@ int evtchn_bind_interdomain(domid_t pal,
   12.52      int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
   12.53      if (err)
   12.54  		return err;
   12.55 +    set_bit(op.local_port,bound_ports);
   12.56  	evtchn_port_t port = op.local_port;
   12.57      clear_evtchn(port);	      /* Without, handler gets invoked now! */
   12.58      *local_port = bind_evtchn(port, handler, data);
    13.1 --- a/extras/mini-os/include/events.h	Sat Dec 02 15:19:50 2006 -0700
    13.2 +++ b/extras/mini-os/include/events.h	Mon Dec 04 08:24:41 2006 -0700
    13.3 @@ -36,6 +36,7 @@ int evtchn_alloc_unbound(domid_t pal, ev
    13.4  int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
    13.5  							evtchn_handler_t handler, void *data,
    13.6  							evtchn_port_t *local_port);
    13.7 +void unbind_all_ports(void);
    13.8  
    13.9  static inline int notify_remote_via_evtchn(evtchn_port_t port)
   13.10  {
    14.1 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig	Sat Dec 02 15:19:50 2006 -0700
    14.2 +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig	Mon Dec 04 08:24:41 2006 -0700
    14.3 @@ -726,7 +726,7 @@ source kernel/Kconfig.hz
    14.4  
    14.5  config KEXEC
    14.6  	bool "kexec system call (EXPERIMENTAL)"
    14.7 -	depends on EXPERIMENTAL && !X86_XEN
    14.8 +	depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST
    14.9  	help
   14.10  	  kexec is a system call that implements the ability to shutdown your
   14.11  	  current kernel, and to start another kernel.  It is like a reboot
    15.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Sat Dec 02 15:19:50 2006 -0700
    15.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Mon Dec 04 08:24:41 2006 -0700
    15.3 @@ -69,6 +69,10 @@
    15.4  #include "setup_arch_pre.h"
    15.5  #include <bios_ebda.h>
    15.6  
    15.7 +#ifdef CONFIG_XEN
    15.8 +#include <xen/interface/kexec.h>
    15.9 +#endif
   15.10 +
   15.11  /* Forward Declaration. */
   15.12  void __init find_max_pfn(void);
   15.13  
   15.14 @@ -943,6 +947,7 @@ static void __init parse_cmdline_early (
   15.15  		 * after a kernel panic.
   15.16  		 */
   15.17  		else if (!memcmp(from, "crashkernel=", 12)) {
   15.18 +#ifndef CONFIG_XEN
   15.19  			unsigned long size, base;
   15.20  			size = memparse(from+12, &from);
   15.21  			if (*from == '@') {
   15.22 @@ -953,6 +958,10 @@ static void __init parse_cmdline_early (
   15.23  				crashk_res.start = base;
   15.24  				crashk_res.end   = base + size - 1;
   15.25  			}
   15.26 +#else
   15.27 +			printk("Ignoring crashkernel command line, "
   15.28 +			       "parameter will be supplied by xen\n");
   15.29 +#endif
   15.30  		}
   15.31  #endif
   15.32  #ifdef CONFIG_PROC_VMCORE
   15.33 @@ -1322,10 +1331,14 @@ void __init setup_bootmem_allocator(void
   15.34  	}
   15.35  #endif
   15.36  #ifdef CONFIG_KEXEC
   15.37 +#ifdef CONFIG_XEN
   15.38 +	xen_machine_kexec_setup_resources();
   15.39 +#else
   15.40  	if (crashk_res.start != crashk_res.end)
   15.41  		reserve_bootmem(crashk_res.start,
   15.42  			crashk_res.end - crashk_res.start + 1);
   15.43  #endif
   15.44 +#endif
   15.45  
   15.46  	if (!xen_feature(XENFEAT_auto_translated_physmap))
   15.47  		phys_to_machine_mapping =
   15.48 @@ -1389,7 +1402,11 @@ legacy_init_iomem_resources(struct e820e
   15.49  			request_resource(res, data_resource);
   15.50  #endif
   15.51  #ifdef CONFIG_KEXEC
   15.52 -			request_resource(res, &crashk_res);
   15.53 +			if (crashk_res.start != crashk_res.end)
   15.54 +			     request_resource(res, &crashk_res);
   15.55 +#ifdef CONFIG_XEN
   15.56 +			xen_machine_kexec_register_resources(res);
   15.57 +#endif
   15.58  #endif
   15.59  		}
   15.60  	}
   15.61 @@ -1850,9 +1867,11 @@ void __init setup_arch(char **cmdline_p)
   15.62  #endif
   15.63  #endif
   15.64  	} else {
   15.65 -		extern int console_use_vt;
   15.66 -		console_use_vt = 0;
   15.67 +#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
   15.68 +		conswitchp = &dummy_con;
   15.69 +#endif
   15.70  	}
   15.71 +	xencons_early_setup();
   15.72  }
   15.73  
   15.74  static int
    16.1 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c	Sat Dec 02 15:19:50 2006 -0700
    16.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c	Mon Dec 04 08:24:41 2006 -0700
    16.3 @@ -550,14 +550,16 @@ setup_arch (char **cmdline_p)
    16.4  		       xen_start_info->nr_pages, xen_start_info->flags);
    16.5  
    16.6  		if (!is_initial_xendomain()) {
    16.7 -			extern int console_use_vt;
    16.8 +#if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE)
    16.9  			conswitchp = NULL;
   16.10 -			console_use_vt = 0;
   16.11 +#endif
   16.12  		}
   16.13  	}
   16.14 +	xencons_early_setup();
   16.15  #endif
   16.16  #endif
   16.17  
   16.18 +
   16.19  	/* enable IA-64 Machine Check Abort Handling unless disabled */
   16.20  	if (!strstr(saved_command_line, "nomca"))
   16.21  		ia64_mca_init();
    17.1 --- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig	Sat Dec 02 15:19:50 2006 -0700
    17.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig	Mon Dec 04 08:24:41 2006 -0700
    17.3 @@ -435,7 +435,7 @@ config X86_MCE_AMD
    17.4  
    17.5  config KEXEC
    17.6  	bool "kexec system call (EXPERIMENTAL)"
    17.7 -	depends on EXPERIMENTAL && !X86_64_XEN
    17.8 +	depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST
    17.9  	help
   17.10  	  kexec is a system call that implements the ability to shutdown your
   17.11  	  current kernel, and to start another kernel.  It is like a reboot
    18.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Sat Dec 02 15:19:50 2006 -0700
    18.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Mon Dec 04 08:24:41 2006 -0700
    18.3 @@ -260,7 +260,11 @@ void __init e820_reserve_resources(struc
    18.4  			request_resource(res, &data_resource);
    18.5  #endif
    18.6  #ifdef CONFIG_KEXEC
    18.7 -			request_resource(res, &crashk_res);
    18.8 +			if (crashk_res.start != crashk_res.end)
    18.9 +				request_resource(res, &crashk_res);
   18.10 +#ifdef CONFIG_XEN
   18.11 +			xen_machine_kexec_register_resources(res);
   18.12 +#endif
   18.13  #endif
   18.14  		}
   18.15  	}
    19.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Sat Dec 02 15:19:50 2006 -0700
    19.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Mon Dec 04 08:24:41 2006 -0700
    19.3 @@ -80,6 +80,10 @@
    19.4  #include <asm/mach-xen/setup_arch_post.h>
    19.5  #include <xen/interface/memory.h>
    19.6  
    19.7 +#ifdef CONFIG_XEN
    19.8 +#include <xen/interface/kexec.h>
    19.9 +#endif
   19.10 +
   19.11  extern unsigned long start_pfn;
   19.12  extern struct edid_info edid_info;
   19.13  
   19.14 @@ -450,6 +454,7 @@ static __init void parse_cmdline_early (
   19.15  		 * after a kernel panic.
   19.16  		 */
   19.17  		else if (!memcmp(from, "crashkernel=", 12)) {
   19.18 +#ifndef CONFIG_XEN
   19.19  			unsigned long size, base;
   19.20  			size = memparse(from+12, &from);
   19.21  			if (*from == '@') {
   19.22 @@ -460,6 +465,10 @@ static __init void parse_cmdline_early (
   19.23  				crashk_res.start = base;
   19.24  				crashk_res.end   = base + size - 1;
   19.25  			}
   19.26 +#else
   19.27 +			printk("Ignoring crashkernel command line, "
   19.28 +			       "parameter will be supplied by xen\n");
   19.29 +#endif
   19.30  		}
   19.31  #endif
   19.32  
   19.33 @@ -812,11 +821,15 @@ void __init setup_arch(char **cmdline_p)
   19.34  #endif
   19.35  #endif	/* !CONFIG_XEN */
   19.36  #ifdef CONFIG_KEXEC
   19.37 +#ifdef CONFIG_XEN
   19.38 +	xen_machine_kexec_setup_resources();
   19.39 +#else
   19.40  	if (crashk_res.start != crashk_res.end) {
   19.41  		reserve_bootmem(crashk_res.start,
   19.42  			crashk_res.end - crashk_res.start + 1);
   19.43  	}
   19.44  #endif
   19.45 +#endif
   19.46  
   19.47  	paging_init();
   19.48  #ifdef CONFIG_X86_LOCAL_APIC
   19.49 @@ -970,10 +983,12 @@ void __init setup_arch(char **cmdline_p)
   19.50  #endif
   19.51  #endif
   19.52  		} else {
   19.53 -			extern int console_use_vt;
   19.54 -			console_use_vt = 0;
   19.55 -		}
   19.56 +#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
   19.57 +			conswitchp = &dummy_con;
   19.58 +#endif
   19.59 +                }
   19.60  	}
   19.61 +	xencons_early_setup();
   19.62  #else	/* CONFIG_XEN */
   19.63  
   19.64  #ifdef CONFIG_VT
    20.1 --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig	Sat Dec 02 15:19:50 2006 -0700
    20.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig	Mon Dec 04 08:24:41 2006 -0700
    20.3 @@ -172,6 +172,29 @@ config XEN_NETDEV_FRONTEND
    20.4  	  dedicated device-driver domain, or your master control domain
    20.5  	  (domain 0), then you almost certainly want to say Y here.
    20.6  
    20.7 +config XEN_FRAMEBUFFER
    20.8 +	tristate "Framebuffer-device frontend driver"
    20.9 +	depends on XEN && FB
   20.10 +	select FB_CFB_FILLRECT
   20.11 +	select FB_CFB_COPYAREA
   20.12 +	select FB_CFB_IMAGEBLIT
   20.13 +	default y
   20.14 +	help
   20.15 +	  The framebuffer-device frontend drivers allows the kernel to create a
   20.16 +	  virtual framebuffer.  This framebuffer can be viewed in another
   20.17 +	  domain.  Unless this domain has access to a real video card, you
   20.18 +	  probably want to say Y here.
   20.19 +
   20.20 +config XEN_KEYBOARD
   20.21 +	tristate "Keyboard-device frontend driver"
   20.22 +	depends on XEN && XEN_FRAMEBUFFER && INPUT
   20.23 +	default y
   20.24 +	help
   20.25 +	  The keyboard-device frontend driver allows the kernel to create a
   20.26 +	  virtual keyboard.  This keyboard can then be driven by another
   20.27 +	  domain.  If you've said Y to CONFIG_XEN_FRAMEBUFFER, you probably
   20.28 +	  want to say Y here.
   20.29 +
   20.30  config XEN_SCRUB_PAGES
   20.31  	bool "Scrub memory before freeing it to Xen"
   20.32  	default y
    21.1 --- a/linux-2.6-xen-sparse/drivers/xen/Makefile	Sat Dec 02 15:19:50 2006 -0700
    21.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile	Mon Dec 04 08:24:41 2006 -0700
    21.3 @@ -15,3 +15,5 @@ obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= blk
    21.4  obj-$(CONFIG_XEN_NETDEV_FRONTEND)	+= netfront/
    21.5  obj-$(CONFIG_XEN_PCIDEV_BACKEND)	+= pciback/
    21.6  obj-$(CONFIG_XEN_PCIDEV_FRONTEND)	+= pcifront/
    21.7 +obj-$(CONFIG_XEN_FRAMEBUFFER)		+= fbfront/
    21.8 +obj-$(CONFIG_XEN_KEYBOARD)		+= fbfront/
    22.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Sat Dec 02 15:19:50 2006 -0700
    22.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Mon Dec 04 08:24:41 2006 -0700
    22.3 @@ -359,7 +359,7 @@ static void blkfront_closing(struct xenb
    22.4  	DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
    22.5  
    22.6  	if (info->rq == NULL)
    22.7 -		return;
    22.8 +		goto out;
    22.9  
   22.10  	spin_lock_irqsave(&blkif_io_lock, flags);
   22.11  	/* No more blkif_request(). */
   22.12 @@ -373,6 +373,7 @@ static void blkfront_closing(struct xenb
   22.13  
   22.14  	xlvbd_del(info);
   22.15  
   22.16 + out:
   22.17  	xenbus_frontend_closed(dev);
   22.18  }
   22.19  
    23.1 --- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c	Sat Dec 02 15:19:50 2006 -0700
    23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c	Mon Dec 04 08:24:41 2006 -0700
    23.3 @@ -147,7 +147,7 @@ static inline int uncached_access(struct
    23.4  	return 0;
    23.5  }
    23.6  
    23.7 -static int mmap_mem(struct file * file, struct vm_area_struct * vma)
    23.8 +static int xen_mmap_mem(struct file * file, struct vm_area_struct * vma)
    23.9  {
   23.10  	size_t size = vma->vm_end - vma->vm_start;
   23.11  
   23.12 @@ -200,6 +200,6 @@ struct file_operations mem_fops = {
   23.13  	.llseek		= memory_lseek,
   23.14  	.read		= read_mem,
   23.15  	.write		= write_mem,
   23.16 -	.mmap		= mmap_mem,
   23.17 +	.mmap		= xen_mmap_mem,
   23.18  	.open		= open_mem,
   23.19  };
    24.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c	Sat Dec 02 15:19:50 2006 -0700
    24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c	Mon Dec 04 08:24:41 2006 -0700
    24.3 @@ -57,6 +57,7 @@
    24.4  #include <xen/interface/event_channel.h>
    24.5  #include <asm/hypervisor.h>
    24.6  #include <xen/evtchn.h>
    24.7 +#include <xen/xenbus.h>
    24.8  #include <xen/xencons.h>
    24.9  
   24.10  /*
   24.11 @@ -65,14 +66,14 @@
   24.12   *  'xencons=tty'  [XC_TTY]:     Console attached to '/dev/tty[0-9]+'.
   24.13   *  'xencons=ttyS' [XC_SERIAL]:  Console attached to '/dev/ttyS[0-9]+'.
   24.14   *  'xencons=xvc'  [XC_XVC]:     Console attached to '/dev/xvc0'.
   24.15 - *                 [XC_DEFAULT]: DOM0 -> XC_SERIAL ; all others -> XC_TTY.
   24.16 + *  default:                     DOM0 -> XC_SERIAL ; all others -> XC_TTY.
   24.17   * 
   24.18   * NB. In mode XC_TTY, we create dummy consoles for tty2-63. This suppresses
   24.19   * warnings from standard distro startup scripts.
   24.20   */
   24.21  static enum {
   24.22 -	XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL, XC_XVC
   24.23 -} xc_mode = XC_DEFAULT;
   24.24 +	XC_OFF, XC_TTY, XC_SERIAL, XC_XVC
   24.25 +} xc_mode;
   24.26  static int xc_num = -1;
   24.27  
   24.28  /* /dev/xvc0 device number allocated by lanana.org. */
   24.29 @@ -84,17 +85,32 @@ static unsigned long sysrq_requested;
   24.30  extern int sysrq_enabled;
   24.31  #endif
   24.32  
   24.33 +void xencons_early_setup(void)
   24.34 +{
   24.35 +	extern int console_use_vt;
   24.36 +
   24.37 +	if (is_initial_xendomain()) {
   24.38 +		xc_mode = XC_SERIAL;
   24.39 +	} else {
   24.40 +		xc_mode = XC_TTY;
   24.41 +		console_use_vt = 0;
   24.42 +	}
   24.43 +}
   24.44 +
   24.45  static int __init xencons_setup(char *str)
   24.46  {
   24.47  	char *q;
   24.48  	int n;
   24.49 +	extern int console_use_vt;
   24.50  
   24.51 +	console_use_vt = 1;
   24.52  	if (!strncmp(str, "ttyS", 4)) {
   24.53  		xc_mode = XC_SERIAL;
   24.54  		str += 4;
   24.55  	} else if (!strncmp(str, "tty", 3)) {
   24.56  		xc_mode = XC_TTY;
   24.57  		str += 3;
   24.58 +		console_use_vt = 0;
   24.59  	} else if (!strncmp(str, "xvc", 3)) {
   24.60  		xc_mode = XC_XVC;
   24.61  		str += 3;
   24.62 @@ -192,14 +208,10 @@ static int __init xen_console_init(void)
   24.63  		goto out;
   24.64  
   24.65  	if (is_initial_xendomain()) {
   24.66 -		if (xc_mode == XC_DEFAULT)
   24.67 -			xc_mode = XC_SERIAL;
   24.68  		kcons_info.write = kcons_write_dom0;
   24.69  	} else {
   24.70  		if (!xen_start_info->console.domU.evtchn)
   24.71  			goto out;
   24.72 -		if (xc_mode == XC_DEFAULT)
   24.73 -			xc_mode = XC_TTY;
   24.74  		kcons_info.write = kcons_write;
   24.75  	}
   24.76  
    25.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile	Sat Dec 02 15:19:50 2006 -0700
    25.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile	Mon Dec 04 08:24:41 2006 -0700
    25.3 @@ -11,3 +11,4 @@ obj-$(CONFIG_XEN_SYSFS)		+= xen_sysfs.o
    25.4  obj-$(CONFIG_XEN_SKBUFF)	+= skbuff.o
    25.5  obj-$(CONFIG_XEN_REBOOT)	+= reboot.o machine_reboot.o
    25.6  obj-$(CONFIG_XEN_SMPBOOT)	+= smpboot.o
    25.7 +obj-$(CONFIG_KEXEC)		+= machine_kexec.o
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c	Mon Dec 04 08:24:41 2006 -0700
    26.3 @@ -0,0 +1,184 @@
    26.4 +/*
    26.5 + * drivers/xen/core/machine_kexec.c 
    26.6 + * handle transition of Linux booting another kernel
    26.7 + */
    26.8 +
    26.9 +#include <linux/kexec.h>
   26.10 +#include <xen/interface/kexec.h>
   26.11 +#include <linux/mm.h>
   26.12 +#include <linux/bootmem.h>
   26.13 +#include <asm/hypercall.h>
   26.14 +
   26.15 +extern void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, 
   26.16 +					 struct kimage *image);
   26.17 +
   26.18 +int xen_max_nr_phys_cpus;
   26.19 +struct resource xen_hypervisor_res;
   26.20 +struct resource *xen_phys_cpus;
   26.21 +
   26.22 +void xen_machine_kexec_setup_resources(void)
   26.23 +{
   26.24 +	xen_kexec_range_t range;
   26.25 +	struct resource *res;
   26.26 +	int err, k = 0;
   26.27 +
   26.28 +	if (!is_initial_xendomain())
   26.29 +		return;
   26.30 +
   26.31 +	/* determine maximum number of physical cpus */
   26.32 +
   26.33 +	while (1) {
   26.34 +		memset(&range, 0, sizeof(range));
   26.35 +		range.range = KEXEC_RANGE_MA_CPU;
   26.36 +		range.nr = k;
   26.37 +
   26.38 +		/*
   26.39 +		 * Anything other than EINVAL or success indictates
   26.40 +		 * that we are not running on a hypervisor which
   26.41 +		 * supports kexec.
   26.42 +		 */
   26.43 +		err = HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range);
   26.44 +		if (err == -EINVAL)
   26.45 +			break;
   26.46 +		else if (err)
   26.47 +			return;
   26.48 +
   26.49 +		k++;
   26.50 +	}
   26.51 +
   26.52 +	xen_max_nr_phys_cpus = k;
   26.53 +
   26.54 +	/* allocate xen_phys_cpus */
   26.55 +
   26.56 +	xen_phys_cpus = alloc_bootmem_low(k * sizeof(struct resource));
   26.57 +	BUG_ON(!xen_phys_cpus);
   26.58 +
   26.59 +	/* fill in xen_phys_cpus with per-cpu crash note information */
   26.60 +
   26.61 +	for (k = 0; k < xen_max_nr_phys_cpus; k++) {
   26.62 +		memset(&range, 0, sizeof(range));
   26.63 +		range.range = KEXEC_RANGE_MA_CPU;
   26.64 +		range.nr = k;
   26.65 +
   26.66 +		if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
   26.67 +			BUG();
   26.68 +
   26.69 +		res = xen_phys_cpus + k;
   26.70 +
   26.71 +		memset(res, 0, sizeof(*res));
   26.72 +		res->name = "Crash note";
   26.73 +		res->start = range.start;
   26.74 +		res->end = range.start + range.size - 1;
   26.75 +		res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
   26.76 +	}
   26.77 +
   26.78 +	/* fill in xen_hypervisor_res with hypervisor machine address range */
   26.79 +
   26.80 +	memset(&range, 0, sizeof(range));
   26.81 +	range.range = KEXEC_RANGE_MA_XEN;
   26.82 +
   26.83 +	if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
   26.84 +		BUG();
   26.85 +
   26.86 +	xen_hypervisor_res.name = "Hypervisor code and data";
   26.87 +	xen_hypervisor_res.start = range.start;
   26.88 +	xen_hypervisor_res.end = range.start + range.size - 1;
   26.89 +	xen_hypervisor_res.flags = IORESOURCE_BUSY | IORESOURCE_MEM;
   26.90 +
   26.91 +	/* fill in crashk_res if range is reserved by hypervisor */
   26.92 +
   26.93 +	memset(&range, 0, sizeof(range));
   26.94 +	range.range = KEXEC_RANGE_MA_CRASH;
   26.95 +
   26.96 +	if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
   26.97 +		BUG();
   26.98 +
   26.99 +	if (range.size) {
  26.100 +		crashk_res.start = range.start;
  26.101 +		crashk_res.end = range.start + range.size - 1;
  26.102 +	}
  26.103 +}
  26.104 +
  26.105 +void xen_machine_kexec_register_resources(struct resource *res)
  26.106 +{
  26.107 +	int k;
  26.108 +
  26.109 +	request_resource(res, &xen_hypervisor_res);
  26.110 +
  26.111 +	for (k = 0; k < xen_max_nr_phys_cpus; k++)
  26.112 +		request_resource(res, xen_phys_cpus + k);
  26.113 +
  26.114 +}
  26.115 +
  26.116 +static void setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
  26.117 +{
  26.118 +	machine_kexec_setup_load_arg(xki, image);
  26.119 +
  26.120 +	xki->indirection_page = image->head;
  26.121 +	xki->start_address = image->start;
  26.122 +}
  26.123 +
  26.124 +/*
  26.125 + * Load the image into xen so xen can kdump itself
  26.126 + * This might have been done in prepare, but prepare
  26.127 + * is currently called too early. It might make sense
  26.128 + * to move prepare, but for now, just add an extra hook.
  26.129 + */
  26.130 +int xen_machine_kexec_load(struct kimage *image)
  26.131 +{
  26.132 +	xen_kexec_load_t xkl;
  26.133 +
  26.134 +	memset(&xkl, 0, sizeof(xkl));
  26.135 +	xkl.type = image->type;
  26.136 +	setup_load_arg(&xkl.image, image);
  26.137 +	return HYPERVISOR_kexec_op(KEXEC_CMD_kexec_load, &xkl);
  26.138 +}
  26.139 +
  26.140 +/*
  26.141 + * Unload the image that was stored by machine_kexec_load()
  26.142 + * This might have been done in machine_kexec_cleanup() but it
  26.143 + * is called too late, and its possible xen could try and kdump
  26.144 + * using resources that have been freed.
  26.145 + */
  26.146 +void xen_machine_kexec_unload(struct kimage *image)
  26.147 +{
  26.148 +	xen_kexec_load_t xkl;
  26.149 +
  26.150 +	memset(&xkl, 0, sizeof(xkl));
  26.151 +	xkl.type = image->type;
  26.152 +	HYPERVISOR_kexec_op(KEXEC_CMD_kexec_unload, &xkl);
  26.153 +}
  26.154 +
  26.155 +/*
  26.156 + * Do not allocate memory (or fail in any way) in machine_kexec().
  26.157 + * We are past the point of no return, committed to rebooting now.
  26.158 + *
  26.159 + * This has the hypervisor move to the prefered reboot CPU, 
  26.160 + * stop all CPUs and kexec. That is it combines machine_shutdown()
  26.161 + * and machine_kexec() in Linux kexec terms.
  26.162 + */
  26.163 +NORET_TYPE void xen_machine_kexec(struct kimage *image)
  26.164 +{
  26.165 +	xen_kexec_exec_t xke;
  26.166 +
  26.167 +	memset(&xke, 0, sizeof(xke));
  26.168 +	xke.type = image->type;
  26.169 +	HYPERVISOR_kexec_op(KEXEC_CMD_kexec, &xke);
  26.170 +	panic("KEXEC_CMD_kexec hypercall should not return\n");
  26.171 +}
  26.172 +
  26.173 +void machine_shutdown(void)
  26.174 +{
  26.175 +	/* do nothing */
  26.176 +}
  26.177 +
  26.178 +
  26.179 +/*
  26.180 + * Local variables:
  26.181 + *  c-file-style: "linux"
  26.182 + *  indent-tabs-mode: t
  26.183 + *  c-indent-level: 8
  26.184 + *  c-basic-offset: 8
  26.185 + *  tab-width: 8
  26.186 + * End:
  26.187 + */
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/Makefile	Mon Dec 04 08:24:41 2006 -0700
    27.3 @@ -0,0 +1,2 @@
    27.4 +obj-$(CONFIG_XEN_FRAMEBUFFER)	:= xenfb.o
    27.5 +obj-$(CONFIG_XEN_KEYBOARD)	+= xenkbd.o
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c	Mon Dec 04 08:24:41 2006 -0700
    28.3 @@ -0,0 +1,682 @@
    28.4 +/*
    28.5 + * linux/drivers/video/xenfb.c -- Xen para-virtual frame buffer device
    28.6 + *
    28.7 + * Copyright (C) 2005-2006 Anthony Liguori <aliguori@us.ibm.com>
    28.8 + * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
    28.9 + *
   28.10 + *  Based on linux/drivers/video/q40fb.c
   28.11 + *
   28.12 + *  This file is subject to the terms and conditions of the GNU General Public
   28.13 + *  License. See the file COPYING in the main directory of this archive for
   28.14 + *  more details.
   28.15 + */
   28.16 +
   28.17 +/*
   28.18 + * TODO:
   28.19 + *
   28.20 + * Switch to grant tables when they become capable of dealing with the
   28.21 + * frame buffer.
   28.22 + */
   28.23 +
   28.24 +#include <linux/kernel.h>
   28.25 +#include <linux/errno.h>
   28.26 +#include <linux/fb.h>
   28.27 +#include <linux/module.h>
   28.28 +#include <linux/vmalloc.h>
   28.29 +#include <linux/mm.h>
   28.30 +#include <asm/hypervisor.h>
   28.31 +#include <xen/evtchn.h>
   28.32 +#include <xen/interface/io/fbif.h>
   28.33 +#include <xen/xenbus.h>
   28.34 +#include <linux/kthread.h>
   28.35 +
   28.36 +struct xenfb_mapping
   28.37 +{
   28.38 +	struct list_head	link;
   28.39 +	struct vm_area_struct	*vma;
   28.40 +	atomic_t		map_refs;
   28.41 +	int			faults;
   28.42 +	struct xenfb_info	*info;
   28.43 +};
   28.44 +
   28.45 +struct xenfb_info
   28.46 +{
   28.47 +	struct task_struct	*kthread;
   28.48 +	wait_queue_head_t	wq;
   28.49 +
   28.50 +	unsigned char		*fb;
   28.51 +	struct fb_info		*fb_info;
   28.52 +	struct timer_list	refresh;
   28.53 +	int			dirty;
   28.54 +	int			x1, y1, x2, y2;	/* dirty rectangle,
   28.55 +						   protected by mm_lock */
   28.56 +	spinlock_t		mm_lock;
   28.57 +	int			nr_pages;
   28.58 +	struct page		**pages;
   28.59 +	struct list_head	mappings; /* protected by mm_lock */
   28.60 +
   28.61 +	unsigned		evtchn;
   28.62 +	int			irq;
   28.63 +	struct xenfb_page	*page;
   28.64 +	unsigned long 		*mfns;
   28.65 +	int			update_wanted; /* XENFB_TYPE_UPDATE wanted */
   28.66 +
   28.67 +	struct xenbus_device	*xbdev;
   28.68 +};
   28.69 +
   28.70 +static int xenfb_fps = 20;
   28.71 +static unsigned long xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8;
   28.72 +
   28.73 +static int xenfb_remove(struct xenbus_device *);
   28.74 +static void xenfb_init_shared_page(struct xenfb_info *);
   28.75 +static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *);
   28.76 +static void xenfb_disconnect_backend(struct xenfb_info *);
   28.77 +
   28.78 +static void xenfb_do_update(struct xenfb_info *info,
   28.79 +			    int x, int y, int w, int h)
   28.80 +{
   28.81 +	union xenfb_out_event event;
   28.82 +	__u32 prod;
   28.83 +
   28.84 +	event.type = XENFB_TYPE_UPDATE;
   28.85 +	event.update.x = x;
   28.86 +	event.update.y = y;
   28.87 +	event.update.width = w;
   28.88 +	event.update.height = h;
   28.89 +
   28.90 +	prod = info->page->out_prod;
   28.91 +	/* caller ensures !xenfb_queue_full() */
   28.92 +	mb();			/* ensure ring space available */
   28.93 +	XENFB_OUT_RING_REF(info->page, prod) = event;
   28.94 +	wmb();			/* ensure ring contents visible */
   28.95 +	info->page->out_prod = prod + 1;
   28.96 +
   28.97 +	notify_remote_via_evtchn(info->evtchn);
   28.98 +}
   28.99 +
  28.100 +static int xenfb_queue_full(struct xenfb_info *info)
  28.101 +{
  28.102 +	__u32 cons, prod;
  28.103 +
  28.104 +	prod = info->page->out_prod;
  28.105 +	cons = info->page->out_cons;
  28.106 +	return prod - cons == XENFB_OUT_RING_LEN;
  28.107 +}
  28.108 +
  28.109 +static void xenfb_update_screen(struct xenfb_info *info)
  28.110 +{
  28.111 +	unsigned long flags;
  28.112 +	int y1, y2, x1, x2;
  28.113 +	struct xenfb_mapping *map;
  28.114 +
  28.115 +	if (!info->update_wanted)
  28.116 +		return;
  28.117 +	if (xenfb_queue_full(info))
  28.118 +		return;
  28.119 +
  28.120 +	spin_lock_irqsave(&info->mm_lock, flags);
  28.121 +
  28.122 +	y1 = info->y1;
  28.123 +	y2 = info->y2;
  28.124 +	x1 = info->x1;
  28.125 +	x2 = info->x2;
  28.126 +	info->x1 = info->y1 = INT_MAX;
  28.127 +	info->x2 = info->y2 = 0;
  28.128 +
  28.129 +	list_for_each_entry(map, &info->mappings, link) {
  28.130 +		if (!map->faults)
  28.131 +			continue;
  28.132 +		zap_page_range(map->vma, map->vma->vm_start,
  28.133 +			       map->vma->vm_end - map->vma->vm_start, NULL);
  28.134 +		map->faults = 0;
  28.135 +	}
  28.136 +
  28.137 +	spin_unlock_irqrestore(&info->mm_lock, flags);
  28.138 +
  28.139 +	xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1);
  28.140 +}
  28.141 +
  28.142 +static int xenfb_thread(void *data)
  28.143 +{
  28.144 +	struct xenfb_info *info = data;
  28.145 +
  28.146 +	while (!kthread_should_stop()) {
  28.147 +		if (info->dirty) {
  28.148 +			info->dirty = 0;
  28.149 +			xenfb_update_screen(info);
  28.150 +		}
  28.151 +		wait_event_interruptible(info->wq,
  28.152 +			kthread_should_stop() || info->dirty);
  28.153 +		try_to_freeze();
  28.154 +	}
  28.155 +	return 0;
  28.156 +}
  28.157 +
  28.158 +static int xenfb_setcolreg(unsigned regno, unsigned red, unsigned green,
  28.159 +			   unsigned blue, unsigned transp,
  28.160 +			   struct fb_info *info)
  28.161 +{
  28.162 +	u32 v;
  28.163 +
  28.164 +	if (regno > info->cmap.len)
  28.165 +		return 1;
  28.166 +
  28.167 +	red   >>= (16 - info->var.red.length);
  28.168 +	green >>= (16 - info->var.green.length);
  28.169 +	blue  >>= (16 - info->var.blue.length);
  28.170 +
  28.171 +	v = (red << info->var.red.offset) |
  28.172 +	    (green << info->var.green.offset) |
  28.173 +	    (blue << info->var.blue.offset);
  28.174 +
  28.175 +	/* FIXME is this sane?  check against xxxfb_setcolreg()!  */
  28.176 +	switch (info->var.bits_per_pixel) {
  28.177 +	case 16:
  28.178 +	case 24:
  28.179 +	case 32:
  28.180 +		((u32 *)info->pseudo_palette)[regno] = v;
  28.181 +		break;
  28.182 +	}
  28.183 +	
  28.184 +	return 0;
  28.185 +}
  28.186 +
  28.187 +static void xenfb_timer(unsigned long data)
  28.188 +{
  28.189 +	struct xenfb_info *info = (struct xenfb_info *)data;
  28.190 +	info->dirty = 1;
  28.191 +	wake_up(&info->wq);
  28.192 +}
  28.193 +
  28.194 +static void __xenfb_refresh(struct xenfb_info *info,
  28.195 +			    int x1, int y1, int w, int h)
  28.196 +{
  28.197 +	int y2, x2;
  28.198 +
  28.199 +	y2 = y1 + h;
  28.200 +	x2 = x1 + w;
  28.201 +
  28.202 +	if (info->y1 > y1)
  28.203 +		info->y1 = y1;
  28.204 +	if (info->y2 < y2)
  28.205 +		info->y2 = y2;
  28.206 +	if (info->x1 > x1)
  28.207 +		info->x1 = x1;
  28.208 +	if (info->x2 < x2)
  28.209 +		info->x2 = x2;
  28.210 +
  28.211 +	if (timer_pending(&info->refresh))
  28.212 +		return;
  28.213 +
  28.214 +	mod_timer(&info->refresh, jiffies + HZ/xenfb_fps);
  28.215 +}
  28.216 +
  28.217 +static void xenfb_refresh(struct xenfb_info *info,
  28.218 +			  int x1, int y1, int w, int h)
  28.219 +{
  28.220 +	unsigned long flags;
  28.221 +
  28.222 +	spin_lock_irqsave(&info->mm_lock, flags);
  28.223 +	__xenfb_refresh(info, x1, y1, w, h);
  28.224 +	spin_unlock_irqrestore(&info->mm_lock, flags);
  28.225 +}
  28.226 +
  28.227 +static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
  28.228 +{
  28.229 +	struct xenfb_info *info = p->par;
  28.230 +
  28.231 +	cfb_fillrect(p, rect);
  28.232 +	xenfb_refresh(info, rect->dx, rect->dy, rect->width, rect->height);
  28.233 +}
  28.234 +
  28.235 +static void xenfb_imageblit(struct fb_info *p, const struct fb_image *image)
  28.236 +{
  28.237 +	struct xenfb_info *info = p->par;
  28.238 +
  28.239 +	cfb_imageblit(p, image);
  28.240 +	xenfb_refresh(info, image->dx, image->dy, image->width, image->height);
  28.241 +}
  28.242 +
  28.243 +static void xenfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
  28.244 +{
  28.245 +	struct xenfb_info *info = p->par;
  28.246 +
  28.247 +	cfb_copyarea(p, area);
  28.248 +	xenfb_refresh(info, area->dx, area->dy, area->width, area->height);
  28.249 +}
  28.250 +
  28.251 +static void xenfb_vm_open(struct vm_area_struct *vma)
  28.252 +{
  28.253 +	struct xenfb_mapping *map = vma->vm_private_data;
  28.254 +	atomic_inc(&map->map_refs);
  28.255 +}
  28.256 +
  28.257 +static void xenfb_vm_close(struct vm_area_struct *vma)
  28.258 +{
  28.259 +	struct xenfb_mapping *map = vma->vm_private_data;
  28.260 +	struct xenfb_info *info = map->info;
  28.261 +	unsigned long flags;
  28.262 +
  28.263 +	spin_lock_irqsave(&info->mm_lock, flags);
  28.264 +	if (atomic_dec_and_test(&map->map_refs)) {
  28.265 +		list_del(&map->link);
  28.266 +		kfree(map);
  28.267 +	}
  28.268 +	spin_unlock_irqrestore(&info->mm_lock, flags);
  28.269 +}
  28.270 +
  28.271 +static struct page *xenfb_vm_nopage(struct vm_area_struct *vma,
  28.272 +				    unsigned long vaddr, int *type)
  28.273 +{
  28.274 +	struct xenfb_mapping *map = vma->vm_private_data;
  28.275 +	struct xenfb_info *info = map->info;
  28.276 +	int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
  28.277 +	unsigned long flags;
  28.278 +	struct page *page;
  28.279 +	int y1, y2;
  28.280 +
  28.281 +	if (pgnr >= info->nr_pages)
  28.282 +		return NOPAGE_SIGBUS;
  28.283 +
  28.284 +	spin_lock_irqsave(&info->mm_lock, flags);
  28.285 +	page = info->pages[pgnr];
  28.286 +	get_page(page);
  28.287 +	map->faults++;
  28.288 +
  28.289 +	y1 = pgnr * PAGE_SIZE / info->fb_info->fix.line_length;
  28.290 +	y2 = (pgnr * PAGE_SIZE + PAGE_SIZE - 1) / info->fb_info->fix.line_length;
  28.291 +	if (y2 > info->fb_info->var.yres)
  28.292 +		y2 = info->fb_info->var.yres;
  28.293 +	__xenfb_refresh(info, 0, y1, info->fb_info->var.xres, y2 - y1);
  28.294 +	spin_unlock_irqrestore(&info->mm_lock, flags);
  28.295 +
  28.296 +	if (type)
  28.297 +		*type = VM_FAULT_MINOR;
  28.298 +
  28.299 +	return page;
  28.300 +}
  28.301 +
  28.302 +static struct vm_operations_struct xenfb_vm_ops = {
  28.303 +	.open	= xenfb_vm_open,
  28.304 +	.close	= xenfb_vm_close,
  28.305 +	.nopage	= xenfb_vm_nopage,
  28.306 +};
  28.307 +
  28.308 +static int xenfb_mmap(struct fb_info *fb_info, struct vm_area_struct *vma)
  28.309 +{
  28.310 +	struct xenfb_info *info = fb_info->par;
  28.311 +	unsigned long flags;
  28.312 +	struct xenfb_mapping *map;
  28.313 +	int map_pages;
  28.314 +
  28.315 +	if (!(vma->vm_flags & VM_WRITE))
  28.316 +		return -EINVAL;
  28.317 +	if (!(vma->vm_flags & VM_SHARED))
  28.318 +		return -EINVAL;
  28.319 +	if (vma->vm_pgoff != 0)
  28.320 +		return -EINVAL;
  28.321 +
  28.322 +	map_pages = (vma->vm_end - vma->vm_start + PAGE_SIZE-1) >> PAGE_SHIFT;
  28.323 +	if (map_pages > info->nr_pages)
  28.324 +		return -EINVAL;
  28.325 +
  28.326 +	map = kzalloc(sizeof(*map), GFP_KERNEL);
  28.327 +	if (map == NULL)
  28.328 +		return -ENOMEM;
  28.329 +
  28.330 +	map->vma = vma;
  28.331 +	map->faults = 0;
  28.332 +	map->info = info;
  28.333 +	atomic_set(&map->map_refs, 1);
  28.334 +
  28.335 +	spin_lock_irqsave(&info->mm_lock, flags);
  28.336 +	list_add(&map->link, &info->mappings);
  28.337 +	spin_unlock_irqrestore(&info->mm_lock, flags);
  28.338 +
  28.339 +	vma->vm_ops = &xenfb_vm_ops;
  28.340 +	vma->vm_flags |= (VM_DONTEXPAND | VM_RESERVED);
  28.341 +	vma->vm_private_data = map;
  28.342 +
  28.343 +	return 0;
  28.344 +}
  28.345 +
  28.346 +static struct fb_ops xenfb_fb_ops = {
  28.347 +	.owner		= THIS_MODULE,
  28.348 +	.fb_setcolreg	= xenfb_setcolreg,
  28.349 +	.fb_fillrect	= xenfb_fillrect,
  28.350 +	.fb_copyarea	= xenfb_copyarea,
  28.351 +	.fb_imageblit	= xenfb_imageblit,
  28.352 +	.fb_mmap	= xenfb_mmap,
  28.353 +};
  28.354 +
  28.355 +static irqreturn_t xenfb_event_handler(int rq, void *dev_id,
  28.356 +				       struct pt_regs *regs)
  28.357 +{
  28.358 +	/*
  28.359 +	 * No in events recognized, simply ignore them all.
  28.360 +	 * If you need to recognize some, see xenbkd's input_handler()
  28.361 +	 * for how to do that.
  28.362 +	 */
  28.363 +	struct xenfb_info *info = dev_id;
  28.364 +	struct xenfb_page *page = info->page;
  28.365 +
  28.366 +	if (page->in_cons != page->in_prod) {
  28.367 +		info->page->in_cons = info->page->in_prod;
  28.368 +		notify_remote_via_evtchn(info->evtchn);
  28.369 +	}
  28.370 +	return IRQ_HANDLED;
  28.371 +}
  28.372 +
  28.373 +static unsigned long vmalloc_to_mfn(void *address)
  28.374 +{
  28.375 +	return pfn_to_mfn(vmalloc_to_pfn(address));
  28.376 +}
  28.377 +
  28.378 +static int __devinit xenfb_probe(struct xenbus_device *dev,
  28.379 +				 const struct xenbus_device_id *id)
  28.380 +{
  28.381 +	struct xenfb_info *info;
  28.382 +	struct fb_info *fb_info;
  28.383 +	int ret;
  28.384 +
  28.385 +	info = kzalloc(sizeof(*info), GFP_KERNEL);
  28.386 +	if (info == NULL) {
  28.387 +		xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
  28.388 +		return -ENOMEM;
  28.389 +	}
  28.390 +	dev->dev.driver_data = info;
  28.391 +	info->xbdev = dev;
  28.392 +	info->irq = -1;
  28.393 +	info->x1 = info->y1 = INT_MAX;
  28.394 +	spin_lock_init(&info->mm_lock);
  28.395 +	init_waitqueue_head(&info->wq);
  28.396 +	init_timer(&info->refresh);
  28.397 +	info->refresh.function = xenfb_timer;
  28.398 +	info->refresh.data = (unsigned long)info;
  28.399 +	INIT_LIST_HEAD(&info->mappings);
  28.400 +
  28.401 +	info->fb = vmalloc(xenfb_mem_len);
  28.402 +	if (info->fb == NULL)
  28.403 +		goto error_nomem;
  28.404 +	memset(info->fb, 0, xenfb_mem_len);
  28.405 +
  28.406 +	info->nr_pages = (xenfb_mem_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
  28.407 +
  28.408 +	info->pages = kmalloc(sizeof(struct page *) * info->nr_pages,
  28.409 +			      GFP_KERNEL);
  28.410 +	if (info->pages == NULL)
  28.411 +		goto error_nomem;
  28.412 +
  28.413 +	info->mfns = vmalloc(sizeof(unsigned long) * info->nr_pages);
  28.414 +	if (!info->mfns)
  28.415 +		goto error_nomem;
  28.416 +
  28.417 +	/* set up shared page */
  28.418 +	info->page = (void *)__get_free_page(GFP_KERNEL);
  28.419 +	if (!info->page)
  28.420 +		goto error_nomem;
  28.421 +
  28.422 +	xenfb_init_shared_page(info);
  28.423 +
  28.424 +	fb_info = framebuffer_alloc(sizeof(u32) * 256, NULL);
  28.425 +				/* see fishy hackery below */
  28.426 +	if (fb_info == NULL)
  28.427 +		goto error_nomem;
  28.428 +
  28.429 +	/* FIXME fishy hackery */
  28.430 +	fb_info->pseudo_palette = fb_info->par;
  28.431 +	fb_info->par = info;
  28.432 +	/* /FIXME */
  28.433 +	fb_info->screen_base = info->fb;
  28.434 +
  28.435 +	fb_info->fbops = &xenfb_fb_ops;
  28.436 +	fb_info->var.xres_virtual = fb_info->var.xres = info->page->width;
  28.437 +	fb_info->var.yres_virtual = fb_info->var.yres = info->page->height;
  28.438 +	fb_info->var.bits_per_pixel = info->page->depth;
  28.439 +
  28.440 +	fb_info->var.red = (struct fb_bitfield){16, 8, 0};
  28.441 +	fb_info->var.green = (struct fb_bitfield){8, 8, 0};
  28.442 +	fb_info->var.blue = (struct fb_bitfield){0, 8, 0};
  28.443 +
  28.444 +	fb_info->var.activate = FB_ACTIVATE_NOW;
  28.445 +	fb_info->var.height = -1;
  28.446 +	fb_info->var.width = -1;
  28.447 +	fb_info->var.vmode = FB_VMODE_NONINTERLACED;
  28.448 +
  28.449 +	fb_info->fix.visual = FB_VISUAL_TRUECOLOR;
  28.450 +	fb_info->fix.line_length = info->page->line_length;
  28.451 +	fb_info->fix.smem_start = 0;
  28.452 +	fb_info->fix.smem_len = xenfb_mem_len;
  28.453 +	strcpy(fb_info->fix.id, "xen");
  28.454 +	fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
  28.455 +	fb_info->fix.accel = FB_ACCEL_NONE;
  28.456 +
  28.457 +	fb_info->flags = FBINFO_FLAG_DEFAULT;
  28.458 +
  28.459 +	ret = fb_alloc_cmap(&fb_info->cmap, 256, 0);
  28.460 +	if (ret < 0) {
  28.461 +		framebuffer_release(fb_info);
  28.462 +		xenbus_dev_fatal(dev, ret, "fb_alloc_cmap");
  28.463 +		goto error;
  28.464 +	}
  28.465 +
  28.466 +	ret = register_framebuffer(fb_info);
  28.467 +	if (ret) {
  28.468 +		fb_dealloc_cmap(&info->fb_info->cmap);
  28.469 +		framebuffer_release(fb_info);
  28.470 +		xenbus_dev_fatal(dev, ret, "register_framebuffer");
  28.471 +		goto error;
  28.472 +	}
  28.473 +	info->fb_info = fb_info;
  28.474 +
  28.475 +	/* FIXME should this be delayed until backend XenbusStateConnected? */
  28.476 +	info->kthread = kthread_run(xenfb_thread, info, "xenfb thread");
  28.477 +	if (IS_ERR(info->kthread)) {
  28.478 +		ret = PTR_ERR(info->kthread);
  28.479 +		info->kthread = NULL;
  28.480 +		xenbus_dev_fatal(dev, ret, "register_framebuffer");
  28.481 +		goto error;
  28.482 +	}
  28.483 +
  28.484 +	ret = xenfb_connect_backend(dev, info);
  28.485 +	if (ret < 0)
  28.486 +		goto error;
  28.487 +
  28.488 +	return 0;
  28.489 +
  28.490 + error_nomem:
  28.491 +	ret = -ENOMEM;
  28.492 +	xenbus_dev_fatal(dev, ret, "allocating device memory");
  28.493 + error:
  28.494 +	xenfb_remove(dev);
  28.495 +	return ret;
  28.496 +}
  28.497 +
  28.498 +static int xenfb_resume(struct xenbus_device *dev)
  28.499 +{
  28.500 +	struct xenfb_info *info = dev->dev.driver_data;
  28.501 +
  28.502 +	xenfb_disconnect_backend(info);
  28.503 +	xenfb_init_shared_page(info);
  28.504 +	return xenfb_connect_backend(dev, info);
  28.505 +}
  28.506 +
  28.507 +static int xenfb_remove(struct xenbus_device *dev)
  28.508 +{
  28.509 +	struct xenfb_info *info = dev->dev.driver_data;
  28.510 +
  28.511 +	del_timer(&info->refresh);
  28.512 +	if (info->kthread)
  28.513 +		kthread_stop(info->kthread);
  28.514 +	xenfb_disconnect_backend(info);
  28.515 +	if (info->fb_info) {
  28.516 +		unregister_framebuffer(info->fb_info);
  28.517 +		fb_dealloc_cmap(&info->fb_info->cmap);
  28.518 +		framebuffer_release(info->fb_info);
  28.519 +	}
  28.520 +	free_page((unsigned long)info->page);
  28.521 +	vfree(info->mfns);
  28.522 +	kfree(info->pages);
  28.523 +	vfree(info->fb);
  28.524 +	kfree(info);
  28.525 +
  28.526 +	return 0;
  28.527 +}
  28.528 +
  28.529 +static void xenfb_init_shared_page(struct xenfb_info *info)
  28.530 +{
  28.531 +	int i;
  28.532 +
  28.533 +	for (i = 0; i < info->nr_pages; i++)
  28.534 +		info->pages[i] = vmalloc_to_page(info->fb + i * PAGE_SIZE);
  28.535 +
  28.536 +	for (i = 0; i < info->nr_pages; i++)
  28.537 +		info->mfns[i] = vmalloc_to_mfn(info->fb + i * PAGE_SIZE);
  28.538 +
  28.539 +	info->page->pd[0] = vmalloc_to_mfn(info->mfns);
  28.540 +	info->page->pd[1] = 0;
  28.541 +	info->page->width = XENFB_WIDTH;
  28.542 +	info->page->height = XENFB_HEIGHT;
  28.543 +	info->page->depth = XENFB_DEPTH;
  28.544 +	info->page->line_length = (info->page->depth / 8) * info->page->width;
  28.545 +	info->page->mem_length = xenfb_mem_len;
  28.546 +	info->page->in_cons = info->page->in_prod = 0;
  28.547 +	info->page->out_cons = info->page->out_prod = 0;
  28.548 +}
  28.549 +
  28.550 +static int xenfb_connect_backend(struct xenbus_device *dev,
  28.551 +				 struct xenfb_info *info)
  28.552 +{
  28.553 +	int ret;
  28.554 +	struct xenbus_transaction xbt;
  28.555 +
  28.556 +	ret = xenbus_alloc_evtchn(dev, &info->evtchn);
  28.557 +	if (ret)
  28.558 +		return ret;
  28.559 +	ret = bind_evtchn_to_irqhandler(info->evtchn, xenfb_event_handler,
  28.560 +					0, "xenfb", info);
  28.561 +	if (ret < 0) {
  28.562 +		xenbus_free_evtchn(dev, info->evtchn);
  28.563 +		xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
  28.564 +		return ret;
  28.565 +	}
  28.566 +	info->irq = ret;
  28.567 +
  28.568 + again:
  28.569 +	ret = xenbus_transaction_start(&xbt);
  28.570 +	if (ret) {
  28.571 +		xenbus_dev_fatal(dev, ret, "starting transaction");
  28.572 +		return ret;
  28.573 +	}
  28.574 +	ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
  28.575 +			    virt_to_mfn(info->page));
  28.576 +	if (ret)
  28.577 +		goto error_xenbus;
  28.578 +	ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
  28.579 +			    info->evtchn);
  28.580 +	if (ret)
  28.581 +		goto error_xenbus;
  28.582 +	ret = xenbus_printf(xbt, dev->nodename, "feature-update", "1");
  28.583 +	if (ret)
  28.584 +		goto error_xenbus;
  28.585 +	ret = xenbus_transaction_end(xbt, 0);
  28.586 +	if (ret) {
  28.587 +		if (ret == -EAGAIN)
  28.588 +			goto again;
  28.589 +		xenbus_dev_fatal(dev, ret, "completing transaction");
  28.590 +		return ret;
  28.591 +	}
  28.592 +
  28.593 +	xenbus_switch_state(dev, XenbusStateInitialised);
  28.594 +	return 0;
  28.595 +
  28.596 + error_xenbus:
  28.597 +	xenbus_transaction_end(xbt, 1);
  28.598 +	xenbus_dev_fatal(dev, ret, "writing xenstore");
  28.599 +	return ret;
  28.600 +}
  28.601 +
  28.602 +static void xenfb_disconnect_backend(struct xenfb_info *info)
  28.603 +{
  28.604 +	if (info->irq >= 0)
  28.605 +		unbind_from_irqhandler(info->irq, info);
  28.606 +	info->irq = -1;
  28.607 +}
  28.608 +
  28.609 +static void xenfb_backend_changed(struct xenbus_device *dev,
  28.610 +				  enum xenbus_state backend_state)
  28.611 +{
  28.612 +	struct xenfb_info *info = dev->dev.driver_data;
  28.613 +	int val;
  28.614 +
  28.615 +	switch (backend_state) {
  28.616 +	case XenbusStateInitialising:
  28.617 +	case XenbusStateInitialised:
  28.618 +	case XenbusStateUnknown:
  28.619 +	case XenbusStateClosed:
  28.620 +		break;
  28.621 +
  28.622 +	case XenbusStateInitWait:
  28.623 +	InitWait:
  28.624 +		xenbus_switch_state(dev, XenbusStateConnected);
  28.625 +		break;
  28.626 +
  28.627 +	case XenbusStateConnected:
  28.628 +		/*
  28.629 +		 * Work around xenbus race condition: If backend goes
  28.630 +		 * through InitWait to Connected fast enough, we can
  28.631 +		 * get Connected twice here.
  28.632 +		 */
  28.633 +		if (dev->state != XenbusStateConnected)
  28.634 +			goto InitWait; /* no InitWait seen yet, fudge it */
  28.635 +
  28.636 +		if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
  28.637 +				 "request-update", "%d", &val) < 0)
  28.638 +			val = 0;
  28.639 +		if (val)
  28.640 +			info->update_wanted = 1;
  28.641 +		break;
  28.642 +
  28.643 +	case XenbusStateClosing:
  28.644 +		// FIXME is this safe in any dev->state?
  28.645 +		xenbus_frontend_closed(dev);
  28.646 +		break;
  28.647 +	}
  28.648 +}
  28.649 +
  28.650 +static struct xenbus_device_id xenfb_ids[] = {
  28.651 +	{ "vfb" },
  28.652 +	{ "" }
  28.653 +};
  28.654 +
  28.655 +static struct xenbus_driver xenfb = {
  28.656 +	.name = "vfb",
  28.657 +	.owner = THIS_MODULE,
  28.658 +	.ids = xenfb_ids,
  28.659 +	.probe = xenfb_probe,
  28.660 +	.remove = xenfb_remove,
  28.661 +	.resume = xenfb_resume,
  28.662 +	.otherend_changed = xenfb_backend_changed,
  28.663 +};
  28.664 +
  28.665 +static int __init xenfb_init(void)
  28.666 +{
  28.667 +	if (!is_running_on_xen())
  28.668 +		return -ENODEV;
  28.669 +
  28.670 +	/* Nothing to do if running in dom0. */
  28.671 +	if (is_initial_xendomain())
  28.672 +		return -ENODEV;
  28.673 +
  28.674 +	return xenbus_register_frontend(&xenfb);
  28.675 +}
  28.676 +
  28.677 +static void __exit xenfb_cleanup(void)
  28.678 +{
  28.679 +	return xenbus_unregister_driver(&xenfb);
  28.680 +}
  28.681 +
  28.682 +module_init(xenfb_init);
  28.683 +module_exit(xenfb_cleanup);
  28.684 +
  28.685 +MODULE_LICENSE("GPL");
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c	Mon Dec 04 08:24:41 2006 -0700
    29.3 @@ -0,0 +1,300 @@
    29.4 +/*
    29.5 + * linux/drivers/input/keyboard/xenkbd.c -- Xen para-virtual input device
    29.6 + *
    29.7 + * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
    29.8 + * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
    29.9 + *
   29.10 + *  Based on linux/drivers/input/mouse/sermouse.c
   29.11 + *
   29.12 + *  This file is subject to the terms and conditions of the GNU General Public
   29.13 + *  License. See the file COPYING in the main directory of this archive for
   29.14 + *  more details.
   29.15 + */
   29.16 +
   29.17 +/*
   29.18 + * TODO:
   29.19 + *
   29.20 + * Switch to grant tables together with xenfb.c.
   29.21 + */
   29.22 +
   29.23 +#include <linux/kernel.h>
   29.24 +#include <linux/errno.h>
   29.25 +#include <linux/module.h>
   29.26 +#include <linux/input.h>
   29.27 +#include <asm/hypervisor.h>
   29.28 +#include <xen/evtchn.h>
   29.29 +#include <xen/interface/io/fbif.h>
   29.30 +#include <xen/interface/io/kbdif.h>
   29.31 +#include <xen/xenbus.h>
   29.32 +
   29.33 +struct xenkbd_info
   29.34 +{
   29.35 +	struct input_dev *dev;
   29.36 +	struct xenkbd_page *page;
   29.37 +	unsigned evtchn;
   29.38 +	int irq;
   29.39 +	struct xenbus_device *xbdev;
   29.40 +};
   29.41 +
   29.42 +static int xenkbd_remove(struct xenbus_device *);
   29.43 +static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info *);
   29.44 +static void xenkbd_disconnect_backend(struct xenkbd_info *);
   29.45 +
   29.46 +/*
   29.47 + * Note: if you need to send out events, see xenfb_do_update() for how
   29.48 + * to do that.
   29.49 + */
   29.50 +
   29.51 +static irqreturn_t input_handler(int rq, void *dev_id, struct pt_regs *regs)
   29.52 +{
   29.53 +	struct xenkbd_info *info = dev_id;
   29.54 +	struct xenkbd_page *page = info->page;
   29.55 +	__u32 cons, prod;
   29.56 +
   29.57 +	prod = page->in_prod;
   29.58 +	if (prod == page->out_cons)
   29.59 +		return IRQ_HANDLED;
   29.60 +	rmb();			/* ensure we see ring contents up to prod */
   29.61 +	for (cons = page->in_cons; cons != prod; cons++) {
   29.62 +		union xenkbd_in_event *event;
   29.63 +		event = &XENKBD_IN_RING_REF(page, cons);
   29.64 +
   29.65 +		switch (event->type) {
   29.66 +		case XENKBD_TYPE_MOTION:
   29.67 +			input_report_rel(info->dev, REL_X, event->motion.rel_x);
   29.68 +			input_report_rel(info->dev, REL_Y, event->motion.rel_y);
   29.69 +			break;
   29.70 +		case XENKBD_TYPE_KEY:
   29.71 +			input_report_key(info->dev, event->key.keycode, event->key.pressed);
   29.72 +			break;
   29.73 +		case XENKBD_TYPE_POS:
   29.74 +			input_report_abs(info->dev, ABS_X, event->pos.abs_x);
   29.75 +			input_report_abs(info->dev, ABS_Y, event->pos.abs_y);
   29.76 +			break;
   29.77 +		}
   29.78 +	}
   29.79 +	input_sync(info->dev);
   29.80 +	mb();			/* ensure we got ring contents */
   29.81 +	page->in_cons = cons;
   29.82 +	notify_remote_via_evtchn(info->evtchn);
   29.83 +
   29.84 +	return IRQ_HANDLED;
   29.85 +}
   29.86 +
   29.87 +int __devinit xenkbd_probe(struct xenbus_device *dev,
   29.88 +			   const struct xenbus_device_id *id)
   29.89 +{
   29.90 +	int ret, i;
   29.91 +	struct xenkbd_info *info;
   29.92 +	struct input_dev *input_dev;
   29.93 +
   29.94 +	info = kzalloc(sizeof(*info), GFP_KERNEL);
   29.95 +	if (!info) {
   29.96 +		xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
   29.97 +		return -ENOMEM;
   29.98 +	}
   29.99 +	dev->dev.driver_data = info;
  29.100 +	info->xbdev = dev;
  29.101 +
  29.102 +	info->page = (void *)__get_free_page(GFP_KERNEL);
  29.103 +	if (!info->page)
  29.104 +		goto error_nomem;
  29.105 +	info->page->in_cons = info->page->in_prod = 0;
  29.106 +	info->page->out_cons = info->page->out_prod = 0;
  29.107 +
  29.108 +	input_dev = input_allocate_device();
  29.109 +	if (!input_dev)
  29.110 +		goto error_nomem;
  29.111 +
  29.112 +	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
  29.113 +	input_dev->keybit[LONG(BTN_MOUSE)]
  29.114 +		= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
  29.115 +	/* TODO additional buttons */
  29.116 +	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
  29.117 +
  29.118 +	/* FIXME not sure this is quite right */
  29.119 +	for (i = 0; i < 256; i++)
  29.120 +		set_bit(i, input_dev->keybit);
  29.121 +
  29.122 +	input_dev->name = "Xen Virtual Keyboard/Mouse";
  29.123 +
  29.124 +	input_set_abs_params(input_dev, ABS_X, 0, XENFB_WIDTH, 0, 0);
  29.125 +	input_set_abs_params(input_dev, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
  29.126 +
  29.127 +	ret = input_register_device(input_dev);
  29.128 +	if (ret) {
  29.129 +		input_free_device(input_dev);
  29.130 +		xenbus_dev_fatal(dev, ret, "input_register_device");
  29.131 +		goto error;
  29.132 +	}
  29.133 +	info->dev = input_dev;
  29.134 +
  29.135 +	ret = xenkbd_connect_backend(dev, info);
  29.136 +	if (ret < 0)
  29.137 +		goto error;
  29.138 +
  29.139 +	return 0;
  29.140 +
  29.141 + error_nomem:
  29.142 +	ret = -ENOMEM;
  29.143 +	xenbus_dev_fatal(dev, ret, "allocating device memory");
  29.144 + error:
  29.145 +	xenkbd_remove(dev);
  29.146 +	return ret;
  29.147 +}
  29.148 +
  29.149 +static int xenkbd_resume(struct xenbus_device *dev)
  29.150 +{
  29.151 +	struct xenkbd_info *info = dev->dev.driver_data;
  29.152 +
  29.153 +	xenkbd_disconnect_backend(info);
  29.154 +	return xenkbd_connect_backend(dev, info);
  29.155 +}
  29.156 +
  29.157 +static int xenkbd_remove(struct xenbus_device *dev)
  29.158 +{
  29.159 +	struct xenkbd_info *info = dev->dev.driver_data;
  29.160 +
  29.161 +	xenkbd_disconnect_backend(info);
  29.162 +	input_unregister_device(info->dev);
  29.163 +	free_page((unsigned long)info->page);
  29.164 +	kfree(info);
  29.165 +	return 0;
  29.166 +}
  29.167 +
  29.168 +static int xenkbd_connect_backend(struct xenbus_device *dev,
  29.169 +				  struct xenkbd_info *info)
  29.170 +{
  29.171 +	int ret;
  29.172 +	struct xenbus_transaction xbt;
  29.173 +
  29.174 +	ret = xenbus_alloc_evtchn(dev, &info->evtchn);
  29.175 +	if (ret)
  29.176 +		return ret;
  29.177 +	ret = bind_evtchn_to_irqhandler(info->evtchn, input_handler, 0,
  29.178 +					"xenkbd", info);
  29.179 +	if (ret < 0) {
  29.180 +		xenbus_free_evtchn(dev, info->evtchn);
  29.181 +		xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
  29.182 +		return ret;
  29.183 +	}
  29.184 +	info->irq = ret;
  29.185 +
  29.186 + again:
  29.187 +	ret = xenbus_transaction_start(&xbt);
  29.188 +	if (ret) {
  29.189 +		xenbus_dev_fatal(dev, ret, "starting transaction");
  29.190 +		return ret;
  29.191 +	}
  29.192 +	ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
  29.193 +			    virt_to_mfn(info->page));
  29.194 +	if (ret)
  29.195 +		goto error_xenbus;
  29.196 +	ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
  29.197 +			    info->evtchn);
  29.198 +	if (ret)
  29.199 +		goto error_xenbus;
  29.200 +	ret = xenbus_transaction_end(xbt, 0);
  29.201 +	if (ret) {
  29.202 +		if (ret == -EAGAIN)
  29.203 +			goto again;
  29.204 +		xenbus_dev_fatal(dev, ret, "completing transaction");
  29.205 +		return ret;
  29.206 +	}
  29.207 +
  29.208 +	xenbus_switch_state(dev, XenbusStateInitialised);
  29.209 +	return 0;
  29.210 +
  29.211 + error_xenbus:
  29.212 +	xenbus_transaction_end(xbt, 1);
  29.213 +	xenbus_dev_fatal(dev, ret, "writing xenstore");
  29.214 +	return ret;
  29.215 +}
  29.216 +
  29.217 +static void xenkbd_disconnect_backend(struct xenkbd_info *info)
  29.218 +{
  29.219 +	if (info->irq >= 0)
  29.220 +		unbind_from_irqhandler(info->irq, info);
  29.221 +	info->irq = -1;
  29.222 +}
  29.223 +
  29.224 +static void xenkbd_backend_changed(struct xenbus_device *dev,
  29.225 +				   enum xenbus_state backend_state)
  29.226 +{
  29.227 +	struct xenkbd_info *info = dev->dev.driver_data;
  29.228 +	int ret, val;
  29.229 +
  29.230 +	switch (backend_state) {
  29.231 +	case XenbusStateInitialising:
  29.232 +	case XenbusStateInitialised:
  29.233 +	case XenbusStateUnknown:
  29.234 +	case XenbusStateClosed:
  29.235 +		break;
  29.236 +
  29.237 +	case XenbusStateInitWait:
  29.238 +	InitWait:
  29.239 +		ret = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
  29.240 +				   "feature-abs-pointer", "%d", &val);
  29.241 +		if (ret < 0)
  29.242 +			val = 0;
  29.243 +		if (val) {
  29.244 +			ret = xenbus_printf(XBT_NIL, info->xbdev->nodename,
  29.245 +					    "request-abs-pointer", "1");
  29.246 +			if (ret)
  29.247 +				; /* FIXME */
  29.248 +		}
  29.249 +		xenbus_switch_state(dev, XenbusStateConnected);
  29.250 +		break;
  29.251 +
  29.252 +	case XenbusStateConnected:
  29.253 +		/*
  29.254 +		 * Work around xenbus race condition: If backend goes
  29.255 +		 * through InitWait to Connected fast enough, we can
  29.256 +		 * get Connected twice here.
  29.257 +		 */
  29.258 +		if (dev->state != XenbusStateConnected)
  29.259 +			goto InitWait; /* no InitWait seen yet, fudge it */
  29.260 +		break;
  29.261 +
  29.262 +	case XenbusStateClosing:
  29.263 +		xenbus_frontend_closed(dev);
  29.264 +		break;
  29.265 +	}
  29.266 +}
  29.267 +
  29.268 +static struct xenbus_device_id xenkbd_ids[] = {
  29.269 +	{ "vkbd" },
  29.270 +	{ "" }
  29.271 +};
  29.272 +
  29.273 +static struct xenbus_driver xenkbd = {
  29.274 +	.name = "vkbd",
  29.275 +	.owner = THIS_MODULE,
  29.276 +	.ids = xenkbd_ids,
  29.277 +	.probe = xenkbd_probe,
  29.278 +	.remove = xenkbd_remove,
  29.279 +	.resume = xenkbd_resume,
  29.280 +	.otherend_changed = xenkbd_backend_changed,
  29.281 +};
  29.282 +
  29.283 +static int __init xenkbd_init(void)
  29.284 +{
  29.285 +	if (!is_running_on_xen())
  29.286 +		return -ENODEV;
  29.287 +
  29.288 +	/* Nothing to do if running in dom0. */
  29.289 +	if (is_initial_xendomain())
  29.290 +		return -ENODEV;
  29.291 +
  29.292 +	return xenbus_register_frontend(&xenkbd);
  29.293 +}
  29.294 +
  29.295 +static void __exit xenkbd_cleanup(void)
  29.296 +{
  29.297 +	return xenbus_unregister_driver(&xenkbd);
  29.298 +}
  29.299 +
  29.300 +module_init(xenkbd_init);
  29.301 +module_exit(xenkbd_cleanup);
  29.302 +
  29.303 +MODULE_LICENSE("GPL");
    30.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Sat Dec 02 15:19:50 2006 -0700
    30.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Mon Dec 04 08:24:41 2006 -0700
    30.3 @@ -395,5 +395,13 @@ HYPERVISOR_xenoprof_op(
    30.4  	return _hypercall2(int, xenoprof_op, op, arg);
    30.5  }
    30.6  
    30.7 +static inline int
    30.8 +HYPERVISOR_kexec_op(
    30.9 +	unsigned long op, void *args)
   30.10 +{
   30.11 +	return _hypercall2(int, kexec_op, op, args);
   30.12 +}
   30.13 +
   30.14 +
   30.15  
   30.16  #endif /* __HYPERCALL_H__ */
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/agp.h	Mon Dec 04 08:24:41 2006 -0700
    31.3 @@ -0,0 +1,35 @@
    31.4 +#ifndef AGP_H
    31.5 +#define AGP_H 1
    31.6 +
    31.7 +#include <asm/cacheflush.h>
    31.8 +#include <asm/system.h>
    31.9 +
   31.10 +/*
   31.11 + * Functions to keep the agpgart mappings coherent.
   31.12 + * The GART gives the CPU a physical alias of memory. The alias is
   31.13 + * mapped uncacheable. Make sure there are no conflicting mappings
   31.14 + * with different cachability attributes for the same page.
   31.15 + */
   31.16 +
   31.17 +int map_page_into_agp(struct page *page);
   31.18 +int unmap_page_from_agp(struct page *page);
   31.19 +#define flush_agp_mappings() global_flush_tlb()
   31.20 +
   31.21 +/* Could use CLFLUSH here if the cpu supports it. But then it would
   31.22 +   need to be called for each cacheline of the whole page so it may not be
   31.23 +   worth it. Would need a page for it. */
   31.24 +#define flush_agp_cache() wbinvd()
   31.25 +
   31.26 +/* Convert a physical address to an address suitable for the GART. */
   31.27 +#define phys_to_gart(x) phys_to_machine(x)
   31.28 +#define gart_to_phys(x) machine_to_phys(x)
   31.29 +
   31.30 +/* GATT allocation. Returns/accepts GATT kernel virtual address. */
   31.31 +#define alloc_gatt_pages(order)	({                                          \
   31.32 +	char *_t; dma_addr_t _d;                                            \
   31.33 +	_t = dma_alloc_coherent(NULL,PAGE_SIZE<<(order),&_d,GFP_KERNEL);    \
   31.34 +	_t; })
   31.35 +#define free_gatt_pages(table, order)	\
   31.36 +	dma_free_coherent(NULL,PAGE_SIZE<<(order),(table),virt_to_bus(table))
   31.37 +
   31.38 +#endif
    32.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Sat Dec 02 15:19:50 2006 -0700
    32.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Mon Dec 04 08:24:41 2006 -0700
    32.3 @@ -396,4 +396,11 @@ HYPERVISOR_xenoprof_op(
    32.4  	return _hypercall2(int, xenoprof_op, op, arg);
    32.5  }
    32.6  
    32.7 +static inline int
    32.8 +HYPERVISOR_kexec_op(
    32.9 +	unsigned long op, void *args)
   32.10 +{
   32.11 +	return _hypercall2(int, kexec_op, op, args);
   32.12 +}
   32.13 +
   32.14  #endif /* __HYPERCALL_H__ */
    33.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h	Sat Dec 02 15:19:50 2006 -0700
    33.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h	Mon Dec 04 08:24:41 2006 -0700
    33.3 @@ -90,6 +90,8 @@ extern unsigned long profile_pc(struct p
    33.4  #define profile_pc(regs) instruction_pointer(regs)
    33.5  #endif
    33.6  
    33.7 +#include <linux/compiler.h>
    33.8 +
    33.9  void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
   33.10  
   33.11  struct task_struct;
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/xenoprof.h	Mon Dec 04 08:24:41 2006 -0700
    34.3 @@ -0,0 +1,1 @@
    34.4 +#include <asm-i386/mach-xen/asm/xenoprof.h>
    35.1 --- a/linux-2.6-xen-sparse/include/xen/xencons.h	Sat Dec 02 15:19:50 2006 -0700
    35.2 +++ b/linux-2.6-xen-sparse/include/xen/xencons.h	Mon Dec 04 08:24:41 2006 -0700
    35.3 @@ -14,4 +14,6 @@ void xencons_tx(void);
    35.4  int xencons_ring_init(void);
    35.5  int xencons_ring_send(const char *data, unsigned len);
    35.6  
    35.7 +void xencons_early_setup(void);
    35.8 +
    35.9  #endif /* __ASM_XENCONS_H__ */
    36.1 --- a/linux-2.6-xen-sparse/mm/memory.c	Sat Dec 02 15:19:50 2006 -0700
    36.2 +++ b/linux-2.6-xen-sparse/mm/memory.c	Mon Dec 04 08:24:41 2006 -0700
    36.3 @@ -882,6 +882,7 @@ unsigned long zap_page_range(struct vm_a
    36.4  		tlb_finish_mmu(tlb, address, end);
    36.5  	return end;
    36.6  }
    36.7 +EXPORT_SYMBOL(zap_page_range);
    36.8  
    36.9  /*
   36.10   * Do a quick page-table lookup for a single page.
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch	Mon Dec 04 08:24:41 2006 -0700
    37.3 @@ -0,0 +1,62 @@
    37.4 +From: Eric W. Biederman <ebiederm@xmission.com>
    37.5 +Date: Sun, 30 Jul 2006 10:03:20 +0000 (-0700)
    37.6 +Subject: [PATCH] machine_kexec.c: Fix the description of segment handling
    37.7 +X-Git-Tag: v2.6.18-rc4
    37.8 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2a8a3d5b65e86ec1dfef7d268c64a909eab94af7
    37.9 +
   37.10 +[PATCH] machine_kexec.c: Fix the description of segment handling
   37.11 +
   37.12 +One of my original comments in machine_kexec was unclear
   37.13 +and this should fix it.
   37.14 +
   37.15 +Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
   37.16 +Cc: Andi Kleen <ak@muc.de>
   37.17 +Acked-by: Horms <horms@verge.net.au>
   37.18 +Signed-off-by: Andrew Morton <akpm@osdl.org>
   37.19 +Signed-off-by: Linus Torvalds <torvalds@osdl.org>
   37.20 +---
   37.21 +
   37.22 +--- a/arch/i386/kernel/machine_kexec.c
   37.23 ++++ b/arch/i386/kernel/machine_kexec.c
   37.24 +@@ -189,14 +189,11 @@ NORET_TYPE void machine_kexec(struct kim
   37.25 + 	memcpy((void *)reboot_code_buffer, relocate_new_kernel,
   37.26 + 						relocate_new_kernel_size);
   37.27 + 
   37.28 +-	/* The segment registers are funny things, they are
   37.29 +-	 * automatically loaded from a table, in memory wherever you
   37.30 +-	 * set them to a specific selector, but this table is never
   37.31 +-	 * accessed again you set the segment to a different selector.
   37.32 +-	 *
   37.33 +-	 * The more common model is are caches where the behide
   37.34 +-	 * the scenes work is done, but is also dropped at arbitrary
   37.35 +-	 * times.
   37.36 ++	/* The segment registers are funny things, they have both a
   37.37 ++	 * visible and an invisible part.  Whenever the visible part is
   37.38 ++	 * set to a specific selector, the invisible part is loaded
   37.39 ++	 * with from a table in memory.  At no other time is the
   37.40 ++	 * descriptor table in memory accessed.
   37.41 + 	 *
   37.42 + 	 * I take advantage of this here by force loading the
   37.43 + 	 * segments, before I zap the gdt with an invalid value.
   37.44 +--- a/arch/x86_64/kernel/machine_kexec.c
   37.45 ++++ b/arch/x86_64/kernel/machine_kexec.c
   37.46 +@@ -207,14 +207,11 @@ NORET_TYPE void machine_kexec(struct kim
   37.47 + 	__flush_tlb();
   37.48 + 
   37.49 + 
   37.50 +-	/* The segment registers are funny things, they are
   37.51 +-	 * automatically loaded from a table, in memory wherever you
   37.52 +-	 * set them to a specific selector, but this table is never
   37.53 +-	 * accessed again unless you set the segment to a different selector.
   37.54 +-	 *
   37.55 +-	 * The more common model are caches where the behide
   37.56 +-	 * the scenes work is done, but is also dropped at arbitrary
   37.57 +-	 * times.
   37.58 ++	/* The segment registers are funny things, they have both a
   37.59 ++	 * visible and an invisible part.  Whenever the visible part is
   37.60 ++	 * set to a specific selector, the invisible part is loaded
   37.61 ++	 * with from a table in memory.  At no other time is the
   37.62 ++	 * descriptor table in memory accessed.
   37.63 + 	 *
   37.64 + 	 * I take advantage of this here by force loading the
   37.65 + 	 * segments, before I zap the gdt with an invalid value.
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch	Mon Dec 04 08:24:41 2006 -0700
    38.3 @@ -0,0 +1,93 @@
    38.4 +From: Tobias Klauser <tklauser@nuerscht.ch>
    38.5 +Date: Mon, 26 Jun 2006 16:57:34 +0000 (+0200)
    38.6 +Subject: Storage class should be first
    38.7 +X-Git-Tag: v2.6.18-rc1
    38.8 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2efe55a9cec8418f0e0cde3dc3787a42fddc4411
    38.9 +
   38.10 +Storage class should be first
   38.11 +
   38.12 +Storage class should be before const
   38.13 +
   38.14 +Signed-off-by: Tobias Klauser <tklauser@nuerscht.ch>
   38.15 +Signed-off-by: Adrian Bunk <bunk@stusta.de>
   38.16 +---
   38.17 +
   38.18 +--- a/arch/i386/kernel/machine_kexec.c
   38.19 ++++ b/arch/i386/kernel/machine_kexec.c
   38.20 +@@ -133,9 +133,9 @@ typedef asmlinkage NORET_TYPE void (*rel
   38.21 + 					unsigned long start_address,
   38.22 + 					unsigned int has_pae) ATTRIB_NORET;
   38.23 + 
   38.24 +-const extern unsigned char relocate_new_kernel[];
   38.25 ++extern const unsigned char relocate_new_kernel[];
   38.26 + extern void relocate_new_kernel_end(void);
   38.27 +-const extern unsigned int relocate_new_kernel_size;
   38.28 ++extern const unsigned int relocate_new_kernel_size;
   38.29 + 
   38.30 + /*
   38.31 +  * A architecture hook called to validate the
   38.32 +--- a/arch/powerpc/kernel/machine_kexec_32.c
   38.33 ++++ b/arch/powerpc/kernel/machine_kexec_32.c
   38.34 +@@ -30,8 +30,8 @@ typedef NORET_TYPE void (*relocate_new_k
   38.35 +  */
   38.36 + void default_machine_kexec(struct kimage *image)
   38.37 + {
   38.38 +-	const extern unsigned char relocate_new_kernel[];
   38.39 +-	const extern unsigned int relocate_new_kernel_size;
   38.40 ++	extern const unsigned char relocate_new_kernel[];
   38.41 ++	extern const unsigned int relocate_new_kernel_size;
   38.42 + 	unsigned long page_list;
   38.43 + 	unsigned long reboot_code_buffer, reboot_code_buffer_phys;
   38.44 + 	relocate_new_kernel_t rnk;
   38.45 +--- a/arch/ppc/kernel/machine_kexec.c
   38.46 ++++ b/arch/ppc/kernel/machine_kexec.c
   38.47 +@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
   38.48 + 				unsigned long reboot_code_buffer,
   38.49 + 				unsigned long start_address) ATTRIB_NORET;
   38.50 + 
   38.51 +-const extern unsigned char relocate_new_kernel[];
   38.52 +-const extern unsigned int relocate_new_kernel_size;
   38.53 ++extern const unsigned char relocate_new_kernel[];
   38.54 ++extern const unsigned int relocate_new_kernel_size;
   38.55 + 
   38.56 + void machine_shutdown(void)
   38.57 + {
   38.58 +--- a/arch/s390/kernel/machine_kexec.c
   38.59 ++++ b/arch/s390/kernel/machine_kexec.c
   38.60 +@@ -27,8 +27,8 @@ static void kexec_halt_all_cpus(void *);
   38.61 + 
   38.62 + typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);
   38.63 + 
   38.64 +-const extern unsigned char relocate_kernel[];
   38.65 +-const extern unsigned long long relocate_kernel_len;
   38.66 ++extern const unsigned char relocate_kernel[];
   38.67 ++extern const unsigned long long relocate_kernel_len;
   38.68 + 
   38.69 + int
   38.70 + machine_kexec_prepare(struct kimage *image)
   38.71 +--- a/arch/sh/kernel/machine_kexec.c
   38.72 ++++ b/arch/sh/kernel/machine_kexec.c
   38.73 +@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
   38.74 + 				unsigned long start_address,
   38.75 + 				unsigned long vbr_reg) ATTRIB_NORET;
   38.76 + 
   38.77 +-const extern unsigned char relocate_new_kernel[];
   38.78 +-const extern unsigned int relocate_new_kernel_size;
   38.79 ++extern const unsigned char relocate_new_kernel[];
   38.80 ++extern const unsigned int relocate_new_kernel_size;
   38.81 + extern void *gdb_vbr_vector;
   38.82 + 
   38.83 + /*
   38.84 +--- a/arch/x86_64/kernel/machine_kexec.c
   38.85 ++++ b/arch/x86_64/kernel/machine_kexec.c
   38.86 +@@ -149,8 +149,8 @@ typedef NORET_TYPE void (*relocate_new_k
   38.87 + 					unsigned long start_address,
   38.88 + 					unsigned long pgtable) ATTRIB_NORET;
   38.89 + 
   38.90 +-const extern unsigned char relocate_new_kernel[];
   38.91 +-const extern unsigned long relocate_new_kernel_size;
   38.92 ++extern const unsigned char relocate_new_kernel[];
   38.93 ++extern const unsigned long relocate_new_kernel_size;
   38.94 + 
   38.95 + int machine_kexec_prepare(struct kimage *image)
   38.96 + {
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/patches/linux-2.6.16.33/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch	Mon Dec 04 08:24:41 2006 -0700
    39.3 @@ -0,0 +1,401 @@
    39.4 +From: Magnus Damm <magnus@valinux.co.jp>
    39.5 +Date: Tue, 26 Sep 2006 08:52:38 +0000 (+0200)
    39.6 +Subject: [PATCH] i386: Avoid overwriting the current pgd (V4, i386)
    39.7 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3566561bfadffcb5dbc85d576be80c0dbf2cccc9
    39.8 +
    39.9 +[PATCH] i386: Avoid overwriting the current pgd (V4, i386)
   39.10 +
   39.11 +kexec: Avoid overwriting the current pgd (V4, i386)
   39.12 +
   39.13 +This patch upgrades the i386-specific kexec code to avoid overwriting the
   39.14 +current pgd. Overwriting the current pgd is bad when CONFIG_CRASH_DUMP is used
   39.15 +to start a secondary kernel that dumps the memory of the previous kernel.
   39.16 +
   39.17 +The code introduces a new set of page tables. These tables are used to provide
   39.18 +an executable identity mapping without overwriting the current pgd.
   39.19 +
   39.20 +Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
   39.21 +Signed-off-by: Andi Kleen <ak@suse.de>
   39.22 +---
   39.23 +
   39.24 +--- a/arch/i386/kernel/machine_kexec.c
   39.25 ++++ b/arch/i386/kernel/machine_kexec.c
   39.26 +@@ -21,70 +21,13 @@
   39.27 + #include <asm/system.h>
   39.28 + 
   39.29 + #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
   39.30 +-
   39.31 +-#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
   39.32 +-#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
   39.33 +-#define L2_ATTR (_PAGE_PRESENT)
   39.34 +-
   39.35 +-#define LEVEL0_SIZE (1UL << 12UL)
   39.36 +-
   39.37 +-#ifndef CONFIG_X86_PAE
   39.38 +-#define LEVEL1_SIZE (1UL << 22UL)
   39.39 +-static u32 pgtable_level1[1024] PAGE_ALIGNED;
   39.40 +-
   39.41 +-static void identity_map_page(unsigned long address)
   39.42 +-{
   39.43 +-	unsigned long level1_index, level2_index;
   39.44 +-	u32 *pgtable_level2;
   39.45 +-
   39.46 +-	/* Find the current page table */
   39.47 +-	pgtable_level2 = __va(read_cr3());
   39.48 +-
   39.49 +-	/* Find the indexes of the physical address to identity map */
   39.50 +-	level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
   39.51 +-	level2_index = address / LEVEL1_SIZE;
   39.52 +-
   39.53 +-	/* Identity map the page table entry */
   39.54 +-	pgtable_level1[level1_index] = address | L0_ATTR;
   39.55 +-	pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
   39.56 +-
   39.57 +-	/* Flush the tlb so the new mapping takes effect.
   39.58 +-	 * Global tlb entries are not flushed but that is not an issue.
   39.59 +-	 */
   39.60 +-	load_cr3(pgtable_level2);
   39.61 +-}
   39.62 +-
   39.63 +-#else
   39.64 +-#define LEVEL1_SIZE (1UL << 21UL)
   39.65 +-#define LEVEL2_SIZE (1UL << 30UL)
   39.66 +-static u64 pgtable_level1[512] PAGE_ALIGNED;
   39.67 +-static u64 pgtable_level2[512] PAGE_ALIGNED;
   39.68 +-
   39.69 +-static void identity_map_page(unsigned long address)
   39.70 +-{
   39.71 +-	unsigned long level1_index, level2_index, level3_index;
   39.72 +-	u64 *pgtable_level3;
   39.73 +-
   39.74 +-	/* Find the current page table */
   39.75 +-	pgtable_level3 = __va(read_cr3());
   39.76 +-
   39.77 +-	/* Find the indexes of the physical address to identity map */
   39.78 +-	level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
   39.79 +-	level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
   39.80 +-	level3_index = address / LEVEL2_SIZE;
   39.81 +-
   39.82 +-	/* Identity map the page table entry */
   39.83 +-	pgtable_level1[level1_index] = address | L0_ATTR;
   39.84 +-	pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
   39.85 +-	set_64bit(&pgtable_level3[level3_index],
   39.86 +-					       __pa(pgtable_level2) | L2_ATTR);
   39.87 +-
   39.88 +-	/* Flush the tlb so the new mapping takes effect.
   39.89 +-	 * Global tlb entries are not flushed but that is not an issue.
   39.90 +-	 */
   39.91 +-	load_cr3(pgtable_level3);
   39.92 +-}
   39.93 ++static u32 kexec_pgd[1024] PAGE_ALIGNED;
   39.94 ++#ifdef CONFIG_X86_PAE
   39.95 ++static u32 kexec_pmd0[1024] PAGE_ALIGNED;
   39.96 ++static u32 kexec_pmd1[1024] PAGE_ALIGNED;
   39.97 + #endif
   39.98 ++static u32 kexec_pte0[1024] PAGE_ALIGNED;
   39.99 ++static u32 kexec_pte1[1024] PAGE_ALIGNED;
  39.100 + 
  39.101 + static void set_idt(void *newidt, __u16 limit)
  39.102 + {
  39.103 +@@ -128,16 +71,6 @@ static void load_segments(void)
  39.104 + #undef __STR
  39.105 + }
  39.106 + 
  39.107 +-typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
  39.108 +-					unsigned long indirection_page,
  39.109 +-					unsigned long reboot_code_buffer,
  39.110 +-					unsigned long start_address,
  39.111 +-					unsigned int has_pae) ATTRIB_NORET;
  39.112 +-
  39.113 +-extern const unsigned char relocate_new_kernel[];
  39.114 +-extern void relocate_new_kernel_end(void);
  39.115 +-extern const unsigned int relocate_new_kernel_size;
  39.116 +-
  39.117 + /*
  39.118 +  * A architecture hook called to validate the
  39.119 +  * proposed image and prepare the control pages
  39.120 +@@ -170,25 +103,29 @@ void machine_kexec_cleanup(struct kimage
  39.121 +  */
  39.122 + NORET_TYPE void machine_kexec(struct kimage *image)
  39.123 + {
  39.124 +-	unsigned long page_list;
  39.125 +-	unsigned long reboot_code_buffer;
  39.126 +-
  39.127 +-	relocate_new_kernel_t rnk;
  39.128 ++	unsigned long page_list[PAGES_NR];
  39.129 ++	void *control_page;
  39.130 + 
  39.131 + 	/* Interrupts aren't acceptable while we reboot */
  39.132 + 	local_irq_disable();
  39.133 + 
  39.134 +-	/* Compute some offsets */
  39.135 +-	reboot_code_buffer = page_to_pfn(image->control_code_page)
  39.136 +-								<< PAGE_SHIFT;
  39.137 +-	page_list = image->head;
  39.138 +-
  39.139 +-	/* Set up an identity mapping for the reboot_code_buffer */
  39.140 +-	identity_map_page(reboot_code_buffer);
  39.141 +-
  39.142 +-	/* copy it out */
  39.143 +-	memcpy((void *)reboot_code_buffer, relocate_new_kernel,
  39.144 +-						relocate_new_kernel_size);
  39.145 ++	control_page = page_address(image->control_code_page);
  39.146 ++	memcpy(control_page, relocate_kernel, PAGE_SIZE);
  39.147 ++
  39.148 ++	page_list[PA_CONTROL_PAGE] = __pa(control_page);
  39.149 ++	page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
  39.150 ++	page_list[PA_PGD] = __pa(kexec_pgd);
  39.151 ++	page_list[VA_PGD] = (unsigned long)kexec_pgd;
  39.152 ++#ifdef CONFIG_X86_PAE
  39.153 ++	page_list[PA_PMD_0] = __pa(kexec_pmd0);
  39.154 ++	page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
  39.155 ++	page_list[PA_PMD_1] = __pa(kexec_pmd1);
  39.156 ++	page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
  39.157 ++#endif
  39.158 ++	page_list[PA_PTE_0] = __pa(kexec_pte0);
  39.159 ++	page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
  39.160 ++	page_list[PA_PTE_1] = __pa(kexec_pte1);
  39.161 ++	page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
  39.162 + 
  39.163 + 	/* The segment registers are funny things, they have both a
  39.164 + 	 * visible and an invisible part.  Whenever the visible part is
  39.165 +@@ -207,8 +144,8 @@ NORET_TYPE void machine_kexec(struct kim
  39.166 + 	set_idt(phys_to_virt(0),0);
  39.167 + 
  39.168 + 	/* now call it */
  39.169 +-	rnk = (relocate_new_kernel_t) reboot_code_buffer;
  39.170 +-	(*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
  39.171 ++	relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
  39.172 ++			image->start, cpu_has_pae);
  39.173 + }
  39.174 + 
  39.175 + /* crashkernel=size@addr specifies the location to reserve for
  39.176 +--- a/arch/i386/kernel/relocate_kernel.S
  39.177 ++++ b/arch/i386/kernel/relocate_kernel.S
  39.178 +@@ -7,16 +7,138 @@
  39.179 +  */
  39.180 + 
  39.181 + #include <linux/linkage.h>
  39.182 ++#include <asm/page.h>
  39.183 ++#include <asm/kexec.h>
  39.184 ++
  39.185 ++/*
  39.186 ++ * Must be relocatable PIC code callable as a C function
  39.187 ++ */
  39.188 ++
  39.189 ++#define PTR(x) (x << 2)
  39.190 ++#define PAGE_ALIGNED (1 << PAGE_SHIFT)
  39.191 ++#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
  39.192 ++#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */
  39.193 ++
  39.194 ++	.text
  39.195 ++	.align PAGE_ALIGNED
  39.196 ++	.globl relocate_kernel
  39.197 ++relocate_kernel:
  39.198 ++	movl	8(%esp), %ebp /* list of pages */
  39.199 ++
  39.200 ++#ifdef CONFIG_X86_PAE
  39.201 ++	/* map the control page at its virtual address */
  39.202 ++
  39.203 ++	movl	PTR(VA_PGD)(%ebp), %edi
  39.204 ++	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax
  39.205 ++	andl	$0xc0000000, %eax
  39.206 ++	shrl	$27, %eax
  39.207 ++	addl	%edi, %eax
  39.208 ++
  39.209 ++	movl	PTR(PA_PMD_0)(%ebp), %edx
  39.210 ++	orl	$PAE_PGD_ATTR, %edx
  39.211 ++	movl	%edx, (%eax)
  39.212 ++
  39.213 ++	movl	PTR(VA_PMD_0)(%ebp), %edi
  39.214 ++	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax
  39.215 ++	andl	$0x3fe00000, %eax
  39.216 ++	shrl	$18, %eax
  39.217 ++	addl	%edi, %eax
  39.218 ++
  39.219 ++	movl	PTR(PA_PTE_0)(%ebp), %edx
  39.220 ++	orl	$PAGE_ATTR, %edx
  39.221 ++	movl	%edx, (%eax)
  39.222 ++
  39.223 ++	movl	PTR(VA_PTE_0)(%ebp), %edi
  39.224 ++	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax
  39.225 ++	andl	$0x001ff000, %eax
  39.226 ++	shrl	$9, %eax
  39.227 ++	addl	%edi, %eax
  39.228 ++
  39.229 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edx
  39.230 ++	orl	$PAGE_ATTR, %edx
  39.231 ++	movl	%edx, (%eax)
  39.232 ++
  39.233 ++	/* identity map the control page at its physical address */
  39.234 ++
  39.235 ++	movl	PTR(VA_PGD)(%ebp), %edi
  39.236 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax
  39.237 ++	andl	$0xc0000000, %eax
  39.238 ++	shrl	$27, %eax
  39.239 ++	addl	%edi, %eax
  39.240 ++
  39.241 ++	movl	PTR(PA_PMD_1)(%ebp), %edx
  39.242 ++	orl	$PAE_PGD_ATTR, %edx
  39.243 ++	movl	%edx, (%eax)
  39.244 ++
  39.245 ++	movl	PTR(VA_PMD_1)(%ebp), %edi
  39.246 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax
  39.247 ++	andl	$0x3fe00000, %eax
  39.248 ++	shrl	$18, %eax
  39.249 ++	addl	%edi, %eax
  39.250 ++
  39.251 ++	movl	PTR(PA_PTE_1)(%ebp), %edx
  39.252 ++	orl	$PAGE_ATTR, %edx
  39.253 ++	movl	%edx, (%eax)
  39.254 ++
  39.255 ++	movl	PTR(VA_PTE_1)(%ebp), %edi
  39.256 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax
  39.257 ++	andl	$0x001ff000, %eax
  39.258 ++	shrl	$9, %eax
  39.259 ++	addl	%edi, %eax
  39.260 ++
  39.261 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edx
  39.262 ++	orl	$PAGE_ATTR, %edx
  39.263 ++	movl	%edx, (%eax)
  39.264 ++#else
  39.265 ++	/* map the control page at its virtual address */
  39.266 ++
  39.267 ++	movl	PTR(VA_PGD)(%ebp), %edi
  39.268 ++	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax
  39.269 ++	andl	$0xffc00000, %eax
  39.270 ++	shrl	$20, %eax
  39.271 ++	addl	%edi, %eax
  39.272 ++
  39.273 ++	movl	PTR(PA_PTE_0)(%ebp), %edx
  39.274 ++	orl	$PAGE_ATTR, %edx
  39.275 ++	movl	%edx, (%eax)
  39.276 ++
  39.277 ++	movl	PTR(VA_PTE_0)(%ebp), %edi
  39.278 ++	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax
  39.279 ++	andl	$0x003ff000, %eax
  39.280 ++	shrl	$10, %eax
  39.281 ++	addl	%edi, %eax
  39.282 ++
  39.283 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edx
  39.284 ++	orl	$PAGE_ATTR, %edx
  39.285 ++	movl	%edx, (%eax)
  39.286 ++
  39.287 ++	/* identity map the control page at its physical address */
  39.288 ++
  39.289 ++	movl	PTR(VA_PGD)(%ebp), %edi
  39.290 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax
  39.291 ++	andl	$0xffc00000, %eax
  39.292 ++	shrl	$20, %eax
  39.293 ++	addl	%edi, %eax
  39.294 ++
  39.295 ++	movl	PTR(PA_PTE_1)(%ebp), %edx
  39.296 ++	orl	$PAGE_ATTR, %edx
  39.297 ++	movl	%edx, (%eax)
  39.298 ++
  39.299 ++	movl	PTR(VA_PTE_1)(%ebp), %edi
  39.300 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax
  39.301 ++	andl	$0x003ff000, %eax
  39.302 ++	shrl	$10, %eax
  39.303 ++	addl	%edi, %eax
  39.304 ++
  39.305 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edx
  39.306 ++	orl	$PAGE_ATTR, %edx
  39.307 ++	movl	%edx, (%eax)
  39.308 ++#endif
  39.309 + 
  39.310 +-	/*
  39.311 +-	 * Must be relocatable PIC code callable as a C function, that once
  39.312 +-	 * it starts can not use the previous processes stack.
  39.313 +-	 */
  39.314 +-	.globl relocate_new_kernel
  39.315 + relocate_new_kernel:
  39.316 + 	/* read the arguments and say goodbye to the stack */
  39.317 + 	movl  4(%esp), %ebx /* page_list */
  39.318 +-	movl  8(%esp), %ebp /* reboot_code_buffer */
  39.319 ++	movl  8(%esp), %ebp /* list of pages */
  39.320 + 	movl  12(%esp), %edx /* start address */
  39.321 + 	movl  16(%esp), %ecx /* cpu_has_pae */
  39.322 + 
  39.323 +@@ -24,11 +146,26 @@ relocate_new_kernel:
  39.324 + 	pushl $0
  39.325 + 	popfl
  39.326 + 
  39.327 +-	/* set a new stack at the bottom of our page... */
  39.328 +-	lea   4096(%ebp), %esp
  39.329 ++	/* get physical address of control page now */
  39.330 ++	/* this is impossible after page table switch */
  39.331 ++	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edi
  39.332 ++
  39.333 ++	/* switch to new set of page tables */
  39.334 ++	movl	PTR(PA_PGD)(%ebp), %eax
  39.335 ++	movl	%eax, %cr3
  39.336 ++
  39.337 ++	/* setup a new stack at the end of the physical control page */
  39.338 ++	lea	4096(%edi), %esp
  39.339 + 
  39.340 +-	/* store the parameters back on the stack */
  39.341 +-	pushl   %edx /* store the start address */
  39.342 ++	/* jump to identity mapped page */
  39.343 ++	movl    %edi, %eax
  39.344 ++	addl    $(identity_mapped - relocate_kernel), %eax
  39.345 ++	pushl   %eax
  39.346 ++	ret
  39.347 ++
  39.348 ++identity_mapped:
  39.349 ++	/* store the start address on the stack */
  39.350 ++	pushl   %edx
  39.351 + 
  39.352 + 	/* Set cr0 to a known state:
  39.353 + 	 * 31 0 == Paging disabled
  39.354 +@@ -113,8 +250,3 @@ relocate_new_kernel:
  39.355 + 	xorl    %edi, %edi
  39.356 + 	xorl    %ebp, %ebp
  39.357 + 	ret
  39.358 +-relocate_new_kernel_end:
  39.359 +-
  39.360 +-	.globl relocate_new_kernel_size
  39.361 +-relocate_new_kernel_size:
  39.362 +-	.long relocate_new_kernel_end - relocate_new_kernel
  39.363 +--- a/include/asm-i386/kexec.h
  39.364 ++++ b/include/asm-i386/kexec.h
  39.365 +@@ -1,6 +1,26 @@
  39.366 + #ifndef _I386_KEXEC_H
  39.367 + #define _I386_KEXEC_H
  39.368 + 
  39.369 ++#define PA_CONTROL_PAGE  0
  39.370 ++#define VA_CONTROL_PAGE  1
  39.371 ++#define PA_PGD           2
  39.372 ++#define VA_PGD           3
  39.373 ++#define PA_PTE_0         4
  39.374 ++#define VA_PTE_0         5
  39.375 ++#define PA_PTE_1         6
  39.376 ++#define VA_PTE_1         7
  39.377 ++#ifdef CONFIG_X86_PAE
  39.378 ++#define PA_PMD_0         8
  39.379 ++#define VA_PMD_0         9
  39.380 ++#define PA_PMD_1         10
  39.381 ++#define VA_PMD_1         11
  39.382 ++#define PAGES_NR         12
  39.383 ++#else
  39.384 ++#define PAGES_NR         8
  39.385 ++#endif
  39.386 ++
  39.387 ++#ifndef __ASSEMBLY__
  39.388 ++
  39.389 + #include <asm/fixmap.h>
  39.390 + #include <asm/ptrace.h>
  39.391 + #include <asm/string.h>
  39.392 +@@ -72,5 +92,12 @@ static inline void crash_setup_regs(stru
  39.393 +                newregs->eip = (unsigned long)current_text_addr();
  39.394 +        }
  39.395 + }
  39.396 ++asmlinkage NORET_TYPE void
  39.397 ++relocate_kernel(unsigned long indirection_page,
  39.398 ++		unsigned long control_page,
  39.399 ++		unsigned long start_address,
  39.400 ++		unsigned int has_pae) ATTRIB_NORET;
  39.401 ++
  39.402 ++#endif /* __ASSEMBLY__ */
  39.403 + 
  39.404 + #endif /* _I386_KEXEC_H */
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/patches/linux-2.6.16.33/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch	Mon Dec 04 08:24:41 2006 -0700
    40.3 @@ -0,0 +1,375 @@
    40.4 +From: Magnus Damm <magnus@valinux.co.jp>
    40.5 +Date: Tue, 26 Sep 2006 08:52:38 +0000 (+0200)
    40.6 +Subject: [PATCH] Avoid overwriting the current pgd (V4, x86_64)
    40.7 +X-Git-Tag: v2.6.19-rc1
    40.8 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f
    40.9 +
   40.10 +[PATCH] Avoid overwriting the current pgd (V4, x86_64)
   40.11 +
   40.12 +kexec: Avoid overwriting the current pgd (V4, x86_64)
   40.13 +
   40.14 +This patch upgrades the x86_64-specific kexec code to avoid overwriting the
   40.15 +current pgd. Overwriting the current pgd is bad when CONFIG_CRASH_DUMP is used
   40.16 +to start a secondary kernel that dumps the memory of the previous kernel.
   40.17 +
   40.18 +The code introduces a new set of page tables. These tables are used to provide
   40.19 +an executable identity mapping without overwriting the current pgd.
   40.20 +
   40.21 +Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
   40.22 +Signed-off-by: Andi Kleen <ak@suse.de>
   40.23 +---
   40.24 +
   40.25 +--- a/arch/x86_64/kernel/machine_kexec.c
   40.26 ++++ b/arch/x86_64/kernel/machine_kexec.c
   40.27 +@@ -15,6 +15,15 @@
   40.28 + #include <asm/mmu_context.h>
   40.29 + #include <asm/io.h>
   40.30 + 
   40.31 ++#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
   40.32 ++static u64 kexec_pgd[512] PAGE_ALIGNED;
   40.33 ++static u64 kexec_pud0[512] PAGE_ALIGNED;
   40.34 ++static u64 kexec_pmd0[512] PAGE_ALIGNED;
   40.35 ++static u64 kexec_pte0[512] PAGE_ALIGNED;
   40.36 ++static u64 kexec_pud1[512] PAGE_ALIGNED;
   40.37 ++static u64 kexec_pmd1[512] PAGE_ALIGNED;
   40.38 ++static u64 kexec_pte1[512] PAGE_ALIGNED;
   40.39 ++
   40.40 + static void init_level2_page(pmd_t *level2p, unsigned long addr)
   40.41 + {
   40.42 + 	unsigned long end_addr;
   40.43 +@@ -144,32 +153,19 @@ static void load_segments(void)
   40.44 + 		);
   40.45 + }
   40.46 + 
   40.47 +-typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page,
   40.48 +-					unsigned long control_code_buffer,
   40.49 +-					unsigned long start_address,
   40.50 +-					unsigned long pgtable) ATTRIB_NORET;
   40.51 +-
   40.52 +-extern const unsigned char relocate_new_kernel[];
   40.53 +-extern const unsigned long relocate_new_kernel_size;
   40.54 +-
   40.55 + int machine_kexec_prepare(struct kimage *image)
   40.56 + {
   40.57 +-	unsigned long start_pgtable, control_code_buffer;
   40.58 ++	unsigned long start_pgtable;
   40.59 + 	int result;
   40.60 + 
   40.61 + 	/* Calculate the offsets */
   40.62 + 	start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
   40.63 +-	control_code_buffer = start_pgtable + PAGE_SIZE;
   40.64 + 
   40.65 + 	/* Setup the identity mapped 64bit page table */
   40.66 + 	result = init_pgtable(image, start_pgtable);
   40.67 + 	if (result)
   40.68 + 		return result;
   40.69 + 
   40.70 +-	/* Place the code in the reboot code buffer */
   40.71 +-	memcpy(__va(control_code_buffer), relocate_new_kernel,
   40.72 +-						relocate_new_kernel_size);
   40.73 +-
   40.74 + 	return 0;
   40.75 + }
   40.76 + 
   40.77 +@@ -184,28 +180,34 @@ void machine_kexec_cleanup(struct kimage
   40.78 +  */
   40.79 + NORET_TYPE void machine_kexec(struct kimage *image)
   40.80 + {
   40.81 +-	unsigned long page_list;
   40.82 +-	unsigned long control_code_buffer;
   40.83 +-	unsigned long start_pgtable;
   40.84 +-	relocate_new_kernel_t rnk;
   40.85 ++	unsigned long page_list[PAGES_NR];
   40.86 ++	void *control_page;
   40.87 + 
   40.88 + 	/* Interrupts aren't acceptable while we reboot */
   40.89 + 	local_irq_disable();
   40.90 + 
   40.91 +-	/* Calculate the offsets */
   40.92 +-	page_list = image->head;
   40.93 +-	start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
   40.94 +-	control_code_buffer = start_pgtable + PAGE_SIZE;
   40.95 ++	control_page = page_address(image->control_code_page) + PAGE_SIZE;
   40.96 ++	memcpy(control_page, relocate_kernel, PAGE_SIZE);
   40.97 + 
   40.98 +-	/* Set the low half of the page table to my identity mapped
   40.99 +-	 * page table for kexec.  Leave the high half pointing at the
  40.100 +-	 * kernel pages.   Don't bother to flush the global pages
  40.101 +-	 * as that will happen when I fully switch to my identity mapped
  40.102 +-	 * page table anyway.
  40.103 +-	 */
  40.104 +-	memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2);
  40.105 +-	__flush_tlb();
  40.106 ++	page_list[PA_CONTROL_PAGE] = __pa(control_page);
  40.107 ++	page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
  40.108 ++	page_list[PA_PGD] = __pa(kexec_pgd);
  40.109 ++	page_list[VA_PGD] = (unsigned long)kexec_pgd;
  40.110 ++	page_list[PA_PUD_0] = __pa(kexec_pud0);
  40.111 ++	page_list[VA_PUD_0] = (unsigned long)kexec_pud0;
  40.112 ++	page_list[PA_PMD_0] = __pa(kexec_pmd0);
  40.113 ++	page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
  40.114 ++	page_list[PA_PTE_0] = __pa(kexec_pte0);
  40.115 ++	page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
  40.116 ++	page_list[PA_PUD_1] = __pa(kexec_pud1);
  40.117 ++	page_list[VA_PUD_1] = (unsigned long)kexec_pud1;
  40.118 ++	page_list[PA_PMD_1] = __pa(kexec_pmd1);
  40.119 ++	page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
  40.120 ++	page_list[PA_PTE_1] = __pa(kexec_pte1);
  40.121 ++	page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
  40.122 + 
  40.123 ++	page_list[PA_TABLE_PAGE] =
  40.124 ++	  (unsigned long)__pa(page_address(image->control_code_page));
  40.125 + 
  40.126 + 	/* The segment registers are funny things, they have both a
  40.127 + 	 * visible and an invisible part.  Whenever the visible part is
  40.128 +@@ -222,9 +224,10 @@ NORET_TYPE void machine_kexec(struct kim
  40.129 + 	 */
  40.130 + 	set_gdt(phys_to_virt(0),0);
  40.131 + 	set_idt(phys_to_virt(0),0);
  40.132 ++
  40.133 + 	/* now call it */
  40.134 +-	rnk = (relocate_new_kernel_t) control_code_buffer;
  40.135 +-	(*rnk)(page_list, control_code_buffer, image->start, start_pgtable);
  40.136 ++	relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
  40.137 ++			image->start);
  40.138 + }
  40.139 + 
  40.140 + /* crashkernel=size@addr specifies the location to reserve for
  40.141 +--- a/arch/x86_64/kernel/relocate_kernel.S
  40.142 ++++ b/arch/x86_64/kernel/relocate_kernel.S
  40.143 +@@ -7,31 +7,169 @@
  40.144 +  */
  40.145 + 
  40.146 + #include <linux/linkage.h>
  40.147 ++#include <asm/page.h>
  40.148 ++#include <asm/kexec.h>
  40.149 + 
  40.150 +-	/*
  40.151 +-	 * Must be relocatable PIC code callable as a C function, that once
  40.152 +-	 * it starts can not use the previous processes stack.
  40.153 +-	 */
  40.154 +-	.globl relocate_new_kernel
  40.155 ++/*
  40.156 ++ * Must be relocatable PIC code callable as a C function
  40.157 ++ */
  40.158 ++
  40.159 ++#define PTR(x) (x << 3)
  40.160 ++#define PAGE_ALIGNED (1 << PAGE_SHIFT)
  40.161 ++#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
  40.162 ++
  40.163 ++	.text
  40.164 ++	.align PAGE_ALIGNED
  40.165 + 	.code64
  40.166 ++	.globl relocate_kernel
  40.167 ++relocate_kernel:
  40.168 ++	/* %rdi indirection_page
  40.169 ++	 * %rsi page_list
  40.170 ++	 * %rdx start address
  40.171 ++	 */
  40.172 ++
  40.173 ++	/* map the control page at its virtual address */
  40.174 ++
  40.175 ++	movq	$0x0000ff8000000000, %r10        /* mask */
  40.176 ++	mov	$(39 - 3), %cl                   /* bits to shift */
  40.177 ++	movq	PTR(VA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
  40.178 ++
  40.179 ++	movq	%r11, %r9
  40.180 ++	andq	%r10, %r9
  40.181 ++	shrq	%cl, %r9
  40.182 ++
  40.183 ++	movq	PTR(VA_PGD)(%rsi), %r8
  40.184 ++	addq	%r8, %r9
  40.185 ++	movq	PTR(PA_PUD_0)(%rsi), %r8
  40.186 ++	orq	$PAGE_ATTR, %r8
  40.187 ++	movq	%r8, (%r9)
  40.188 ++
  40.189 ++	shrq	$9, %r10
  40.190 ++	sub	$9, %cl
  40.191 ++
  40.192 ++	movq	%r11, %r9
  40.193 ++	andq	%r10, %r9
  40.194 ++	shrq	%cl, %r9
  40.195 ++
  40.196 ++	movq	PTR(VA_PUD_0)(%rsi), %r8
  40.197 ++	addq	%r8, %r9
  40.198 ++	movq	PTR(PA_PMD_0)(%rsi), %r8
  40.199 ++	orq	$PAGE_ATTR, %r8
  40.200 ++	movq	%r8, (%r9)
  40.201 ++
  40.202 ++	shrq	$9, %r10
  40.203 ++	sub	$9, %cl
  40.204 ++
  40.205 ++	movq	%r11, %r9
  40.206 ++	andq	%r10, %r9
  40.207 ++	shrq	%cl, %r9
  40.208 ++
  40.209 ++	movq	PTR(VA_PMD_0)(%rsi), %r8
  40.210 ++	addq	%r8, %r9
  40.211 ++	movq	PTR(PA_PTE_0)(%rsi), %r8
  40.212 ++	orq	$PAGE_ATTR, %r8
  40.213 ++	movq	%r8, (%r9)
  40.214 ++
  40.215 ++	shrq	$9, %r10
  40.216 ++	sub	$9, %cl
  40.217 ++
  40.218 ++	movq	%r11, %r9
  40.219 ++	andq	%r10, %r9
  40.220 ++	shrq	%cl, %r9
  40.221 ++
  40.222 ++	movq	PTR(VA_PTE_0)(%rsi), %r8
  40.223 ++	addq	%r8, %r9
  40.224 ++	movq	PTR(PA_CONTROL_PAGE)(%rsi), %r8
  40.225 ++	orq	$PAGE_ATTR, %r8
  40.226 ++	movq	%r8, (%r9)
  40.227 ++
  40.228 ++	/* identity map the control page at its physical address */
  40.229 ++
  40.230 ++	movq	$0x0000ff8000000000, %r10        /* mask */
  40.231 ++	mov	$(39 - 3), %cl                   /* bits to shift */
  40.232 ++	movq	PTR(PA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
  40.233 ++
  40.234 ++	movq	%r11, %r9
  40.235 ++	andq	%r10, %r9
  40.236 ++	shrq	%cl, %r9
  40.237 ++
  40.238 ++	movq	PTR(VA_PGD)(%rsi), %r8
  40.239 ++	addq	%r8, %r9
  40.240 ++	movq	PTR(PA_PUD_1)(%rsi), %r8
  40.241 ++	orq	$PAGE_ATTR, %r8
  40.242 ++	movq	%r8, (%r9)
  40.243 ++
  40.244 ++	shrq	$9, %r10
  40.245 ++	sub	$9, %cl
  40.246 ++
  40.247 ++	movq	%r11, %r9
  40.248 ++	andq	%r10, %r9
  40.249 ++	shrq	%cl, %r9
  40.250 ++
  40.251 ++	movq	PTR(VA_PUD_1)(%rsi), %r8
  40.252 ++	addq	%r8, %r9
  40.253 ++	movq	PTR(PA_PMD_1)(%rsi), %r8
  40.254 ++	orq	$PAGE_ATTR, %r8
  40.255 ++	movq	%r8, (%r9)
  40.256 ++
  40.257 ++	shrq	$9, %r10
  40.258 ++	sub	$9, %cl
  40.259 ++
  40.260 ++	movq	%r11, %r9
  40.261 ++	andq	%r10, %r9
  40.262 ++	shrq	%cl, %r9
  40.263 ++
  40.264 ++	movq	PTR(VA_PMD_1)(%rsi), %r8
  40.265 ++	addq	%r8, %r9
  40.266 ++	movq	PTR(PA_PTE_1)(%rsi), %r8
  40.267 ++	orq	$PAGE_ATTR, %r8
  40.268 ++	movq	%r8, (%r9)
  40.269 ++
  40.270 ++	shrq	$9, %r10
  40.271 ++	sub	$9, %cl
  40.272 ++
  40.273 ++	movq	%r11, %r9
  40.274 ++	andq	%r10, %r9
  40.275 ++	shrq	%cl, %r9
  40.276 ++
  40.277 ++	movq	PTR(VA_PTE_1)(%rsi), %r8
  40.278 ++	addq	%r8, %r9
  40.279 ++	movq	PTR(PA_CONTROL_PAGE)(%rsi), %r8
  40.280 ++	orq	$PAGE_ATTR, %r8
  40.281 ++	movq	%r8, (%r9)
  40.282 ++
  40.283 + relocate_new_kernel:
  40.284 +-	/* %rdi page_list
  40.285 +-	 * %rsi reboot_code_buffer
  40.286 ++	/* %rdi indirection_page
  40.287 ++	 * %rsi page_list
  40.288 + 	 * %rdx start address
  40.289 +-	 * %rcx page_table
  40.290 +-	 * %r8  arg5
  40.291 +-	 * %r9  arg6
  40.292 + 	 */
  40.293 + 
  40.294 + 	/* zero out flags, and disable interrupts */
  40.295 + 	pushq $0
  40.296 + 	popfq
  40.297 + 
  40.298 +-	/* set a new stack at the bottom of our page... */
  40.299 +-	lea   4096(%rsi), %rsp
  40.300 ++	/* get physical address of control page now */
  40.301 ++	/* this is impossible after page table switch */
  40.302 ++	movq	PTR(PA_CONTROL_PAGE)(%rsi), %r8
  40.303 ++
  40.304 ++	/* get physical address of page table now too */
  40.305 ++	movq	PTR(PA_TABLE_PAGE)(%rsi), %rcx
  40.306 ++
  40.307 ++	/* switch to new set of page tables */
  40.308 ++	movq	PTR(PA_PGD)(%rsi), %r9
  40.309 ++	movq	%r9, %cr3
  40.310 ++
  40.311 ++	/* setup a new stack at the end of the physical control page */
  40.312 ++	lea	4096(%r8), %rsp
  40.313 ++
  40.314 ++	/* jump to identity mapped page */
  40.315 ++	addq	$(identity_mapped - relocate_kernel), %r8
  40.316 ++	pushq	%r8
  40.317 ++	ret
  40.318 + 
  40.319 +-	/* store the parameters back on the stack */
  40.320 +-	pushq	%rdx /* store the start address */
  40.321 ++identity_mapped:
  40.322 ++	/* store the start address on the stack */
  40.323 ++	pushq   %rdx
  40.324 + 
  40.325 + 	/* Set cr0 to a known state:
  40.326 + 	 * 31 1 == Paging enabled
  40.327 +@@ -136,8 +274,3 @@ relocate_new_kernel:
  40.328 + 	xorq	%r15, %r15
  40.329 + 
  40.330 + 	ret
  40.331 +-relocate_new_kernel_end:
  40.332 +-
  40.333 +-	.globl relocate_new_kernel_size
  40.334 +-relocate_new_kernel_size:
  40.335 +-	.quad relocate_new_kernel_end - relocate_new_kernel
  40.336 +--- a/include/asm-x86_64/kexec.h
  40.337 ++++ b/include/asm-x86_64/kexec.h
  40.338 +@@ -1,6 +1,27 @@
  40.339 + #ifndef _X86_64_KEXEC_H
  40.340 + #define _X86_64_KEXEC_H
  40.341 + 
  40.342 ++#define PA_CONTROL_PAGE  0
  40.343 ++#define VA_CONTROL_PAGE  1
  40.344 ++#define PA_PGD           2
  40.345 ++#define VA_PGD           3
  40.346 ++#define PA_PUD_0         4
  40.347 ++#define VA_PUD_0         5
  40.348 ++#define PA_PMD_0         6
  40.349 ++#define VA_PMD_0         7
  40.350 ++#define PA_PTE_0         8
  40.351 ++#define VA_PTE_0         9
  40.352 ++#define PA_PUD_1         10
  40.353 ++#define VA_PUD_1         11
  40.354 ++#define PA_PMD_1         12
  40.355 ++#define VA_PMD_1         13
  40.356 ++#define PA_PTE_1         14
  40.357 ++#define VA_PTE_1         15
  40.358 ++#define PA_TABLE_PAGE    16
  40.359 ++#define PAGES_NR         17
  40.360 ++
  40.361 ++#ifndef __ASSEMBLY__
  40.362 ++
  40.363 + #include <linux/string.h>
  40.364 + 
  40.365 + #include <asm/page.h>
  40.366 +@@ -64,4 +85,12 @@ static inline void crash_setup_regs(stru
  40.367 + 		newregs->rip = (unsigned long)current_text_addr();
  40.368 + 	}
  40.369 + }
  40.370 ++
  40.371 ++NORET_TYPE void
  40.372 ++relocate_kernel(unsigned long indirection_page,
  40.373 ++		unsigned long page_list,
  40.374 ++		unsigned long start_address) ATTRIB_NORET;
  40.375 ++
  40.376 ++#endif /* __ASSEMBLY__ */
  40.377 ++
  40.378 + #endif /* _X86_64_KEXEC_H */
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/patches/linux-2.6.16.33/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch	Mon Dec 04 08:24:41 2006 -0700
    41.3 @@ -0,0 +1,47 @@
    41.4 +commit dbaab49f92ff6ae6255762a948375e4036cbdbd2
    41.5 +Author: Vivek Goyal <vgoyal@in.ibm.com>
    41.6 +Date:   Sat Oct 21 18:37:03 2006 +0200
    41.7 +
    41.8 +    [PATCH] x86-64: Overlapping program headers in physical addr space fix
    41.9 +    
   41.10 +    o A recent change to vmlinux.ld.S file broke kexec as now resulting vmlinux
   41.11 +      program headers are overlapping in physical address space.
   41.12 +    
   41.13 +    o Now all the vsyscall related sections are placed after data and after
   41.14 +      that mostly init data sections are placed. To avoid physical overlap
   41.15 +      among phdrs, there are three possible solutions.
   41.16 +    	- Place vsyscall sections also in data phdrs instead of user
   41.17 +    	- move vsyscal sections after init data in bss.
   41.18 +    	- create another phdrs say data.init and move all the sections
   41.19 +    	  after vsyscall into this new phdr.
   41.20 +    
   41.21 +    o This patch implements the third solution.
   41.22 +    
   41.23 +    Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com>
   41.24 +    Signed-off-by: Andi Kleen <ak@suse.de>
   41.25 +    Cc: Magnus Damm <magnus@valinux.co.jp>
   41.26 +    Cc: Andi Kleen <ak@suse.de>
   41.27 +    Cc: "Eric W. Biederman" <ebiederm@xmission.com>
   41.28 +    Signed-off-by: Andrew Morton <akpm@osdl.org>
   41.29 +
   41.30 +diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
   41.31 +index b9df2ab..1283614 100644
   41.32 +--- a/arch/x86_64/kernel/vmlinux.lds.S
   41.33 ++++ b/arch/x86_64/kernel/vmlinux.lds.S
   41.34 +@@ -17,6 +17,7 @@ PHDRS {
   41.35 + 	text PT_LOAD FLAGS(5);	/* R_E */
   41.36 + 	data PT_LOAD FLAGS(7);	/* RWE */
   41.37 + 	user PT_LOAD FLAGS(7);	/* RWE */
   41.38 ++	data.init PT_LOAD FLAGS(7);	/* RWE */
   41.39 + 	note PT_NOTE FLAGS(4);	/* R__ */
   41.40 + }
   41.41 + SECTIONS
   41.42 +@@ -131,7 +132,7 @@ SECTIONS
   41.43 +   . = ALIGN(8192);		/* init_task */
   41.44 +   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
   41.45 + 	*(.data.init_task)
   41.46 +-  } :data
   41.47 ++  }:data.init
   41.48 + 
   41.49 +   . = ALIGN(4096);
   41.50 +   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/patches/linux-2.6.16.33/kexec-generic.patch	Mon Dec 04 08:24:41 2006 -0700
    42.3 @@ -0,0 +1,228 @@
    42.4 +--- 0001/include/linux/kexec.h
    42.5 ++++ work/include/linux/kexec.h
    42.6 +@@ -31,6 +31,13 @@
    42.7 + #error KEXEC_ARCH not defined
    42.8 + #endif
    42.9 + 
   42.10 ++#ifndef KEXEC_ARCH_HAS_PAGE_MACROS
   42.11 ++#define kexec_page_to_pfn(page)  page_to_pfn(page)
   42.12 ++#define kexec_pfn_to_page(pfn)   pfn_to_page(pfn)
   42.13 ++#define kexec_virt_to_phys(addr) virt_to_phys(addr)
   42.14 ++#define kexec_phys_to_virt(addr) phys_to_virt(addr)
   42.15 ++#endif
   42.16 ++
   42.17 + /*
   42.18 +  * This structure is used to hold the arguments that are used when loading
   42.19 +  * kernel binaries.
   42.20 +@@ -91,6 +98,13 @@ struct kimage {
   42.21 + extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET;
   42.22 + extern int machine_kexec_prepare(struct kimage *image);
   42.23 + extern void machine_kexec_cleanup(struct kimage *image);
   42.24 ++#ifdef CONFIG_XEN
   42.25 ++extern int xen_machine_kexec_load(struct kimage *image);
   42.26 ++extern void xen_machine_kexec_unload(struct kimage *image);
   42.27 ++extern NORET_TYPE void xen_machine_kexec(struct kimage *image) ATTRIB_NORET;
   42.28 ++extern void xen_machine_kexec_setup_resources(void);
   42.29 ++extern void xen_machine_kexec_register_resources(struct resource *res);
   42.30 ++#endif
   42.31 + extern asmlinkage long sys_kexec_load(unsigned long entry,
   42.32 + 					unsigned long nr_segments,
   42.33 + 					struct kexec_segment __user *segments,
   42.34 +--- 0001/kernel/kexec.c
   42.35 ++++ work/kernel/kexec.c
   42.36 +@@ -403,7 +403,7 @@ static struct page *kimage_alloc_normal_
   42.37 + 		pages = kimage_alloc_pages(GFP_KERNEL, order);
   42.38 + 		if (!pages)
   42.39 + 			break;
   42.40 +-		pfn   = page_to_pfn(pages);
   42.41 ++		pfn   = kexec_page_to_pfn(pages);
   42.42 + 		epfn  = pfn + count;
   42.43 + 		addr  = pfn << PAGE_SHIFT;
   42.44 + 		eaddr = epfn << PAGE_SHIFT;
   42.45 +@@ -437,6 +437,7 @@ static struct page *kimage_alloc_normal_
   42.46 + 	return pages;
   42.47 + }
   42.48 + 
   42.49 ++#ifndef CONFIG_XEN
   42.50 + static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
   42.51 + 						      unsigned int order)
   42.52 + {
   42.53 +@@ -490,7 +491,7 @@ static struct page *kimage_alloc_crash_c
   42.54 + 		}
   42.55 + 		/* If I don't overlap any segments I have found my hole! */
   42.56 + 		if (i == image->nr_segments) {
   42.57 +-			pages = pfn_to_page(hole_start >> PAGE_SHIFT);
   42.58 ++			pages = kexec_pfn_to_page(hole_start >> PAGE_SHIFT);
   42.59 + 			break;
   42.60 + 		}
   42.61 + 	}
   42.62 +@@ -517,6 +518,13 @@ struct page *kimage_alloc_control_pages(
   42.63 + 
   42.64 + 	return pages;
   42.65 + }
   42.66 ++#else /* !CONFIG_XEN */
   42.67 ++struct page *kimage_alloc_control_pages(struct kimage *image,
   42.68 ++					 unsigned int order)
   42.69 ++{
   42.70 ++	return kimage_alloc_normal_control_pages(image, order);
   42.71 ++}
   42.72 ++#endif
   42.73 + 
   42.74 + static int kimage_add_entry(struct kimage *image, kimage_entry_t entry)
   42.75 + {
   42.76 +@@ -532,7 +540,7 @@ static int kimage_add_entry(struct kimag
   42.77 + 			return -ENOMEM;
   42.78 + 
   42.79 + 		ind_page = page_address(page);
   42.80 +-		*image->entry = virt_to_phys(ind_page) | IND_INDIRECTION;
   42.81 ++		*image->entry = kexec_virt_to_phys(ind_page) | IND_INDIRECTION;
   42.82 + 		image->entry = ind_page;
   42.83 + 		image->last_entry = ind_page +
   42.84 + 				      ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1);
   42.85 +@@ -593,13 +601,13 @@ static int kimage_terminate(struct kimag
   42.86 + #define for_each_kimage_entry(image, ptr, entry) \
   42.87 + 	for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \
   42.88 + 		ptr = (entry & IND_INDIRECTION)? \
   42.89 +-			phys_to_virt((entry & PAGE_MASK)): ptr +1)
   42.90 ++			kexec_phys_to_virt((entry & PAGE_MASK)): ptr +1)
   42.91 + 
   42.92 + static void kimage_free_entry(kimage_entry_t entry)
   42.93 + {
   42.94 + 	struct page *page;
   42.95 + 
   42.96 +-	page = pfn_to_page(entry >> PAGE_SHIFT);
   42.97 ++	page = kexec_pfn_to_page(entry >> PAGE_SHIFT);
   42.98 + 	kimage_free_pages(page);
   42.99 + }
  42.100 + 
  42.101 +@@ -611,6 +619,10 @@ static void kimage_free(struct kimage *i
  42.102 + 	if (!image)
  42.103 + 		return;
  42.104 + 
  42.105 ++#ifdef CONFIG_XEN
  42.106 ++	xen_machine_kexec_unload(image);
  42.107 ++#endif
  42.108 ++
  42.109 + 	kimage_free_extra_pages(image);
  42.110 + 	for_each_kimage_entry(image, ptr, entry) {
  42.111 + 		if (entry & IND_INDIRECTION) {
  42.112 +@@ -686,7 +698,7 @@ static struct page *kimage_alloc_page(st
  42.113 + 	 * have a match.
  42.114 + 	 */
  42.115 + 	list_for_each_entry(page, &image->dest_pages, lru) {
  42.116 +-		addr = page_to_pfn(page) << PAGE_SHIFT;
  42.117 ++		addr = kexec_page_to_pfn(page) << PAGE_SHIFT;
  42.118 + 		if (addr == destination) {
  42.119 + 			list_del(&page->lru);
  42.120 + 			return page;
  42.121 +@@ -701,12 +713,12 @@ static struct page *kimage_alloc_page(st
  42.122 + 		if (!page)
  42.123 + 			return NULL;
  42.124 + 		/* If the page cannot be used file it away */
  42.125 +-		if (page_to_pfn(page) >
  42.126 ++		if (kexec_page_to_pfn(page) >
  42.127 + 				(KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {
  42.128 + 			list_add(&page->lru, &image->unuseable_pages);
  42.129 + 			continue;
  42.130 + 		}
  42.131 +-		addr = page_to_pfn(page) << PAGE_SHIFT;
  42.132 ++		addr = kexec_page_to_pfn(page) << PAGE_SHIFT;
  42.133 + 
  42.134 + 		/* If it is the destination page we want use it */
  42.135 + 		if (addr == destination)
  42.136 +@@ -729,7 +741,7 @@ static struct page *kimage_alloc_page(st
  42.137 + 			struct page *old_page;
  42.138 + 
  42.139 + 			old_addr = *old & PAGE_MASK;
  42.140 +-			old_page = pfn_to_page(old_addr >> PAGE_SHIFT);
  42.141 ++			old_page = kexec_pfn_to_page(old_addr >> PAGE_SHIFT);
  42.142 + 			copy_highpage(page, old_page);
  42.143 + 			*old = addr | (*old & ~PAGE_MASK);
  42.144 + 
  42.145 +@@ -779,7 +791,7 @@ static int kimage_load_normal_segment(st
  42.146 + 			result  = -ENOMEM;
  42.147 + 			goto out;
  42.148 + 		}
  42.149 +-		result = kimage_add_page(image, page_to_pfn(page)
  42.150 ++		result = kimage_add_page(image, kexec_page_to_pfn(page)
  42.151 + 								<< PAGE_SHIFT);
  42.152 + 		if (result < 0)
  42.153 + 			goto out;
  42.154 +@@ -811,6 +823,7 @@ out:
  42.155 + 	return result;
  42.156 + }
  42.157 + 
  42.158 ++#ifndef CONFIG_XEN
  42.159 + static int kimage_load_crash_segment(struct kimage *image,
  42.160 + 					struct kexec_segment *segment)
  42.161 + {
  42.162 +@@ -833,7 +846,7 @@ static int kimage_load_crash_segment(str
  42.163 + 		char *ptr;
  42.164 + 		size_t uchunk, mchunk;
  42.165 + 
  42.166 +-		page = pfn_to_page(maddr >> PAGE_SHIFT);
  42.167 ++		page = kexec_pfn_to_page(maddr >> PAGE_SHIFT);
  42.168 + 		if (page == 0) {
  42.169 + 			result  = -ENOMEM;
  42.170 + 			goto out;
  42.171 +@@ -881,6 +894,13 @@ static int kimage_load_segment(struct ki
  42.172 + 
  42.173 + 	return result;
  42.174 + }
  42.175 ++#else /* CONFIG_XEN */
  42.176 ++static int kimage_load_segment(struct kimage *image,
  42.177 ++				struct kexec_segment *segment)
  42.178 ++{
  42.179 ++	return kimage_load_normal_segment(image, segment);
  42.180 ++}
  42.181 ++#endif
  42.182 + 
  42.183 + /*
  42.184 +  * Exec Kernel system call: for obvious reasons only root may call it.
  42.185 +@@ -991,6 +1011,11 @@ asmlinkage long sys_kexec_load(unsigned 
  42.186 + 		if (result)
  42.187 + 			goto out;
  42.188 + 	}
  42.189 ++#ifdef CONFIG_XEN
  42.190 ++	result = xen_machine_kexec_load(image);
  42.191 ++	if (result)
  42.192 ++		goto out;
  42.193 ++#endif
  42.194 + 	/* Install the new kernel, and  Uninstall the old */
  42.195 + 	image = xchg(dest_image, image);
  42.196 + 
  42.197 +@@ -1045,7 +1070,6 @@ void crash_kexec(struct pt_regs *regs)
  42.198 + 	struct kimage *image;
  42.199 + 	int locked;
  42.200 + 
  42.201 +-
  42.202 + 	/* Take the kexec_lock here to prevent sys_kexec_load
  42.203 + 	 * running on one cpu from replacing the crash kernel
  42.204 + 	 * we are using after a panic on a different cpu.
  42.205 +@@ -1061,7 +1085,11 @@ void crash_kexec(struct pt_regs *regs)
  42.206 + 			struct pt_regs fixed_regs;
  42.207 + 			crash_setup_regs(&fixed_regs, regs);
  42.208 + 			machine_crash_shutdown(&fixed_regs);
  42.209 ++#ifdef CONFIG_XEN
  42.210 ++			xen_machine_kexec(image);
  42.211 ++#else
  42.212 + 			machine_kexec(image);
  42.213 ++#endif
  42.214 + 		}
  42.215 + 		xchg(&kexec_lock, 0);
  42.216 + 	}
  42.217 +--- 0002/kernel/sys.c
  42.218 ++++ work/kernel/sys.c
  42.219 +@@ -435,8 +435,12 @@ void kernel_kexec(void)
  42.220 + 	kernel_restart_prepare(NULL);
  42.221 + 	printk(KERN_EMERG "Starting new kernel\n");
  42.222 + 	machine_shutdown();
  42.223 ++#ifdef CONFIG_XEN
  42.224 ++	xen_machine_kexec(image);
  42.225 ++#else
  42.226 + 	machine_kexec(image);
  42.227 + #endif
  42.228 ++#endif
  42.229 + }
  42.230 + EXPORT_SYMBOL_GPL(kernel_kexec);
  42.231 + 
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch	Mon Dec 04 08:24:41 2006 -0700
    43.3 @@ -0,0 +1,169 @@
    43.4 +kexec: Move asm segment handling code to the assembly file (i386)
    43.5 +
    43.6 +This patch moves the idt, gdt, and segment handling code from machine_kexec.c
    43.7 +to relocate_kernel.S. The main reason behind this move is to avoid code 
    43.8 +duplication in the Xen hypervisor. With this patch all code required to kexec
    43.9 +is put on the control page.
   43.10 +
   43.11 +On top of that this patch also counts as a cleanup - I think it is much
   43.12 +nicer to write assembly directly in assembly files than wrap inline assembly
   43.13 +in C functions for no apparent reason.
   43.14 +
   43.15 +Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
   43.16 +---
   43.17 +
   43.18 + Applies to 2.6.19-rc1.
   43.19 +
   43.20 + machine_kexec.c   |   59 -----------------------------------------------------
   43.21 + relocate_kernel.S |   58 +++++++++++++++++++++++++++++++++++++++++++++++-----
   43.22 + 2 files changed, 53 insertions(+), 64 deletions(-)
   43.23 +
   43.24 +--- 0002/arch/i386/kernel/machine_kexec.c
   43.25 ++++ work/arch/i386/kernel/machine_kexec.c	2006-10-05 15:49:08.000000000 +0900
   43.26 +@@ -29,48 +29,6 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
   43.27 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
   43.28 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
   43.29 + 
   43.30 +-static void set_idt(void *newidt, __u16 limit)
   43.31 +-{
   43.32 +-	struct Xgt_desc_struct curidt;
   43.33 +-
   43.34 +-	/* ia32 supports unaliged loads & stores */
   43.35 +-	curidt.size    = limit;
   43.36 +-	curidt.address = (unsigned long)newidt;
   43.37 +-
   43.38 +-	load_idt(&curidt);
   43.39 +-};
   43.40 +-
   43.41 +-
   43.42 +-static void set_gdt(void *newgdt, __u16 limit)
   43.43 +-{
   43.44 +-	struct Xgt_desc_struct curgdt;
   43.45 +-
   43.46 +-	/* ia32 supports unaligned loads & stores */
   43.47 +-	curgdt.size    = limit;
   43.48 +-	curgdt.address = (unsigned long)newgdt;
   43.49 +-
   43.50 +-	load_gdt(&curgdt);
   43.51 +-};
   43.52 +-
   43.53 +-static void load_segments(void)
   43.54 +-{
   43.55 +-#define __STR(X) #X
   43.56 +-#define STR(X) __STR(X)
   43.57 +-
   43.58 +-	__asm__ __volatile__ (
   43.59 +-		"\tljmp $"STR(__KERNEL_CS)",$1f\n"
   43.60 +-		"\t1:\n"
   43.61 +-		"\tmovl $"STR(__KERNEL_DS)",%%eax\n"
   43.62 +-		"\tmovl %%eax,%%ds\n"
   43.63 +-		"\tmovl %%eax,%%es\n"
   43.64 +-		"\tmovl %%eax,%%fs\n"
   43.65 +-		"\tmovl %%eax,%%gs\n"
   43.66 +-		"\tmovl %%eax,%%ss\n"
   43.67 +-		::: "eax", "memory");
   43.68 +-#undef STR
   43.69 +-#undef __STR
   43.70 +-}
   43.71 +-
   43.72 + /*
   43.73 +  * A architecture hook called to validate the
   43.74 +  * proposed image and prepare the control pages
   43.75 +@@ -127,23 +85,6 @@ NORET_TYPE void machine_kexec(struct kim
   43.76 + 	page_list[PA_PTE_1] = __pa(kexec_pte1);
   43.77 + 	page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
   43.78 + 
   43.79 +-	/* The segment registers are funny things, they have both a
   43.80 +-	 * visible and an invisible part.  Whenever the visible part is
   43.81 +-	 * set to a specific selector, the invisible part is loaded
   43.82 +-	 * with from a table in memory.  At no other time is the
   43.83 +-	 * descriptor table in memory accessed.
   43.84 +-	 *
   43.85 +-	 * I take advantage of this here by force loading the
   43.86 +-	 * segments, before I zap the gdt with an invalid value.
   43.87 +-	 */
   43.88 +-	load_segments();
   43.89 +-	/* The gdt & idt are now invalid.
   43.90 +-	 * If you want to load them you must set up your own idt & gdt.
   43.91 +-	 */
   43.92 +-	set_gdt(phys_to_virt(0),0);
   43.93 +-	set_idt(phys_to_virt(0),0);
   43.94 +-
   43.95 +-	/* now call it */
   43.96 + 	relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
   43.97 + 			image->start, cpu_has_pae);
   43.98 + }
   43.99 +--- 0002/arch/i386/kernel/relocate_kernel.S
  43.100 ++++ work/arch/i386/kernel/relocate_kernel.S	2006-10-05 16:03:21.000000000 +0900
  43.101 +@@ -154,14 +154,45 @@ relocate_new_kernel:
  43.102 + 	movl	PTR(PA_PGD)(%ebp), %eax
  43.103 + 	movl	%eax, %cr3
  43.104 + 
  43.105 ++	/* setup idt */
  43.106 ++	movl	%edi, %eax
  43.107 ++	addl	$(idt_48 - relocate_kernel), %eax
  43.108 ++	lidtl	(%eax)
  43.109 ++
  43.110 ++	/* setup gdt */
  43.111 ++	movl	%edi, %eax
  43.112 ++	addl	$(gdt - relocate_kernel), %eax
  43.113 ++	movl	%edi, %esi
  43.114 ++	addl	$((gdt_48 - relocate_kernel) + 2), %esi
  43.115 ++	movl	%eax, (%esi)
  43.116 ++	
  43.117 ++	movl	%edi, %eax
  43.118 ++	addl	$(gdt_48 - relocate_kernel), %eax
  43.119 ++	lgdtl	(%eax)
  43.120 ++
  43.121 ++	/* setup data segment registers */
  43.122 ++	mov	$(gdt_ds - gdt), %eax
  43.123 ++	mov	%eax, %ds
  43.124 ++	mov	%eax, %es
  43.125 ++	mov	%eax, %fs
  43.126 ++	mov	%eax, %gs
  43.127 ++	mov	%eax, %ss
  43.128 ++	
  43.129 + 	/* setup a new stack at the end of the physical control page */
  43.130 + 	lea	4096(%edi), %esp
  43.131 + 
  43.132 +-	/* jump to identity mapped page */
  43.133 +-	movl    %edi, %eax
  43.134 +-	addl    $(identity_mapped - relocate_kernel), %eax
  43.135 +-	pushl   %eax
  43.136 +-	ret
  43.137 ++	/* load new code segment and jump to identity mapped page */
  43.138 ++	movl	%edi, %esi
  43.139 ++	xorl	%eax, %eax
  43.140 ++	pushl	%eax
  43.141 ++	pushl	%esi
  43.142 ++	pushl	%eax
  43.143 ++	movl	$(gdt_cs - gdt), %eax
  43.144 ++	pushl	%eax	
  43.145 ++	movl	%edi, %eax
  43.146 ++	addl	$(identity_mapped - relocate_kernel),%eax
  43.147 ++	pushl	%eax
  43.148 ++	iretl
  43.149 + 
  43.150 + identity_mapped:
  43.151 + 	/* store the start address on the stack */
  43.152 +@@ -250,3 +281,20 @@ identity_mapped:
  43.153 + 	xorl    %edi, %edi
  43.154 + 	xorl    %ebp, %ebp
  43.155 + 	ret
  43.156 ++
  43.157 ++	.align	16
  43.158 ++gdt:
  43.159 ++	.quad	0x0000000000000000	/* NULL descriptor */
  43.160 ++gdt_cs:	
  43.161 ++	.quad	0x00cf9a000000ffff	/* kernel 4GB code at 0x00000000 */
  43.162 ++gdt_ds:
  43.163 ++	.quad	0x00cf92000000ffff	/* kernel 4GB data at 0x00000000 */
  43.164 ++gdt_end:
  43.165 ++	
  43.166 ++gdt_48:
  43.167 ++	.word	gdt_end - gdt - 1	/* limit */
  43.168 ++	.long	0			/* base - filled in by code above */
  43.169 ++
  43.170 ++idt_48:
  43.171 ++	.word	0			/* limit */
  43.172 ++	.long	0			/* base */
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch	Mon Dec 04 08:24:41 2006 -0700
    44.3 @@ -0,0 +1,161 @@
    44.4 +kexec: Move asm segment handling code to the assembly file (x86_64)
    44.5 +
    44.6 +This patch moves the idt, gdt, and segment handling code from machine_kexec.c
    44.7 +to relocate_kernel.S.  The main reason behind this move is to avoid code 
    44.8 +duplication in the Xen hypervisor. With this patch all code required to kexec
    44.9 +is put on the control page.
   44.10 +
   44.11 +On top of that this patch also counts as a cleanup - I think it is much
   44.12 +nicer to write assembly directly in assembly files than wrap inline assembly
   44.13 +in C functions for no apparent reason.
   44.14 +
   44.15 +Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
   44.16 +---
   44.17 +
   44.18 + Applies to 2.6.19-rc1.
   44.19 +
   44.20 + machine_kexec.c   |   58 -----------------------------------------------------
   44.21 + relocate_kernel.S |   50 +++++++++++++++++++++++++++++++++++++++++----
   44.22 + 2 files changed, 45 insertions(+), 63 deletions(-)
   44.23 +
   44.24 +--- 0002/arch/x86_64/kernel/machine_kexec.c
   44.25 ++++ work/arch/x86_64/kernel/machine_kexec.c	2006-10-05 16:15:49.000000000 +0900
   44.26 +@@ -112,47 +112,6 @@ static int init_pgtable(struct kimage *i
   44.27 +  	return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT);
   44.28 + }
   44.29 + 
   44.30 +-static void set_idt(void *newidt, u16 limit)
   44.31 +-{
   44.32 +-	struct desc_ptr curidt;
   44.33 +-
   44.34 +-	/* x86-64 supports unaliged loads & stores */
   44.35 +-	curidt.size    = limit;
   44.36 +-	curidt.address = (unsigned long)newidt;
   44.37 +-
   44.38 +-	__asm__ __volatile__ (
   44.39 +-		"lidtq %0\n"
   44.40 +-		: : "m" (curidt)
   44.41 +-		);
   44.42 +-};
   44.43 +-
   44.44 +-
   44.45 +-static void set_gdt(void *newgdt, u16 limit)
   44.46 +-{
   44.47 +-	struct desc_ptr curgdt;
   44.48 +-
   44.49 +-	/* x86-64 supports unaligned loads & stores */
   44.50 +-	curgdt.size    = limit;
   44.51 +-	curgdt.address = (unsigned long)newgdt;
   44.52 +-
   44.53 +-	__asm__ __volatile__ (
   44.54 +-		"lgdtq %0\n"
   44.55 +-		: : "m" (curgdt)
   44.56 +-		);
   44.57 +-};
   44.58 +-
   44.59 +-static void load_segments(void)
   44.60 +-{
   44.61 +-	__asm__ __volatile__ (
   44.62 +-		"\tmovl %0,%%ds\n"
   44.63 +-		"\tmovl %0,%%es\n"
   44.64 +-		"\tmovl %0,%%ss\n"
   44.65 +-		"\tmovl %0,%%fs\n"
   44.66 +-		"\tmovl %0,%%gs\n"
   44.67 +-		: : "a" (__KERNEL_DS) : "memory"
   44.68 +-		);
   44.69 +-}
   44.70 +-
   44.71 + int machine_kexec_prepare(struct kimage *image)
   44.72 + {
   44.73 + 	unsigned long start_pgtable;
   44.74 +@@ -209,23 +168,6 @@ NORET_TYPE void machine_kexec(struct kim
   44.75 + 	page_list[PA_TABLE_PAGE] =
   44.76 + 	  (unsigned long)__pa(page_address(image->control_code_page));
   44.77 + 
   44.78 +-	/* The segment registers are funny things, they have both a
   44.79 +-	 * visible and an invisible part.  Whenever the visible part is
   44.80 +-	 * set to a specific selector, the invisible part is loaded
   44.81 +-	 * with from a table in memory.  At no other time is the
   44.82 +-	 * descriptor table in memory accessed.
   44.83 +-	 *
   44.84 +-	 * I take advantage of this here by force loading the
   44.85 +-	 * segments, before I zap the gdt with an invalid value.
   44.86 +-	 */
   44.87 +-	load_segments();
   44.88 +-	/* The gdt & idt are now invalid.
   44.89 +-	 * If you want to load them you must set up your own idt & gdt.
   44.90 +-	 */
   44.91 +-	set_gdt(phys_to_virt(0),0);
   44.92 +-	set_idt(phys_to_virt(0),0);
   44.93 +-
   44.94 +-	/* now call it */
   44.95 + 	relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
   44.96 + 			image->start);
   44.97 + }
   44.98 +--- 0002/arch/x86_64/kernel/relocate_kernel.S
   44.99 ++++ work/arch/x86_64/kernel/relocate_kernel.S	2006-10-05 16:18:07.000000000 +0900
  44.100 +@@ -159,13 +159,39 @@ relocate_new_kernel:
  44.101 + 	movq	PTR(PA_PGD)(%rsi), %r9
  44.102 + 	movq	%r9, %cr3
  44.103 + 
  44.104 ++	/* setup idt */
  44.105 ++	movq    %r8, %rax
  44.106 ++	addq    $(idt_80 - relocate_kernel), %rax
  44.107 ++	lidtq   (%rax)
  44.108 ++
  44.109 ++	/* setup gdt */
  44.110 ++	movq    %r8, %rax
  44.111 ++	addq    $(gdt - relocate_kernel), %rax
  44.112 ++	movq    %r8, %r9
  44.113 ++	addq    $((gdt_80 - relocate_kernel) + 2), %r9
  44.114 ++	movq    %rax, (%r9)
  44.115 ++
  44.116 ++	movq    %r8, %rax
  44.117 ++	addq    $(gdt_80 - relocate_kernel), %rax
  44.118 ++	lgdtq   (%rax)
  44.119 ++
  44.120 ++	/* setup data segment registers */
  44.121 ++	xorl	%eax, %eax
  44.122 ++	movl    %eax, %ds
  44.123 ++	movl    %eax, %es
  44.124 ++	movl    %eax, %fs
  44.125 ++	movl    %eax, %gs
  44.126 ++	movl    %eax, %ss
  44.127 ++	
  44.128 + 	/* setup a new stack at the end of the physical control page */
  44.129 + 	lea	4096(%r8), %rsp
  44.130 + 
  44.131 +-	/* jump to identity mapped page */
  44.132 +-	addq	$(identity_mapped - relocate_kernel), %r8
  44.133 +-	pushq	%r8
  44.134 +-	ret
  44.135 ++	/* load new code segment and jump to identity mapped page */
  44.136 ++	movq	%r8, %rax
  44.137 ++	addq    $(identity_mapped - relocate_kernel), %rax
  44.138 ++	pushq	$(gdt_cs - gdt)
  44.139 ++	pushq	%rax
  44.140 ++	lretq
  44.141 + 
  44.142 + identity_mapped:
  44.143 + 	/* store the start address on the stack */
  44.144 +@@ -272,5 +298,19 @@ identity_mapped:
  44.145 + 	xorq	%r13, %r13
  44.146 + 	xorq	%r14, %r14
  44.147 + 	xorq	%r15, %r15
  44.148 +-
  44.149 + 	ret
  44.150 ++
  44.151 ++	.align  16
  44.152 ++gdt:
  44.153 ++	.quad	0x0000000000000000	/* NULL descriptor */
  44.154 ++gdt_cs:
  44.155 ++	.quad   0x00af9a000000ffff
  44.156 ++gdt_end:
  44.157 ++
  44.158 ++gdt_80:
  44.159 ++	.word	gdt_end - gdt - 1	/* limit */
  44.160 ++	.quad	0			/* base - filled in by code above */
  44.161 ++
  44.162 ++idt_80:
  44.163 ++	.word	0			/* limit */
  44.164 ++	.quad	0			/* base */
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-xen-i386.patch	Mon Dec 04 08:24:41 2006 -0700
    45.3 @@ -0,0 +1,108 @@
    45.4 +--- 0001/arch/i386/kernel/crash.c
    45.5 ++++ work/arch/i386/kernel/crash.c
    45.6 +@@ -90,6 +90,7 @@ static void crash_save_self(struct pt_re
    45.7 + 	crash_save_this_cpu(regs, cpu);
    45.8 + }
    45.9 + 
   45.10 ++#ifndef CONFIG_XEN
   45.11 + #ifdef CONFIG_SMP
   45.12 + static atomic_t waiting_for_crash_ipi;
   45.13 + 
   45.14 +@@ -158,6 +159,7 @@ static void nmi_shootdown_cpus(void)
   45.15 + 	/* There are no cpus to shootdown */
   45.16 + }
   45.17 + #endif
   45.18 ++#endif /* CONFIG_XEN */
   45.19 + 
   45.20 + void machine_crash_shutdown(struct pt_regs *regs)
   45.21 + {
   45.22 +@@ -174,10 +176,12 @@ void machine_crash_shutdown(struct pt_re
   45.23 + 
   45.24 + 	/* Make a note of crashing cpu. Will be used in NMI callback.*/
   45.25 + 	crashing_cpu = smp_processor_id();
   45.26 ++#ifndef CONFIG_XEN
   45.27 + 	nmi_shootdown_cpus();
   45.28 + 	lapic_shutdown();
   45.29 + #if defined(CONFIG_X86_IO_APIC)
   45.30 + 	disable_IO_APIC();
   45.31 + #endif
   45.32 ++#endif /* CONFIG_XEN */
   45.33 + 	crash_save_self(regs);
   45.34 + }
   45.35 +--- 0007/arch/i386/kernel/machine_kexec.c
   45.36 ++++ work/arch/i386/kernel/machine_kexec.c
   45.37 +@@ -19,6 +19,10 @@
   45.38 + #include <asm/desc.h>
   45.39 + #include <asm/system.h>
   45.40 + 
   45.41 ++#ifdef CONFIG_XEN
   45.42 ++#include <xen/interface/kexec.h>
   45.43 ++#endif
   45.44 ++
   45.45 + #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
   45.46 + static u32 kexec_pgd[1024] PAGE_ALIGNED;
   45.47 + #ifdef CONFIG_X86_PAE
   45.48 +@@ -28,6 +32,40 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
   45.49 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
   45.50 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
   45.51 + 
   45.52 ++#ifdef CONFIG_XEN
   45.53 ++
   45.54 ++#define __ma(x) (pfn_to_mfn(__pa((x)) >> PAGE_SHIFT) << PAGE_SHIFT)
   45.55 ++
   45.56 ++#if PAGES_NR > KEXEC_XEN_NO_PAGES
   45.57 ++#error PAGES_NR is greater than KEXEC_XEN_NO_PAGES - Xen support will break
   45.58 ++#endif
   45.59 ++
   45.60 ++#if PA_CONTROL_PAGE != 0
   45.61 ++#error PA_CONTROL_PAGE is non zero - Xen support will break
   45.62 ++#endif
   45.63 ++
   45.64 ++void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
   45.65 ++{
   45.66 ++	void *control_page;
   45.67 ++
   45.68 ++	memset(xki->page_list, 0, sizeof(xki->page_list));
   45.69 ++
   45.70 ++	control_page = page_address(image->control_code_page);
   45.71 ++	memcpy(control_page, relocate_kernel, PAGE_SIZE);
   45.72 ++
   45.73 ++	xki->page_list[PA_CONTROL_PAGE] = __ma(control_page);
   45.74 ++	xki->page_list[PA_PGD] = __ma(kexec_pgd);
   45.75 ++#ifdef CONFIG_X86_PAE
   45.76 ++	xki->page_list[PA_PMD_0] = __ma(kexec_pmd0);
   45.77 ++	xki->page_list[PA_PMD_1] = __ma(kexec_pmd1);
   45.78 ++#endif
   45.79 ++	xki->page_list[PA_PTE_0] = __ma(kexec_pte0);
   45.80 ++	xki->page_list[PA_PTE_1] = __ma(kexec_pte1);
   45.81 ++
   45.82 ++}
   45.83 ++
   45.84 ++#endif /* CONFIG_XEN */
   45.85 ++
   45.86 + /*
   45.87 +  * A architecture hook called to validate the
   45.88 +  * proposed image and prepare the control pages
   45.89 +--- 0006/include/asm-i386/kexec.h
   45.90 ++++ work/include/asm-i386/kexec.h
   45.91 +@@ -98,6 +98,20 @@ relocate_kernel(unsigned long indirectio
   45.92 + 		unsigned long start_address,
   45.93 + 		unsigned int has_pae) ATTRIB_NORET;
   45.94 + 
   45.95 ++
   45.96 ++/* Under Xen we need to work with machine addresses. These macros give the
   45.97 ++ * machine address of a certain page to the generic kexec code instead of 
   45.98 ++ * the pseudo physical address which would be given by the default macros.
   45.99 ++ */
  45.100 ++
  45.101 ++#ifdef CONFIG_XEN
  45.102 ++#define KEXEC_ARCH_HAS_PAGE_MACROS
  45.103 ++#define kexec_page_to_pfn(page)  pfn_to_mfn(page_to_pfn(page))
  45.104 ++#define kexec_pfn_to_page(pfn)   pfn_to_page(mfn_to_pfn(pfn))
  45.105 ++#define kexec_virt_to_phys(addr) virt_to_machine(addr)
  45.106 ++#define kexec_phys_to_virt(addr) phys_to_virt(machine_to_phys(addr))
  45.107 ++#endif
  45.108 ++
  45.109 + #endif /* __ASSEMBLY__ */
  45.110 + 
  45.111 + #endif /* _I386_KEXEC_H */
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-xen-x86_64.patch	Mon Dec 04 08:24:41 2006 -0700
    46.3 @@ -0,0 +1,219 @@
    46.4 +--- 0001/arch/x86_64/kernel/crash.c
    46.5 ++++ work/arch/x86_64/kernel/crash.c
    46.6 +@@ -92,6 +92,7 @@ static void crash_save_self(struct pt_re
    46.7 + 	crash_save_this_cpu(regs, cpu);
    46.8 + }
    46.9 + 
   46.10 ++#ifndef CONFIG_XEN
   46.11 + #ifdef CONFIG_SMP
   46.12 + static atomic_t waiting_for_crash_ipi;
   46.13 + 
   46.14 +@@ -156,6 +157,7 @@ static void nmi_shootdown_cpus(void)
   46.15 + 	/* There are no cpus to shootdown */
   46.16 + }
   46.17 + #endif
   46.18 ++#endif /* CONFIG_XEN */
   46.19 + 
   46.20 + void machine_crash_shutdown(struct pt_regs *regs)
   46.21 + {
   46.22 +@@ -173,6 +175,8 @@ void machine_crash_shutdown(struct pt_re
   46.23 + 
   46.24 + 	/* Make a note of crashing cpu. Will be used in NMI callback.*/
   46.25 + 	crashing_cpu = smp_processor_id();
   46.26 ++
   46.27 ++#ifndef CONFIG_XEN
   46.28 + 	nmi_shootdown_cpus();
   46.29 + 
   46.30 + 	if(cpu_has_apic)
   46.31 +@@ -181,6 +185,6 @@ void machine_crash_shutdown(struct pt_re
   46.32 + #if defined(CONFIG_X86_IO_APIC)
   46.33 + 	disable_IO_APIC();
   46.34 + #endif
   46.35 +-
   46.36 ++#endif /* CONFIG_XEN */
   46.37 + 	crash_save_self(regs);
   46.38 + }
   46.39 +--- 0010/arch/x86_64/kernel/machine_kexec.c
   46.40 ++++ work/arch/x86_64/kernel/machine_kexec.c
   46.41 +@@ -24,6 +24,104 @@ static u64 kexec_pud1[512] PAGE_ALIGNED;
   46.42 + static u64 kexec_pmd1[512] PAGE_ALIGNED;
   46.43 + static u64 kexec_pte1[512] PAGE_ALIGNED;
   46.44 + 
   46.45 ++#ifdef CONFIG_XEN
   46.46 ++
   46.47 ++/* In the case of Xen, override hypervisor functions to be able to create
   46.48 ++ * a regular identity mapping page table...
   46.49 ++ */
   46.50 ++
   46.51 ++#include <xen/interface/kexec.h>
   46.52 ++#include <xen/interface/memory.h>
   46.53 ++
   46.54 ++#define x__pmd(x) ((pmd_t) { (x) } )
   46.55 ++#define x__pud(x) ((pud_t) { (x) } )
   46.56 ++#define x__pgd(x) ((pgd_t) { (x) } )
   46.57 ++
   46.58 ++#define x_pmd_val(x)   ((x).pmd)
   46.59 ++#define x_pud_val(x)   ((x).pud)
   46.60 ++#define x_pgd_val(x)   ((x).pgd)
   46.61 ++
   46.62 ++static inline void x_set_pmd(pmd_t *dst, pmd_t val)
   46.63 ++{
   46.64 ++	x_pmd_val(*dst) = x_pmd_val(val);
   46.65 ++}
   46.66 ++
   46.67 ++static inline void x_set_pud(pud_t *dst, pud_t val)
   46.68 ++{
   46.69 ++	x_pud_val(*dst) = phys_to_machine(x_pud_val(val));
   46.70 ++}
   46.71 ++
   46.72 ++static inline void x_pud_clear (pud_t *pud)
   46.73 ++{
   46.74 ++	x_pud_val(*pud) = 0;
   46.75 ++}
   46.76 ++
   46.77 ++static inline void x_set_pgd(pgd_t *dst, pgd_t val)
   46.78 ++{
   46.79 ++	x_pgd_val(*dst) = phys_to_machine(x_pgd_val(val));
   46.80 ++}
   46.81 ++
   46.82 ++static inline void x_pgd_clear (pgd_t * pgd)
   46.83 ++{
   46.84 ++	x_pgd_val(*pgd) = 0;
   46.85 ++}
   46.86 ++
   46.87 ++#define X__PAGE_KERNEL_LARGE_EXEC \
   46.88 ++         _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_PSE
   46.89 ++#define X_KERNPG_TABLE _PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY
   46.90 ++
   46.91 ++#define __ma(x) (pfn_to_mfn(__pa((x)) >> PAGE_SHIFT) << PAGE_SHIFT)
   46.92 ++
   46.93 ++#if PAGES_NR > KEXEC_XEN_NO_PAGES
   46.94 ++#error PAGES_NR is greater than KEXEC_XEN_NO_PAGES - Xen support will break
   46.95 ++#endif
   46.96 ++
   46.97 ++#if PA_CONTROL_PAGE != 0
   46.98 ++#error PA_CONTROL_PAGE is non zero - Xen support will break
   46.99 ++#endif
  46.100 ++
  46.101 ++void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
  46.102 ++{
  46.103 ++	void *control_page;
  46.104 ++	void *table_page;
  46.105 ++
  46.106 ++	memset(xki->page_list, 0, sizeof(xki->page_list));
  46.107 ++
  46.108 ++	control_page = page_address(image->control_code_page) + PAGE_SIZE;
  46.109 ++	memcpy(control_page, relocate_kernel, PAGE_SIZE);
  46.110 ++
  46.111 ++	table_page = page_address(image->control_code_page);
  46.112 ++
  46.113 ++	xki->page_list[PA_CONTROL_PAGE] = __ma(control_page);
  46.114 ++	xki->page_list[PA_TABLE_PAGE] = __ma(table_page);
  46.115 ++
  46.116 ++	xki->page_list[PA_PGD] = __ma(kexec_pgd);
  46.117 ++	xki->page_list[PA_PUD_0] = __ma(kexec_pud0);
  46.118 ++	xki->page_list[PA_PUD_1] = __ma(kexec_pud1);
  46.119 ++	xki->page_list[PA_PMD_0] = __ma(kexec_pmd0);
  46.120 ++	xki->page_list[PA_PMD_1] = __ma(kexec_pmd1);
  46.121 ++	xki->page_list[PA_PTE_0] = __ma(kexec_pte0);
  46.122 ++	xki->page_list[PA_PTE_1] = __ma(kexec_pte1);
  46.123 ++}
  46.124 ++
  46.125 ++#else /* CONFIG_XEN */
  46.126 ++
  46.127 ++#define x__pmd(x) __pmd(x)
  46.128 ++#define x__pud(x) __pud(x)
  46.129 ++#define x__pgd(x) __pgd(x)
  46.130 ++
  46.131 ++#define x_set_pmd(x, y) set_pmd(x, y)
  46.132 ++#define x_set_pud(x, y) set_pud(x, y)
  46.133 ++#define x_set_pgd(x, y) set_pgd(x, y)
  46.134 ++
  46.135 ++#define x_pud_clear(x) pud_clear(x)
  46.136 ++#define x_pgd_clear(x) pgd_clear(x)
  46.137 ++
  46.138 ++#define X__PAGE_KERNEL_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC
  46.139 ++#define X_KERNPG_TABLE _KERNPG_TABLE
  46.140 ++
  46.141 ++#endif /* CONFIG_XEN */
  46.142 ++
  46.143 + static void init_level2_page(pmd_t *level2p, unsigned long addr)
  46.144 + {
  46.145 + 	unsigned long end_addr;
  46.146 +@@ -31,7 +129,7 @@ static void init_level2_page(pmd_t *leve
  46.147 + 	addr &= PAGE_MASK;
  46.148 + 	end_addr = addr + PUD_SIZE;
  46.149 + 	while (addr < end_addr) {
  46.150 +-		set_pmd(level2p++, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC));
  46.151 ++		x_set_pmd(level2p++, x__pmd(addr | X__PAGE_KERNEL_LARGE_EXEC));
  46.152 + 		addr += PMD_SIZE;
  46.153 + 	}
  46.154 + }
  46.155 +@@ -56,12 +154,12 @@ static int init_level3_page(struct kimag
  46.156 + 		}
  46.157 + 		level2p = (pmd_t *)page_address(page);
  46.158 + 		init_level2_page(level2p, addr);
  46.159 +-		set_pud(level3p++, __pud(__pa(level2p) | _KERNPG_TABLE));
  46.160 ++		x_set_pud(level3p++, x__pud(__pa(level2p) | X_KERNPG_TABLE));
  46.161 + 		addr += PUD_SIZE;
  46.162 + 	}
  46.163 + 	/* clear the unused entries */
  46.164 + 	while (addr < end_addr) {
  46.165 +-		pud_clear(level3p++);
  46.166 ++		x_pud_clear(level3p++);
  46.167 + 		addr += PUD_SIZE;
  46.168 + 	}
  46.169 + out:
  46.170 +@@ -92,12 +190,12 @@ static int init_level4_page(struct kimag
  46.171 + 		if (result) {
  46.172 + 			goto out;
  46.173 + 		}
  46.174 +-		set_pgd(level4p++, __pgd(__pa(level3p) | _KERNPG_TABLE));
  46.175 ++		x_set_pgd(level4p++, x__pgd(__pa(level3p) | X_KERNPG_TABLE));
  46.176 + 		addr += PGDIR_SIZE;
  46.177 + 	}
  46.178 + 	/* clear the unused entries */
  46.179 + 	while (addr < end_addr) {
  46.180 +-		pgd_clear(level4p++);
  46.181 ++		x_pgd_clear(level4p++);
  46.182 + 		addr += PGDIR_SIZE;
  46.183 + 	}
  46.184 + out:
  46.185 +@@ -108,8 +206,14 @@ out:
  46.186 + static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
  46.187 + {
  46.188 + 	pgd_t *level4p;
  46.189 ++	unsigned long x_end_pfn = end_pfn;
  46.190 ++
  46.191 ++#ifdef CONFIG_XEN
  46.192 ++	x_end_pfn = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
  46.193 ++#endif
  46.194 ++
  46.195 + 	level4p = (pgd_t *)__va(start_pgtable);
  46.196 +- 	return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT);
  46.197 ++ 	return init_level4_page(image, level4p, 0, x_end_pfn << PAGE_SHIFT);
  46.198 + }
  46.199 + 
  46.200 + int machine_kexec_prepare(struct kimage *image)
  46.201 +--- 0009/include/asm-x86_64/kexec.h
  46.202 ++++ work/include/asm-x86_64/kexec.h
  46.203 +@@ -91,6 +91,19 @@ relocate_kernel(unsigned long indirectio
  46.204 + 		unsigned long page_list,
  46.205 + 		unsigned long start_address) ATTRIB_NORET;
  46.206 + 
  46.207 ++/* Under Xen we need to work with machine addresses. These macros give the
  46.208 ++ * machine address of a certain page to the generic kexec code instead of 
  46.209 ++ * the pseudo physical address which would be given by the default macros.
  46.210 ++ */
  46.211 ++
  46.212 ++#ifdef CONFIG_XEN
  46.213 ++#define KEXEC_ARCH_HAS_PAGE_MACROS
  46.214 ++#define kexec_page_to_pfn(page)  pfn_to_mfn(page_to_pfn(page))
  46.215 ++#define kexec_pfn_to_page(pfn)   pfn_to_page(mfn_to_pfn(pfn))
  46.216 ++#define kexec_virt_to_phys(addr) virt_to_machine(addr)
  46.217 ++#define kexec_phys_to_virt(addr) phys_to_virt(machine_to_phys(addr))
  46.218 ++#endif
  46.219 ++
  46.220 + #endif /* __ASSEMBLY__ */
  46.221 + 
  46.222 + #endif /* _X86_64_KEXEC_H */
    47.1 --- a/patches/linux-2.6.16.33/series	Sat Dec 02 15:19:50 2006 -0700
    47.2 +++ b/patches/linux-2.6.16.33/series	Mon Dec 04 08:24:41 2006 -0700
    47.3 @@ -1,3 +1,12 @@
    47.4 +kexec-generic.patch
    47.5 +git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
    47.6 +git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
    47.7 +git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch
    47.8 +linux-2.6.19-rc1-kexec-move_segment_code-i386.patch
    47.9 +linux-2.6.19-rc1-kexec-xen-i386.patch
   47.10 +git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch
   47.11 +linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch
   47.12 +linux-2.6.19-rc1-kexec-xen-x86_64.patch
   47.13  blktap-aio-16_03_06.patch
   47.14  device_bind.patch
   47.15  fix-hz-suspend.patch
   47.16 @@ -22,6 +31,7 @@ xen-hotplug.patch
   47.17  xenoprof-generic.patch
   47.18  x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
   47.19  x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
   47.20 +git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch
   47.21  x86-elfnote-as-preprocessor-macro.patch
   47.22  vsnprintf.patch
   47.23  kasprintf.patch
    48.1 --- a/tools/Makefile	Sat Dec 02 15:19:50 2006 -0700
    48.2 +++ b/tools/Makefile	Mon Dec 04 08:24:41 2006 -0700
    48.3 @@ -19,6 +19,7 @@ SUBDIRS-y += xenstat
    48.4  SUBDIRS-y += libaio
    48.5  SUBDIRS-y += blktap
    48.6  SUBDIRS-y += libfsimage
    48.7 +SUBDIRS-$(XENFB_TOOLS) += xenfb
    48.8  SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
    48.9  
   48.10  # These don't cross-compile
    49.1 --- a/tools/blktap/drivers/block-aio.c	Sat Dec 02 15:19:50 2006 -0700
    49.2 +++ b/tools/blktap/drivers/block-aio.c	Mon Dec 04 08:24:41 2006 -0700
    49.3 @@ -311,12 +311,8 @@ int tdaio_do_callbacks(struct td_state *
    49.4  		struct pending_aio *pio;
    49.5  		
    49.6  		pio = &prv->pending_aio[(long)io->data];
    49.7 -		
    49.8 -		if (ep->res != io->u.c.nbytes) {
    49.9 -			/* TODO: handle this case better. */
   49.10 -			DPRINTF("AIO did less than I asked it to. \n");
   49.11 -		}
   49.12 -		rsp += pio->cb(s, ep->res2, pio->id, pio->private);
   49.13 +		rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1,
   49.14 +			       pio->id, pio->private);
   49.15  
   49.16  		prv->iocb_free[prv->iocb_free_count++] = io;
   49.17  	}
    50.1 --- a/tools/blktap/drivers/block-qcow.c	Sat Dec 02 15:19:50 2006 -0700
    50.2 +++ b/tools/blktap/drivers/block-qcow.c	Mon Dec 04 08:24:41 2006 -0700
    50.3 @@ -1145,13 +1145,6 @@ int tdqcow_do_callbacks(struct td_state 
    50.4  
    50.5                  pio = &prv->pending_aio[(long)io->data];
    50.6  
    50.7 -                if (ep->res != io->u.c.nbytes) {
    50.8 -                        /* TODO: handle this case better. */
    50.9 -			ptr = (int *)&ep->res;
   50.10 -                        DPRINTF("AIO did less than I asked it to "
   50.11 -				"[%lu,%lu,%d]\n", 
   50.12 -				ep->res, io->u.c.nbytes, *ptr);
   50.13 -                }
   50.14  		aio_unlock(prv, pio->sector);
   50.15  		if (pio->id >= 0) {
   50.16  			if (prv->crypt_method)
   50.17 @@ -1162,7 +1155,7 @@ int tdqcow_do_callbacks(struct td_state 
   50.18  						&prv->aes_decrypt_key);
   50.19  			prv->nr_reqs[pio->qcow_idx]--;
   50.20  			if (prv->nr_reqs[pio->qcow_idx] == 0) 
   50.21 -				rsp += pio->cb(s, ep->res2, pio->id, 
   50.22 +			        rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1, pio->id, 
   50.23  					       pio->private);
   50.24  		} else if (pio->id == -2) free(pio->buf);
   50.25  
    51.1 --- a/tools/blktap/drivers/tapdisk.c	Sat Dec 02 15:19:50 2006 -0700
    51.2 +++ b/tools/blktap/drivers/tapdisk.c	Mon Dec 04 08:24:41 2006 -0700
    51.3 @@ -424,8 +424,7 @@ int send_responses(struct td_state *s, i
    51.4  	}
    51.5  	
    51.6  	if (res != 0) {
    51.7 -		DPRINTF("*** request error %d! \n", res);
    51.8 -		return 0;
    51.9 +	        blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
   51.10  	}
   51.11  
   51.12  	blkif->pending_list[idx].count--;
    52.1 --- a/tools/check/Makefile	Sat Dec 02 15:19:50 2006 -0700
    52.2 +++ b/tools/check/Makefile	Mon Dec 04 08:24:41 2006 -0700
    52.3 @@ -1,3 +1,5 @@
    52.4 +XEN_ROOT = ../..
    52.5 +include $(XEN_ROOT)/tools/Rules.mk
    52.6  
    52.7  .PHONY: all
    52.8  all: build
    52.9 @@ -5,7 +7,7 @@ all: build
   52.10  # Check this machine is OK for building on.
   52.11  .PHONY: build
   52.12  build:
   52.13 -	./chk build
   52.14 +	XENFB_TOOLS=$(XENFB_TOOLS) ./chk build
   52.15  
   52.16  # Check this machine is OK for installing on.
   52.17  # DO NOT use this check from 'make install' in the parent
   52.18 @@ -13,7 +15,7 @@ build:
   52.19  # copy rather than actually installing.
   52.20  .PHONY: install
   52.21  install:
   52.22 -	./chk install
   52.23 +	XENFB_TOOLS=$(XENFB_TOOLS) ./chk install
   52.24  
   52.25  .PHONY: clean
   52.26  clean:
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/tools/check/check_libvncserver	Mon Dec 04 08:24:41 2006 -0700
    53.3 @@ -0,0 +1,27 @@
    53.4 +#!/bin/sh
    53.5 +# CHECK-BUILD CHECK-INSTALL
    53.6 +
    53.7 +if [ ! "$XENFB_TOOLS" = "y" ]
    53.8 +then
    53.9 +    echo -n "unused, "
   53.10 +    exit 0
   53.11 +fi
   53.12 +
   53.13 +RC=0
   53.14 +
   53.15 +LIBVNCSERVER_CONFIG="$(which libvncserver-config)"
   53.16 +
   53.17 +if test -z ${LIBVNCSERVER_CONFIG}; then 
   53.18 +    RC=1
   53.19 +else
   53.20 +    ${LIBVNCSERVER_CONFIG} --libs 2>&1 > /dev/null
   53.21 +    RC=$?
   53.22 +fi
   53.23 +
   53.24 +if test $RC -ne 0; then
   53.25 +    echo "FAILED"
   53.26 +	echo " *** libvncserver-config is missing. "
   53.27 +    echo " *** Please install libvncserver."
   53.28 +fi
   53.29 +
   53.30 +exit $RC
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/tools/check/check_sdl	Mon Dec 04 08:24:41 2006 -0700
    54.3 @@ -0,0 +1,27 @@
    54.4 +#!/bin/sh
    54.5 +# CHECK-BUILD CHECK-INSTALL
    54.6 +
    54.7 +if [ ! "$XENFB_TOOLS" = "y" ]
    54.8 +then
    54.9 +    echo -n "unused, "
   54.10 +    exit 0
   54.11 +fi
   54.12 +
   54.13 +RC=0
   54.14 +
   54.15 +SDL_CONFIG="$(which sdl-config)"
   54.16 +
   54.17 +if test -z ${SDL_CONFIG}; then 
   54.18 +    RC=1
   54.19 +else
   54.20 +    ${SDL_CONFIG} --libs 2>&1 > /dev/null
   54.21 +    RC=$?
   54.22 +fi
   54.23 +
   54.24 +if test $RC -ne 0; then
   54.25 +    echo "FAILED"
   54.26 +	echo " *** sdl-config is missing. "
   54.27 +    echo " *** Please install libsdl-dev or sdl."
   54.28 +fi
   54.29 +
   54.30 +exit $RC
    55.1 --- a/tools/firmware/vmxassist/setup.c	Sat Dec 02 15:19:50 2006 -0700
    55.2 +++ b/tools/firmware/vmxassist/setup.c	Mon Dec 04 08:24:41 2006 -0700
    55.3 @@ -66,7 +66,7 @@ struct vmx_assist_context newctx;
    55.4  unsigned long memory_size;
    55.5  int initialize_real_mode;
    55.6  
    55.7 -extern char stack[], stack_top[];
    55.8 +extern char stack_top[];
    55.9  extern unsigned trap_handlers[];
   55.10  
   55.11  void
   55.12 @@ -201,7 +201,7 @@ void
   55.13  enter_real_mode(struct regs *regs)
   55.14  {
   55.15  	/* mask off TSS busy bit */
   55.16 -        gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL;
   55.17 +	gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL;
   55.18  
   55.19  	/* start 8086 emulation of BIOS */
   55.20  	if (initialize_real_mode) {
   55.21 @@ -219,8 +219,10 @@ enter_real_mode(struct regs *regs)
   55.22  			regs->cs = booting_vector << 8; /* AP entry point */
   55.23  			regs->eip = 0;
   55.24  		}
   55.25 -		regs->uesp = 0;
   55.26 -		regs->uss = 0;
   55.27 +
   55.28 +		regs->uesp = regs->uss = 0;
   55.29 +		regs->eax = regs->ecx = regs->edx = regs->ebx = 0;
   55.30 +		regs->esp = regs->ebp = regs->esi = regs->edi = 0;
   55.31  
   55.32  		/* intercept accesses to the PIC */
   55.33  		setiomap(PIC_MASTER+PIC_CMD);
   55.34 @@ -236,14 +238,12 @@ enter_real_mode(struct regs *regs)
   55.35  
   55.36  		/* this should get us into 16-bit mode */
   55.37  		return;
   55.38 -	} else {
   55.39 -		/* go from protected to real mode */
   55.40 -		regs->eflags |= EFLAGS_VM;
   55.41 +	}
   55.42  
   55.43 -		set_mode(regs, VM86_PROTECTED_TO_REAL);
   55.44 -
   55.45 -		emulate(regs);
   55.46 -	}
   55.47 +	/* go from protected to real mode */
   55.48 +	regs->eflags |= EFLAGS_VM;
   55.49 +	set_mode(regs, VM86_PROTECTED_TO_REAL);
   55.50 +	emulate(regs);
   55.51  }
   55.52  
   55.53  /*
    56.1 --- a/tools/firmware/vmxassist/trap.S	Sat Dec 02 15:19:50 2006 -0700
    56.2 +++ b/tools/firmware/vmxassist/trap.S	Mon Dec 04 08:24:41 2006 -0700
    56.3 @@ -100,10 +100,6 @@ trap_handlers:
    56.4  	.code32
    56.5  	.align	16
    56.6  common_trap:				/* common trap handler */
    56.7 -	pushl	%gs
    56.8 -	pushl	%fs
    56.9 -	pushl	%ds
   56.10 -	pushl	%es
   56.11  	pushal
   56.12  
   56.13  	movl	$(DATA_SELECTOR), %eax	/* make sure these are sane */
   56.14 @@ -114,17 +110,13 @@ common_trap:				/* common trap handler *
   56.15  	movl	%esp, %ebp
   56.16  
   56.17  	pushl	%ebp
   56.18 -	pushl	52(%ebp)
   56.19 -	pushl	48(%ebp)
   56.20 +	pushl	36(%ebp)
   56.21 +	pushl	32(%ebp)
   56.22  	call	trap			/* trap(trapno, errno, regs) */
   56.23  	addl	$12, %esp
   56.24  
   56.25  trap_return:
   56.26  	popal
   56.27 -	popl	%es
   56.28 -	popl	%ds
   56.29 -	popl	%fs
   56.30 -	popl	%gs
   56.31  	addl	$8, %esp		/* skip trapno, errno */
   56.32  	iret
   56.33  	/* NOT REACHED */
   56.34 @@ -152,10 +144,6 @@ switch_to_real_mode:
   56.35  	pushl	oldctx+VMX_ASSIST_CTX_EIP
   56.36  	pushl	$-1			/* trapno, errno */
   56.37  	pushl	$-1
   56.38 -	pushl	%gs
   56.39 -	pushl	%fs
   56.40 -	pushl	%ds
   56.41 -	pushl	%es
   56.42  	pushal
   56.43  
   56.44  	movl	%esp, %ebp
    57.1 --- a/tools/firmware/vmxassist/util.c	Sat Dec 02 15:19:50 2006 -0700
    57.2 +++ b/tools/firmware/vmxassist/util.c	Mon Dec 04 08:24:41 2006 -0700
    57.3 @@ -62,17 +62,15 @@ dump_regs(struct regs *regs)
    57.4  		regs->eax, regs->ecx, regs->edx, regs->ebx);
    57.5  	printf("esp    %8x ebp    %8x esi    %8x edi    %8x\n",
    57.6  		regs->esp, regs->ebp, regs->esi, regs->edi);
    57.7 -	printf("es     %8x ds     %8x fs     %8x gs     %8x\n",
    57.8 -		regs->es, regs->ds, regs->fs, regs->gs);
    57.9  	printf("trapno %8x errno  %8x\n", regs->trapno, regs->errno);
   57.10  	printf("eip    %8x cs     %8x eflags %8x\n",
   57.11  		regs->eip, regs->cs, regs->eflags);
   57.12 -	printf("uesp   %8x uss    %8x \n",
   57.13 +	printf("uesp   %8x uss    %8x\n",
   57.14  		regs->uesp, regs->uss);
   57.15  	printf("ves    %8x vds    %8x vfs    %8x vgs    %8x\n",
   57.16  		regs->ves, regs->vds, regs->vfs, regs->vgs);
   57.17  
   57.18 -	printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n",
   57.19 +	printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n\n",
   57.20  		(long)oldctx.cr0, get_cr2(),
   57.21  		(long)oldctx.cr3, (long)oldctx.cr4);
   57.22  }
    58.1 --- a/tools/firmware/vmxassist/vm86.c	Sat Dec 02 15:19:50 2006 -0700
    58.2 +++ b/tools/firmware/vmxassist/vm86.c	Mon Dec 04 08:24:41 2006 -0700
    58.3 @@ -376,9 +376,9 @@ segment(unsigned prefix, struct regs *re
    58.4  	if (prefix & SEG_SS)
    58.5  		seg = regs->uss;
    58.6  	if (prefix & SEG_FS)
    58.7 -		seg = regs->fs;
    58.8 +		seg = regs->vfs;
    58.9  	if (prefix & SEG_GS)
   58.10 -		seg = regs->gs;
   58.11 +		seg = regs->vgs;
   58.12  	return seg;
   58.13  }
   58.14  
   58.15 @@ -934,6 +934,8 @@ load_or_clear_seg(unsigned long sel, uin
   58.16  static void
   58.17  protected_mode(struct regs *regs)
   58.18  {
   58.19 +	extern char stack_top[];
   58.20 +
   58.21  	regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM);
   58.22  
   58.23  	oldctx.eip = regs->eip;
   58.24 @@ -958,12 +960,10 @@ protected_mode(struct regs *regs)
   58.25  			  &oldctx.gs_limit, &oldctx.gs_arbytes);
   58.26  
   58.27  	/* initialize jump environment to warp back to protected mode */
   58.28 +	regs->uss = DATA_SELECTOR;
   58.29 +	regs->uesp = stack_top;
   58.30  	regs->cs = CODE_SELECTOR;
   58.31 -	regs->ds = DATA_SELECTOR;
   58.32 -	regs->es = DATA_SELECTOR;
   58.33 -	regs->fs = DATA_SELECTOR;
   58.34 -	regs->gs = DATA_SELECTOR;
   58.35 -	regs->eip = (unsigned) &switch_to_protected_mode;
   58.36 +	regs->eip = (unsigned) switch_to_protected_mode;
   58.37  
   58.38  	/* this should get us into 32-bit mode */
   58.39  }
   58.40 @@ -975,10 +975,6 @@ static void
   58.41  real_mode(struct regs *regs)
   58.42  {
   58.43  	regs->eflags |= EFLAGS_VM | 0x02;
   58.44 -	regs->ds = DATA_SELECTOR;
   58.45 -	regs->es = DATA_SELECTOR;
   58.46 -	regs->fs = DATA_SELECTOR;
   58.47 -	regs->gs = DATA_SELECTOR;
   58.48  
   58.49  	/*
   58.50  	 * When we transition from protected to real-mode and we
   58.51 @@ -1070,9 +1066,6 @@ set_mode(struct regs *regs, enum vm86_mo
   58.52  	case VM86_PROTECTED:
   58.53  		if (mode == VM86_REAL_TO_PROTECTED) {
   58.54  			protected_mode(regs);
   58.55 -//			printf("<VM86_PROTECTED>\n");
   58.56 -			mode = newmode;
   58.57 -			return;
   58.58  		} else
   58.59  			panic("unexpected protected mode transition");
   58.60  		break;
    59.1 --- a/tools/firmware/vmxassist/vm86.h	Sat Dec 02 15:19:50 2006 -0700
    59.2 +++ b/tools/firmware/vmxassist/vm86.h	Mon Dec 04 08:24:41 2006 -0700
    59.3 @@ -34,7 +34,6 @@
    59.4  
    59.5  struct regs {
    59.6  	unsigned	edi, esi, ebp, esp, ebx, edx, ecx, eax;
    59.7 -	unsigned	es, ds, fs, gs;
    59.8  	unsigned	trapno, errno;
    59.9  	unsigned	eip, cs, eflags, uesp, uss;
   59.10  	unsigned	ves, vds, vfs, vgs;
   59.11 @@ -55,7 +54,6 @@ enum vm86_mode {
   59.12  
   59.13  extern enum vm86_mode prevmode, mode;
   59.14  extern struct vmx_assist_context oldctx;
   59.15 -extern struct vmx_assist_context newctx;
   59.16  
   59.17  extern void emulate(struct regs *);
   59.18  extern void dump_regs(struct regs *);
    60.1 --- a/tools/ioemu/hw/pci.c	Sat Dec 02 15:19:50 2006 -0700
    60.2 +++ b/tools/ioemu/hw/pci.c	Mon Dec 04 08:24:41 2006 -0700
    60.3 @@ -221,23 +221,16 @@ uint32_t pci_default_read_config(PCIDevi
    60.4                                   uint32_t address, int len)
    60.5  {
    60.6      uint32_t val;
    60.7 -
    60.8      switch(len) {
    60.9 +    case 1:
   60.10 +        val = d->config[address];
   60.11 +        break;
   60.12 +    case 2:
   60.13 +        val = le16_to_cpu(*(uint16_t *)(d->config + address));
   60.14 +        break;
   60.15      default:
   60.16      case 4:
   60.17 -	if (address <= 0xfc) {
   60.18 -	    val = le32_to_cpu(*(uint32_t *)(d->config + address));
   60.19 -	    break;
   60.20 -	}
   60.21 -	/* fall through */
   60.22 -    case 2:
   60.23 -        if (address <= 0xfe) {
   60.24 -	    val = le16_to_cpu(*(uint16_t *)(d->config + address));
   60.25 -	    break;
   60.26 -	}
   60.27 -	/* fall through */
   60.28 -    case 1:
   60.29 -        val = d->config[address];
   60.30 +        val = le32_to_cpu(*(uint32_t *)(d->config + address));
   60.31          break;
   60.32      }
   60.33      return val;
   60.34 @@ -340,8 +333,7 @@ void pci_default_write_config(PCIDevice 
   60.35  
   60.36              d->config[addr] = val;
   60.37          }
   60.38 -        if (++addr > 0xff)
   60.39 -        	break;
   60.40 +        addr++;
   60.41          val >>= 8;
   60.42      }
   60.43  
    61.1 --- a/tools/ioemu/hw/usb-uhci.c	Sat Dec 02 15:19:50 2006 -0700
    61.2 +++ b/tools/ioemu/hw/usb-uhci.c	Mon Dec 04 08:24:41 2006 -0700
    61.3 @@ -421,7 +421,7 @@ static int uhci_broadcast_packet(UHCISta
    61.4  static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
    61.5  {
    61.6      uint8_t pid;
    61.7 -    uint8_t buf[1280];
    61.8 +    uint8_t buf[2048];
    61.9      int len, max_len, err, ret;
   61.10  
   61.11      if (td->ctrl & TD_CTRL_IOC) {
    62.1 --- a/tools/ioemu/vl.h	Sat Dec 02 15:19:50 2006 -0700
    62.2 +++ b/tools/ioemu/vl.h	Mon Dec 04 08:24:41 2006 -0700
    62.3 @@ -650,8 +650,11 @@ typedef struct PCIIORegion {
    62.4  #define PCI_MAX_LAT		0x3f	/* 8 bits */
    62.5  
    62.6  struct PCIDevice {
    62.7 -    /* PCI config space */
    62.8 -    uint8_t config[256];
    62.9 +    /*
   62.10 +     * PCI config space. The 4 extra bytes are a safety buffer for guest
   62.11 +     * word/dword writes that can extend past byte 0xff.
   62.12 +     */
   62.13 +    uint8_t config[256+4];
   62.14  
   62.15      /* the following fields are read only */
   62.16      PCIBus *bus;
    63.1 --- a/tools/ioemu/vnc.c	Sat Dec 02 15:19:50 2006 -0700
    63.2 +++ b/tools/ioemu/vnc.c	Mon Dec 04 08:24:41 2006 -0700
    63.3 @@ -114,6 +114,7 @@ struct VncState
    63.4      int visible_h;
    63.5  
    63.6      int ctl_keys;               /* Ctrl+Alt starts calibration */
    63.7 +    int shift_keys;             /* Shift / CapsLock keys */
    63.8  };
    63.9  
   63.10  #define DIRTY_PIXEL_BITS 64
   63.11 @@ -870,9 +871,12 @@ static void do_key_event(VncState *vs, i
   63.12      } else if (down) {
   63.13  	int qemu_keysym = 0;
   63.14  
   63.15 -	if (sym <= 128) /* normal ascii */
   63.16 +	if (sym <= 128) { /* normal ascii */
   63.17 +	    int shifted = vs->shift_keys == 1 || vs->shift_keys == 2;
   63.18  	    qemu_keysym = sym;
   63.19 -	else {
   63.20 +	    if (sym >= 'a' && sym <= 'z' && shifted)
   63.21 +	        qemu_keysym -= 'a' - 'A';
   63.22 +	} else {
   63.23  	    switch (sym) {
   63.24  	    case XK_Up: qemu_keysym = QEMU_KEY_UP; break;
   63.25  	    case XK_Down: qemu_keysym = QEMU_KEY_DOWN; break;
   63.26 @@ -903,6 +907,10 @@ static void do_key_event(VncState *vs, i
   63.27  	    vs->ctl_keys |= 2;
   63.28  	    break;
   63.29  
   63.30 +	case XK_Shift_L:
   63.31 +	    vs->shift_keys |= 1;
   63.32 +	    break;
   63.33 +
   63.34  	default:
   63.35  	    break;
   63.36  	}
   63.37 @@ -916,6 +924,14 @@ static void do_key_event(VncState *vs, i
   63.38  	    vs->ctl_keys &= ~2;
   63.39  	    break;
   63.40  
   63.41 +	case XK_Shift_L:
   63.42 +	    vs->shift_keys &= ~1;
   63.43 +	    break;
   63.44 +
   63.45 +	case XK_Caps_Lock:
   63.46 +	    vs->shift_keys ^= 2;
   63.47 +	    break;
   63.48 +
   63.49  	case XK_1 ... XK_9:
   63.50  	    if ((vs->ctl_keys & 3) != 3)
   63.51  		break;
    64.1 --- a/tools/libxc/xc_linux.c	Sat Dec 02 15:19:50 2006 -0700
    64.2 +++ b/tools/libxc/xc_linux.c	Mon Dec 04 08:24:41 2006 -0700
    64.3 @@ -250,6 +250,15 @@ int xc_evtchn_notify(int xce_handle, evt
    64.4      return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, &notify);
    64.5  }
    64.6  
    64.7 +evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
    64.8 +{
    64.9 +    struct ioctl_evtchn_bind_unbound_port bind;
   64.10 +
   64.11 +    bind.remote_domain = domid;
   64.12 +
   64.13 +    return ioctl(xce_handle, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
   64.14 +}
   64.15 +
   64.16  evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
   64.17      evtchn_port_t remote_port)
   64.18  {
    65.1 --- a/tools/libxc/xc_solaris.c	Sat Dec 02 15:19:50 2006 -0700
    65.2 +++ b/tools/libxc/xc_solaris.c	Mon Dec 04 08:24:41 2006 -0700
    65.3 @@ -165,6 +165,15 @@ int xc_evtchn_notify(int xce_handle, evt
    65.4      return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, &notify);
    65.5  }
    65.6  
    65.7 +evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
    65.8 +{
    65.9 +    struct ioctl_evtchn_bind_unbound_port bind;
   65.10 +
   65.11 +    bind.remote_domain = domid;
   65.12 +
   65.13 +    return ioctl(xce_handle, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
   65.14 +}
   65.15 +
   65.16  evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
   65.17      evtchn_port_t remote_port)
   65.18  {
    66.1 --- a/tools/libxc/xenctrl.h	Sat Dec 02 15:19:50 2006 -0700
    66.2 +++ b/tools/libxc/xenctrl.h	Mon Dec 04 08:24:41 2006 -0700
    66.3 @@ -382,6 +382,10 @@ int xc_sched_credit_domain_get(int xc_ha
    66.4   * This function allocates an unbound port.  Ports are named endpoints used for
    66.5   * interdomain communication.  This function is most useful in opening a
    66.6   * well-known port within a domain to receive events on.
    66.7 + * 
    66.8 + * NOTE: If you are allocating a *local* unbound port, you probably want to
    66.9 + * use xc_evtchn_bind_unbound_port(). This function is intended for allocating
   66.10 + * ports *only* during domain creation.
   66.11   *
   66.12   * @parm xc_handle a handle to an open hypervisor interface
   66.13   * @parm dom the ID of the local domain (the 'allocatee')
   66.14 @@ -630,6 +634,12 @@ int xc_evtchn_fd(int xce_handle);
   66.15  int xc_evtchn_notify(int xce_handle, evtchn_port_t port);
   66.16  
   66.17  /*
   66.18 + * Returns a new event port awaiting interdomain connection from the given
   66.19 + * domain ID, or -1 on failure, in which case errno will be set appropriately.
   66.20 + */
   66.21 +evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid);
   66.22 +
   66.23 +/*
   66.24   * Returns a new event port bound to the remote port for the given domain ID,
   66.25   * or -1 on failure, in which case errno will be set appropriately.
   66.26   */
   66.27 @@ -661,15 +671,15 @@ evtchn_port_t xc_evtchn_pending(int xce_
   66.28  int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
   66.29  
   66.30  int xc_hvm_set_pci_intx_level(
   66.31 -    int xce_handle, domid_t dom,
   66.32 +    int xc_handle, domid_t dom,
   66.33      uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
   66.34      unsigned int level);
   66.35  int xc_hvm_set_isa_irq_level(
   66.36 -    int xce_handle, domid_t dom,
   66.37 +    int xc_handle, domid_t dom,
   66.38      uint8_t isa_irq,
   66.39      unsigned int level);
   66.40  
   66.41  int xc_hvm_set_pci_link_route(
   66.42 -    int xce_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
   66.43 +    int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
   66.44  
   66.45  #endif
    67.1 --- a/tools/libxen/Makefile	Sat Dec 02 15:19:50 2006 -0700
    67.2 +++ b/tools/libxen/Makefile	Mon Dec 04 08:24:41 2006 -0700
    67.3 @@ -48,8 +48,8 @@ libxenapi.so.$(MAJOR).$(MINOR): $(LIBXEN
    67.4  libxenapi.a: $(LIBXENAPI_OBJS)
    67.5  	$(AR) rcs libxenapi.a $^
    67.6  
    67.7 -test/test_bindings: test/test_bindings.o src/libxen.so
    67.8 -	$(CC) $(LDFLAGS) -o $@ $< -L src -lxen
    67.9 +test/test_bindings: test/test_bindings.o libxenapi.so
   67.10 +	$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
   67.11  
   67.12  
   67.13  .PHONY: install
    68.1 --- a/tools/libxen/README	Sat Dec 02 15:19:50 2006 -0700
    68.2 +++ b/tools/libxen/README	Mon Dec 04 08:24:41 2006 -0700
    68.3 @@ -44,11 +44,12 @@ The bindings depend upon libxml2, the XM
    68.4  test program depends upon libcurl3 also.  On Debian, you need the packages
    68.5  libxml2-dev and libcurl3-dev.
    68.6  
    68.7 -To compile, type make.
    68.8 +To compile, type make.  To compile the test also, type make
    68.9 +test/test_bindings, remembering the additional dependency.
   68.10  
   68.11  To run the test, do
   68.12  
   68.13 -LD_LIBRARY_PATH=src ./test/test_bindings <url> <username> <password>
   68.14 +LD_LIBRARY_PATH=. ./test/test_bindings <url> <username> <password>
   68.15  
   68.16  where <url> is the fragment of the server URL that follows the http://, for
   68.17  example "localhost:8005/RPC2".
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/tools/libxen/include/xen_console.h	Mon Dec 04 08:24:41 2006 -0700
    69.3 @@ -0,0 +1,207 @@
    69.4 +/*
    69.5 + * Copyright (c) 2006, XenSource Inc.
    69.6 + *
    69.7 + * This library is free software; you can redistribute it and/or
    69.8 + * modify it under the terms of the GNU Lesser General Public
    69.9 + * License as published by the Free Software Foundation; either
   69.10 + * version 2.1 of the License, or (at your option) any later version.
   69.11 + *
   69.12 + * This library is distributed in the hope that it will be useful,
   69.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   69.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   69.15 + * Lesser General Public License for more details.
   69.16 + *
   69.17 + * You should have received a copy of the GNU Lesser General Public
   69.18 + * License along with this library; if not, write to the Free Software
   69.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   69.20 + */
   69.21 +
   69.22 +#ifndef XEN_CONSOLE_H
   69.23 +#define XEN_CONSOLE_H
   69.24 +
   69.25 +#include "xen_common.h"
   69.26 +#include "xen_console_decl.h"
   69.27 +#include "xen_console_protocol.h"
   69.28 +#include "xen_vm_decl.h"
   69.29 +
   69.30 +
   69.31 +/*
   69.32 + * The console class. 
   69.33 + *  
   69.34 + * A console.
   69.35 + */
   69.36 +
   69.37 +
   69.38 +/**
   69.39 + * Free the given xen_console.  The given handle must have been
   69.40 + * allocated by this library.
   69.41 + */
   69.42 +extern void
   69.43 +xen_console_free(xen_console console);
   69.44 +
   69.45 +
   69.46 +typedef struct xen_console_set
   69.47 +{
   69.48 +    size_t size;
   69.49 +    xen_console *contents[];
   69.50 +} xen_console_set;
   69.51 +
   69.52 +/**
   69.53 + * Allocate a xen_console_set of the given size.
   69.54 + */
   69.55 +extern xen_console_set *
   69.56 +xen_console_set_alloc(size_t size);
   69.57 +
   69.58 +/**
   69.59 + * Free the given xen_console_set.  The given set must have been
   69.60 + * allocated by this library.
   69.61 + */
   69.62 +extern void
   69.63 +xen_console_set_free(xen_console_set *set);
   69.64 +
   69.65 +
   69.66 +typedef struct xen_console_record
   69.67 +{
   69.68 +    xen_console handle;
   69.69 +    char *uuid;
   69.70 +    enum xen_console_protocol protocol;
   69.71 +    char *uri;
   69.72 +    struct xen_vm_record_opt *vm;
   69.73 +} xen_console_record;
   69.74 +
   69.75 +/**
   69.76 + * Allocate a xen_console_record.
   69.77 + */
   69.78 +extern xen_console_record *
   69.79 +xen_console_record_alloc(void);
   69.80 +
   69.81 +/**
   69.82 + * Free the given xen_console_record, and all referenced values.  The
   69.83 + * given record must have been allocated by this library.
   69.84 + */
   69.85 +extern void
   69.86 +xen_console_record_free(xen_console_record *record);
   69.87 +
   69.88 +
   69.89 +typedef struct xen_console_record_opt
   69.90 +{
   69.91 +    bool is_record;
   69.92 +    union
   69.93 +    {
   69.94 +        xen_console handle;
   69.95 +        xen_console_record *record;
   69.96 +    } u;
   69.97 +} xen_console_record_opt;
   69.98 +
   69.99 +/**
  69.100 + * Allocate a xen_console_record_opt.
  69.101 + */
  69.102 +extern xen_console_record_opt *
  69.103 +xen_console_record_opt_alloc(void);
  69.104 +
  69.105 +/**
  69.106 + * Free the given xen_console_record_opt, and all referenced values. 
  69.107 + * The given record_opt must have been allocated by this library.
  69.108 + */
  69.109 +extern void
  69.110 +xen_console_record_opt_free(xen_console_record_opt *record_opt);
  69.111 +
  69.112 +
  69.113 +typedef struct xen_console_record_set
  69.114 +{
  69.115 +    size_t size;
  69.116 +    xen_console_record *contents[];
  69.117 +} xen_console_record_set;
  69.118 +
  69.119 +/**
  69.120 + * Allocate a xen_console_record_set of the given size.
  69.121 + */
  69.122 +extern xen_console_record_set *
  69.123 +xen_console_record_set_alloc(size_t size);
  69.124 +
  69.125 +/**
  69.126 + * Free the given xen_console_record_set, and all referenced values. 
  69.127 + * The given set must have been allocated by this library.
  69.128 + */
  69.129 +extern void
  69.130 +xen_console_record_set_free(xen_console_record_set *set);
  69.131 +
  69.132 +
  69.133 +
  69.134 +typedef struct xen_console_record_opt_set
  69.135 +{
  69.136 +    size_t size;
  69.137 +    xen_console_record_opt *contents[];
  69.138 +} xen_console_record_opt_set;
  69.139 +
  69.140 +/**
  69.141 + * Allocate a xen_console_record_opt_set of the given size.
  69.142 + */
  69.143 +extern xen_console_record_opt_set *
  69.144 +xen_console_record_opt_set_alloc(size_t size);
  69.145 +
  69.146 +/**
  69.147 + * Free the given xen_console_record_opt_set, and all referenced
  69.148 + * values.  The given set must have been allocated by this library.
  69.149 + */
  69.150 +extern void
  69.151 +xen_console_record_opt_set_free(xen_console_record_opt_set *set);
  69.152 +
  69.153 +
  69.154 +/**
  69.155 + * Get the current state of the given console.
  69.156 + */
  69.157 +extern bool
  69.158 +xen_console_get_record(xen_session *session, xen_console_record **result, xen_console console);
  69.159 +
  69.160 +
  69.161 +/**
  69.162 + * Get a reference to the object with the specified UUID.
  69.163 + */
  69.164 +extern bool
  69.165 +xen_console_get_by_uuid(xen_session *session, xen_console *result, char *uuid);
  69.166 +
  69.167 +
  69.168 +/**
  69.169 + * Create a new console instance, and return its handle.
  69.170 + */
  69.171 +extern bool
  69.172 +xen_console_create(xen_session *session, xen_console *result, xen_console_record *record);
  69.173 +
  69.174 +
  69.175 +/**
  69.176 + * Destroy the specified console instance.
  69.177 + */
  69.178 +extern bool
  69.179 +xen_console_destroy(xen_session *session, xen_console console);
  69.180 +
  69.181 +
  69.182 +/**
  69.183 + * Get the uuid field of the given console.
  69.184 + */
  69.185 +extern bool
  69.186 +xen_console_get_uuid(xen_session *session, char **result, xen_console console);
  69.187 +
  69.188 +
  69.189 +/**
  69.190 + * Get the protocol field of the given console.
  69.191 + */
  69.192 +extern bool
  69.193 +xen_console_get_protocol(xen_session *session, enum xen_console_protocol *result, xen_console console);
  69.194 +
  69.195 +
  69.196 +/**
  69.197 + * Get the uri field of the given console.
  69.198 + */
  69.199 +extern bool
  69.200 +xen_console_get_uri(xen_session *session, char **result, xen_console console);
  69.201 +
  69.202 +
  69.203 +/**
  69.204 + * Get the VM field of the given console.
  69.205 + */
  69.206 +extern bool
  69.207 +xen_console_get_vm(xen_session *session, xen_vm *result, xen_console console);
  69.208 +
  69.209 +
  69.210 +#endif
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/tools/libxen/include/xen_console_decl.h	Mon Dec 04 08:24:41 2006 -0700
    70.3 @@ -0,0 +1,30 @@
    70.4 +/*
    70.5 + * Copyright (c) 2006, XenSource Inc.
    70.6 + *
    70.7 + * This library is free software; you can redistribute it and/or
    70.8 + * modify it under the terms of the GNU Lesser General Public
    70.9 + * License as published by the Free Software Foundation; either
   70.10 + * version 2.1 of the License, or (at your option) any later version.
   70.11 + *
   70.12 + * This library is distributed in the hope that it will be useful,
   70.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   70.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   70.15 + * Lesser General Public License for more details.
   70.16 + *
   70.17 + * You should have received a copy of the GNU Lesser General Public
   70.18 + * License along with this library; if not, write to the Free Software
   70.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   70.20 + */
   70.21 +
   70.22 +#ifndef XEN_CONSOLE_DECL_H
   70.23 +#define XEN_CONSOLE_DECL_H
   70.24 +
   70.25 +typedef void *xen_console;
   70.26 +
   70.27 +struct xen_console_set;
   70.28 +struct xen_console_record;
   70.29 +struct xen_console_record_set;
   70.30 +struct xen_console_record_opt;
   70.31 +struct xen_console_record_opt_set;
   70.32 +
   70.33 +#endif
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/tools/libxen/include/xen_console_protocol.h	Mon Dec 04 08:24:41 2006 -0700
    71.3 @@ -0,0 +1,82 @@
    71.4 +/*
    71.5 + * Copyright (c) 2006, XenSource Inc.
    71.6 + *
    71.7 + * This library is free software; you can redistribute it and/or
    71.8 + * modify it under the terms of the GNU Lesser General Public
    71.9 + * License as published by the Free Software Foundation; either
   71.10 + * version 2.1 of the License, or (at your option) any later version.
   71.11 + *
   71.12 + * This library is distributed in the hope that it will be useful,
   71.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   71.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   71.15 + * Lesser General Public License for more details.
   71.16 + *
   71.17 + * You should have received a copy of the GNU Lesser General Public
   71.18 + * License along with this library; if not, write to the Free Software
   71.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   71.20 + */
   71.21 +
   71.22 +#ifndef XEN_CONSOLE_PROTOCOL_H
   71.23 +#define XEN_CONSOLE_PROTOCOL_H
   71.24 +
   71.25 +
   71.26 +#include "xen_common.h"
   71.27 +
   71.28 +
   71.29 +enum xen_console_protocol
   71.30 +{
   71.31 +    /**
   71.32 +     * VT100 terminal
   71.33 +     */
   71.34 +    XEN_CONSOLE_PROTOCOL_VT100,
   71.35 +
   71.36 +    /**
   71.37 +     * Remote FrameBuffer protocol (as used in VNC)
   71.38 +     */
   71.39 +    XEN_CONSOLE_PROTOCOL_RFB,
   71.40 +
   71.41 +    /**
   71.42 +     * Remote Desktop Protocol
   71.43 +     */
   71.44 +    XEN_CONSOLE_PROTOCOL_RDP
   71.45 +};
   71.46 +
   71.47 +
   71.48 +typedef struct xen_console_protocol_set
   71.49 +{
   71.50 +    size_t size;
   71.51 +    enum xen_console_protocol contents[];
   71.52 +} xen_console_protocol_set;
   71.53 +
   71.54 +/**
   71.55 + * Allocate a xen_console_protocol_set of the given size.
   71.56 + */
   71.57 +extern xen_console_protocol_set *
   71.58 +xen_console_protocol_set_alloc(size_t size);
   71.59 +
   71.60 +/**
   71.61 + * Free the given xen_console_protocol_set.  The given set must have
   71.62 + * been allocated by this library.
   71.63 + */
   71.64 +extern void
   71.65 +xen_console_protocol_set_free(xen_console_protocol_set *set);
   71.66 +
   71.67 +
   71.68 +/**
   71.69 + * Return the name corresponding to the given code.  This string must
   71.70 + * not be modified or freed.
   71.71 + */
   71.72 +extern const char *
   71.73 +xen_console_protocol_to_string(enum xen_console_protocol val);
   71.74 +
   71.75 +
   71.76 +/**
   71.77 + * Return the correct code for the given string, or set the session
   71.78 + * object to failure and return an undefined value if the given string does
   71.79 + * not match a known code.
   71.80 + */
   71.81 +extern enum xen_console_protocol
   71.82 +xen_console_protocol_from_string(xen_session *session, const char *str);
   71.83 +
   71.84 +
   71.85 +#endif
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/tools/libxen/include/xen_console_protocol_internal.h	Mon Dec 04 08:24:41 2006 -0700
    72.3 @@ -0,0 +1,37 @@
    72.4 +/*
    72.5 + * Copyright (c) 2006, XenSource Inc.
    72.6 + *
    72.7 + * This library is free software; you can redistribute it and/or
    72.8 + * modify it under the terms of the GNU Lesser General Public
    72.9 + * License as published by the Free Software Foundation; either
   72.10 + * version 2.1 of the License, or (at your option) any later version.
   72.11 + *
   72.12 + * This library is distributed in the hope that it will be useful,
   72.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   72.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   72.15 + * Lesser General Public License for more details.
   72.16 + *
   72.17 + * You should have received a copy of the GNU Lesser General Public
   72.18 + * License along with this library; if not, write to the Free Software
   72.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   72.20 + */
   72.21 +
   72.22 +
   72.23 +/*
   72.24 + * Declarations of the abstract types used during demarshalling of enum
   72.25 + * xen_console_protocol.  Internal to this library -- do not use from outside.
   72.26 + */
   72.27 +
   72.28 +
   72.29 +#ifndef XEN_CONSOLE_PROTOCOL_INTERNAL_H
   72.30 +#define XEN_CONSOLE_PROTOCOL_INTERNAL_H
   72.31 +
   72.32 +
   72.33 +#include "xen_internal.h"
   72.34 +
   72.35 +
   72.36 +extern const abstract_type xen_console_protocol_abstract_type_;
   72.37 +extern const abstract_type xen_console_protocol_set_abstract_type_;
   72.38 +
   72.39 +
   72.40 +#endif
    73.1 --- a/tools/libxen/include/xen_vm.h	Sat Dec 02 15:19:50 2006 -0700
    73.2 +++ b/tools/libxen/include/xen_vm.h	Mon Dec 04 08:24:41 2006 -0700
    73.3 @@ -21,6 +21,7 @@
    73.4  
    73.5  #include "xen_boot_type.h"
    73.6  #include "xen_common.h"
    73.7 +#include "xen_console_decl.h"
    73.8  #include "xen_cpu_feature.h"
    73.9  #include "xen_host_decl.h"
   73.10  #include "xen_int_float_map.h"
   73.11 @@ -96,6 +97,7 @@ typedef struct xen_vm_record
   73.12      enum xen_on_normal_exit actions_after_reboot;
   73.13      enum xen_on_normal_exit actions_after_suspend;
   73.14      enum xen_on_crash_behaviour actions_after_crash;
   73.15 +    struct xen_console_record_opt_set *consoles;
   73.16      struct xen_vif_record_opt_set *vifs;
   73.17      struct xen_vbd_record_opt_set *vbds;
   73.18      struct xen_vtpm_record_opt_set *vtpms;
   73.19 @@ -401,6 +403,13 @@ xen_vm_get_actions_after_crash(xen_sessi
   73.20  
   73.21  
   73.22  /**
   73.23 + * Get the consoles field of the given VM.
   73.24 + */
   73.25 +extern bool
   73.26 +xen_vm_get_consoles(xen_session *session, struct xen_console_set **result, xen_vm vm);
   73.27 +
   73.28 +
   73.29 +/**
   73.30   * Get the VIFs field of the given VM.
   73.31   */
   73.32  extern bool
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/tools/libxen/src/xen_console.c	Mon Dec 04 08:24:41 2006 -0700
    74.3 @@ -0,0 +1,207 @@
    74.4 +/*
    74.5 + * Copyright (c) 2006, XenSource Inc.
    74.6 + *
    74.7 + * This library is free software; you can redistribute it and/or
    74.8 + * modify it under the terms of the GNU Lesser General Public
    74.9 + * License as published by the Free Software Foundation; either
   74.10 + * version 2.1 of the License, or (at your option) any later version.
   74.11 + *
   74.12 + * This library is distributed in the hope that it will be useful,
   74.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   74.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   74.15 + * Lesser General Public License for more details.
   74.16 + *
   74.17 + * You should have received a copy of the GNU Lesser General Public
   74.18 + * License along with this library; if not, write to the Free Software
   74.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   74.20 + */
   74.21 +
   74.22 +
   74.23 +#include <stddef.h>
   74.24 +#include <stdlib.h>
   74.25 +
   74.26 +#include "xen_common.h"
   74.27 +#include "xen_console.h"
   74.28 +#include "xen_console_protocol_internal.h"
   74.29 +#include "xen_internal.h"
   74.30 +#include "xen_vm.h"
   74.31 +
   74.32 +
   74.33 +XEN_FREE(xen_console)
   74.34 +XEN_SET_ALLOC_FREE(xen_console)
   74.35 +XEN_ALLOC(xen_console_record)
   74.36 +XEN_SET_ALLOC_FREE(xen_console_record)
   74.37 +XEN_ALLOC(xen_console_record_opt)
   74.38 +XEN_RECORD_OPT_FREE(xen_console)
   74.39 +XEN_SET_ALLOC_FREE(xen_console_record_opt)
   74.40 +
   74.41 +
   74.42 +static const struct_member xen_console_record_struct_members[] =
   74.43 +    {
   74.44 +        { .key = "uuid",
   74.45 +          .type = &abstract_type_string,
   74.46 +          .offset = offsetof(xen_console_record, uuid) },
   74.47 +        { .key = "protocol",
   74.48 +          .type = &xen_console_protocol_abstract_type_,
   74.49 +          .offset = offsetof(xen_console_record, protocol) },
   74.50 +        { .key = "uri",
   74.51 +          .type = &abstract_type_string,
   74.52 +          .offset = offsetof(xen_console_record, uri) },
   74.53 +        { .key = "VM",
   74.54 +          .type = &abstract_type_ref,
   74.55 +          .offset = offsetof(xen_console_record, vm) }
   74.56 +    };
   74.57 +
   74.58 +const abstract_type xen_console_record_abstract_type_ =
   74.59 +    {
   74.60 +       .typename = STRUCT,
   74.61 +       .struct_size = sizeof(xen_console_record),
   74.62 +       .member_count =
   74.63 +           sizeof(xen_console_record_struct_members) / sizeof(struct_member),
   74.64 +       .members = xen_console_record_struct_members
   74.65 +    };
   74.66 +
   74.67 +
   74.68 +void
   74.69 +xen_console_record_free(xen_console_record *record)
   74.70 +{
   74.71 +    if (record == NULL)
   74.72 +    {
   74.73 +        return;
   74.74 +    }
   74.75 +    free(record->handle);
   74.76 +    free(record->uuid);
   74.77 +    free(record->uri);
   74.78 +    xen_vm_record_opt_free(record->vm);
   74.79 +    free(record);
   74.80 +}
   74.81 +
   74.82 +
   74.83 +bool
   74.84 +xen_console_get_record(xen_session *session, xen_console_record **result, xen_console console)
   74.85 +{
   74.86 +    abstract_value param_values[] =
   74.87 +        {
   74.88 +            { .type = &abstract_type_string,
   74.89 +              .u.string_val = console }
   74.90 +        };
   74.91 +
   74.92 +    abstract_type result_type = xen_console_record_abstract_type_;
   74.93 +
   74.94 +    *result = NULL;
   74.95 +    XEN_CALL_("console.get_record");
   74.96 +
   74.97 +    if (session->ok)
   74.98 +    {
   74.99 +       (*result)->handle = xen_strdup_((*result)->uuid);
  74.100 +    }
  74.101 +
  74.102 +    return session->ok;
  74.103 +}
  74.104 +
  74.105 +
  74.106 +bool
  74.107 +xen_console_get_by_uuid(xen_session *session, xen_console *result, char *uuid)
  74.108 +{
  74.109 +    abstract_value param_values[] =
  74.110 +        {
  74.111 +            { .type = &abstract_type_string,
  74.112 +              .u.string_val = uuid }
  74.113 +        };
  74.114 +
  74.115 +    abstract_type result_type = abstract_type_string;
  74.116 +
  74.117 +    *result = NULL;
  74.118 +    XEN_CALL_("console.get_by_uuid");
  74.119 +    return session->ok;
  74.120 +}
  74.121 +
  74.122 +
  74.123 +bool
  74.124 +xen_console_create(xen_session *session, xen_console *result, xen_console_record *record)
  74.125 +{
  74.126 +    abstract_value param_values[] =
  74.127 +        {
  74.128 +            { .type = &xen_console_record_abstract_type_,
  74.129 +              .u.struct_val = record }
  74.130 +        };
  74.131 +
  74.132 +    abstract_type result_type = abstract_type_string;
  74.133 +
  74.134 +    *result = NULL;
  74.135 +    XEN_CALL_("console.create");
  74.136 +    return session->ok;
  74.137 +}
  74.138 +
  74.139 +
  74.140 +bool
  74.141 +xen_console_destroy(xen_session *session, xen_console console)
  74.142 +{
  74.143 +    abstract_value param_values[] =
  74.144 +        {
  74.145 +            { .type = &abstract_type_string,
  74.146 +              .u.string_val = console }
  74.147 +        };
  74.148 +
  74.149 +    xen_call_(session, "console.destroy", param_values, 1, NULL, NULL);
  74.150 +    return session->ok;
  74.151 +}
  74.152 +
  74.153 +
  74.154 +bool
  74.155 +xen_console_get_protocol(xen_session *session, enum xen_console_protocol *result, xen_console console)
  74.156 +{
  74.157 +    abstract_value param_values[] =
  74.158 +        {
  74.159 +            { .type = &abstract_type_string,
  74.160 +              .u.string_val = console }
  74.161 +        };
  74.162 +
  74.163 +    abstract_type result_type = xen_console_protocol_abstract_type_;
  74.164 +    char *result_str = NULL;
  74.165 +    XEN_CALL_("console.get_protocol");
  74.166 +    *result = xen_console_protocol_from_string(session, result_str);
  74.167 +    return session->ok;
  74.168 +}
  74.169 +
  74.170 +
  74.171 +bool
  74.172 +xen_console_get_uri(xen_session *session, char **result, xen_console console)
  74.173 +{
  74.174 +    abstract_value param_values[] =
  74.175 +        {
  74.176 +            { .type = &abstract_type_string,
  74.177 +              .u.string_val = console }
  74.178 +        };
  74.179 +
  74.180 +    abstract_type result_type = abstract_type_string;
  74.181 +
  74.182 +    *result = NULL;
  74.183 +    XEN_CALL_("console.get_uri");
  74.184 +    return session->ok;
  74.185 +}
  74.186 +
  74.187 +
  74.188 +bool
  74.189 +xen_console_get_vm(xen_session *session, xen_vm *result, xen_console console)
  74.190 +{
  74.191 +    abstract_value param_values[] =
  74.192 +        {
  74.193 +            { .type = &abstract_type_string,
  74.194 +              .u.string_val = console }
  74.195 +        };
  74.196 +
  74.197 +    abstract_type result_type = abstract_type_string;
  74.198 +
  74.199 +    *result = NULL;
  74.200 +    XEN_CALL_("console.get_VM");
  74.201 +    return session->ok;
  74.202 +}
  74.203 +
  74.204 +
  74.205 +bool
  74.206 +xen_console_get_uuid(xen_session *session, char **result, xen_console console)
  74.207 +{
  74.208 +    *result = session->ok ? xen_strdup_((char *)console) : NULL;
  74.209 +    return session->ok;
  74.210 +}
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/tools/libxen/src/xen_console_protocol.c	Mon Dec 04 08:24:41 2006 -0700
    75.3 @@ -0,0 +1,82 @@
    75.4 +/*
    75.5 + * Copyright (c) 2006, XenSource Inc.
    75.6 + *
    75.7 + * This library is free software; you can redistribute it and/or
    75.8 + * modify it under the terms of the GNU Lesser General Public
    75.9 + * License as published by the Free Software Foundation; either
   75.10 + * version 2.1 of the License, or (at your option) any later version.
   75.11 + *
   75.12 + * This library is distributed in the hope that it will be useful,
   75.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   75.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   75.15 + * Lesser General Public License for more details.
   75.16 + *
   75.17 + * You should have received a copy of the GNU Lesser General Public
   75.18 + * License along with this library; if not, write to the Free Software
   75.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   75.20 + */
   75.21 +
   75.22 +#include <string.h>
   75.23 +
   75.24 +#include "xen_internal.h"
   75.25 +#include "xen_console_protocol.h"
   75.26 +#include "xen_console_protocol_internal.h"
   75.27 +
   75.28 +
   75.29 +/*
   75.30 + * Maintain this in the same order as the enum declaration!
   75.31 + */
   75.32 +static const char *lookup_table[] =
   75.33 +{
   75.34 +    "vt100",
   75.35 +    "rfb",
   75.36 +    "rdp"
   75.37 +};
   75.38 +
   75.39 +
   75.40 +extern xen_console_protocol_set *
   75.41 +xen_console_protocol_set_alloc(size_t size)
   75.42 +{
   75.43 +    return calloc(1, sizeof(xen_console_protocol_set) +
   75.44 +                  size * sizeof(enum xen_console_protocol));
   75.45 +}
   75.46 +
   75.47 +
   75.48 +extern void
   75.49 +xen_console_protocol_set_free(xen_console_protocol_set *set)
   75.50 +{
   75.51 +    free(set);
   75.52 +}
   75.53 +
   75.54 +
   75.55 +const char *
   75.56 +xen_console_protocol_to_string(enum xen_console_protocol val)
   75.57 +{
   75.58 +    return lookup_table[val];
   75.59 +}
   75.60 +
   75.61 +
   75.62 +extern enum xen_console_protocol
   75.63 +xen_console_protocol_from_string(xen_session *session, const char *str)
   75.64 +{
   75.65 +    return ENUM_LOOKUP(session, str, lookup_table);
   75.66 +}
   75.67 +
   75.68 +
   75.69 +const abstract_type xen_console_protocol_abstract_type_ =
   75.70 +    {
   75.71 +        .typename = ENUM,
   75.72 +        .enum_marshaller =
   75.73 +             (const char *(*)(int))&xen_console_protocol_to_string,
   75.74 +        .enum_demarshaller =
   75.75 +             (int (*)(xen_session *, const char *))&xen_console_protocol_from_string
   75.76 +    };
   75.77 +
   75.78 +
   75.79 +const abstract_type xen_console_protocol_set_abstract_type_ =
   75.80 +    {
   75.81 +        .typename = SET,
   75.82 +        .child = &xen_console_protocol_abstract_type_
   75.83 +    };
   75.84 +
   75.85 +
    76.1 --- a/tools/libxen/src/xen_vm.c	Sat Dec 02 15:19:50 2006 -0700
    76.2 +++ b/tools/libxen/src/xen_vm.c	Mon Dec 04 08:24:41 2006 -0700
    76.3 @@ -22,6 +22,7 @@
    76.4  
    76.5  #include "xen_boot_type_internal.h"
    76.6  #include "xen_common.h"
    76.7 +#include "xen_console.h"
    76.8  #include "xen_cpu_feature.h"
    76.9  #include "xen_cpu_feature_internal.h"
   76.10  #include "xen_host.h"
   76.11 @@ -120,6 +121,9 @@ static const struct_member xen_vm_record
   76.12          { .key = "actions_after_crash",
   76.13            .type = &xen_on_crash_behaviour_abstract_type_,
   76.14            .offset = offsetof(xen_vm_record, actions_after_crash) },
   76.15 +        { .key = "consoles",
   76.16 +          .type = &abstract_type_ref_set,
   76.17 +          .offset = offsetof(xen_vm_record, consoles) },
   76.18          { .key = "VIFs",
   76.19            .type = &abstract_type_ref_set,
   76.20            .offset = offsetof(xen_vm_record, vifs) },
   76.21 @@ -205,6 +209,7 @@ xen_vm_record_free(xen_vm_record *record
   76.22      xen_cpu_feature_set_free(record->vcpus_features_can_use);
   76.23      xen_cpu_feature_set_free(record->vcpus_features_force_on);
   76.24      xen_cpu_feature_set_free(record->vcpus_features_force_off);
   76.25 +    xen_console_record_opt_set_free(record->consoles);
   76.26      xen_vif_record_opt_set_free(record->vifs);
   76.27      xen_vbd_record_opt_set_free(record->vbds);
   76.28      xen_vtpm_record_opt_set_free(record->vtpms);
   76.29 @@ -694,6 +699,23 @@ xen_vm_get_actions_after_crash(xen_sessi
   76.30  
   76.31  
   76.32  bool
   76.33 +xen_vm_get_consoles(xen_session *session, struct xen_console_set **result, xen_vm vm)
   76.34 +{
   76.35 +    abstract_value param_values[] =
   76.36 +        {
   76.37 +            { .type = &abstract_type_string,
   76.38 +              .u.string_val = vm }
   76.39 +        };
   76.40 +
   76.41 +    abstract_type result_type = abstract_type_string_set;
   76.42 +
   76.43 +    *result = NULL;
   76.44 +    XEN_CALL_("VM.get_consoles");
   76.45 +    return session->ok;
   76.46 +}
   76.47 +
   76.48 +
   76.49 +bool
   76.50  xen_vm_get_vifs(xen_session *session, struct xen_vif_set **result, xen_vm vm)
   76.51  {
   76.52      abstract_value param_values[] =
    77.1 --- a/tools/python/scripts/xapi.domcfg.py	Sat Dec 02 15:19:50 2006 -0700
    77.2 +++ b/tools/python/scripts/xapi.domcfg.py	Mon Dec 04 08:24:41 2006 -0700
    77.3 @@ -26,7 +26,7 @@ platform_serial =  ''
    77.4  platform_localtime =  False
    77.5  platform_clock_offset =  False
    77.6  platform_enable_audio =  False
    77.7 -builder =  ''
    77.8 +builder =  'linux'
    77.9  boot_method =  '' # this will remove the kernel/initrd ??
   77.10  kernel_kernel =  '/boot/vmlinuz-2.6.16.29-xen'
   77.11  kernel_initrd =  '/root/initrd-2.6.16.29-xen.img'
    78.1 --- a/tools/python/scripts/xapi.py	Sat Dec 02 15:19:50 2006 -0700
    78.2 +++ b/tools/python/scripts/xapi.py	Mon Dec 04 08:24:41 2006 -0700
    78.3 @@ -29,17 +29,20 @@ from getpass import getpass
    78.4  MB = 1024 * 1024
    78.5  
    78.6  HOST_INFO_FORMAT = '%-20s: %-50s'
    78.7 -VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(vcpus_number)-5s'\
    78.8 +VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(VCPUs_number)-5s'\
    78.9                   ' %(power_state)-10s %(uuid)-36s'
   78.10  SR_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(physical_size)-10s' \
   78.11                   '%(type)-10s'
   78.12  VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s '\
   78.13                    '%(sector_size)-8s'
   78.14 +VBD_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(VDI)-8s '\
   78.15 +                  '%(image)-8s'
   78.16  
   78.17  COMMANDS = {
   78.18      'host-info': ('', 'Get Xen Host Info'),
   78.19      'host-set-name': ('', 'Set host name'),
   78.20      'sr-list':   ('', 'List all SRs'),
   78.21 +    'vbd-list':  ('', 'List all VBDs'),
   78.22      'vbd-create': ('<domname> <pycfg> [opts]',
   78.23                     'Create VBD attached to domname'),
   78.24      'vdi-create': ('<pycfg> [opts]', 'Create a VDI'),
   78.25 @@ -165,6 +168,13 @@ def resolve_vm(server, session, vm_name)
   78.26      else:
   78.27          return vm_uuid[0]
   78.28  
   78.29 +def resolve_vdi(server, session, vdi_name):
   78.30 +    vdi_uuid = execute(server.VDI.get_by_name_label, session, vdi_name)
   78.31 +    if not vdi_uuid:
   78.32 +        return None
   78.33 +    else:
   78.34 +        return vdi_uuid[0]
   78.35 +
   78.36  #
   78.37  # Actual commands
   78.38  #
   78.39 @@ -216,16 +226,16 @@ def xapi_vm_list(*args):
   78.40      if not is_long:
   78.41          print VM_LIST_FORMAT % {'name_label':'Name',
   78.42                                  'memory_actual':'Mem',
   78.43 -                                'vcpus_number': 'VCPUs',
   78.44 +                                'VCPUs_number': 'VCPUs',
   78.45                                  'power_state': 'State',
   78.46                                  'uuid': 'UUID'}
   78.47  
   78.48      for uuid in vm_uuids:
   78.49          vm_info = execute(server.VM.get_record, session, uuid)
   78.50          if is_long:
   78.51 -            vbds = vm_info['vbds']
   78.52 -            vifs = vm_info['vifs']
   78.53 -            vtpms = vm_info['vtpms']
   78.54 +            vbds = vm_info['VBDs']
   78.55 +            vifs = vm_info['VIFs']
   78.56 +            vtpms = vm_info['VTPMs']
   78.57              vif_infos = []
   78.58              vbd_infos = []
   78.59              vtpm_infos = []
   78.60 @@ -238,9 +248,9 @@ def xapi_vm_list(*args):
   78.61              for vtpm in vtpms:
   78.62                  vtpm_info = execute(server.VTPM.get_record, session, vtpm)
   78.63                  vtpm_infos.append(vtpm_info)
   78.64 -            vm_info['vbds'] = vbd_infos
   78.65 -            vm_info['vifs'] = vif_infos
   78.66 -            vm_info['vtpms'] = vtpm_infos
   78.67 +            vm_info['VBDs'] = vbd_infos
   78.68 +            vm_info['VIFs'] = vif_infos
   78.69 +            vm_info['VTPMs'] = vtpm_infos
   78.70              pprint(vm_info)
   78.71          else:
   78.72              print VM_LIST_FORMAT % _stringify(vm_info)
   78.73 @@ -276,7 +286,7 @@ def xapi_vm_start(*args):
   78.74      server, session = _connect()
   78.75      vm_uuid = resolve_vm(server, session, args[0])
   78.76      print 'Starting VM %s (%s)' % (args[0], vm_uuid)
   78.77 -    success = execute(server.VM.start, session, vm_uuid)
   78.78 +    success = execute(server.VM.start, session, vm_uuid, False)
   78.79      print 'Done.'
   78.80  
   78.81  def xapi_vm_shutdown(*args):
   78.82 @@ -334,6 +344,22 @@ def xapi_vif_create(*args):
   78.83      vif_uuid = execute(server.VIF.create, session, cfg)
   78.84      print 'Done. (%s)' % vif_uuid
   78.85  
   78.86 +def xapi_vbd_list(*args):
   78.87 +    server, session = _connect()
   78.88 +    domname = args[0]
   78.89 +    
   78.90 +    dom_uuid = resolve_vm(server, session, domname)
   78.91 +    vbds = execute(server.VM.get_VBDs, session, dom_uuid)
   78.92 +    
   78.93 +    print VBD_LIST_FORMAT % {'name_label': 'VDI Label',
   78.94 +                             'uuid' : 'UUID',
   78.95 +                             'VDI': 'VDI',
   78.96 +                             'image': 'Image'}
   78.97 +    
   78.98 +    for vbd in vbds:
   78.99 +        vbd_struct = execute(server.VBD.get_record, session, vbd)
  78.100 +        print VBD_LIST_FORMAT % vbd_struct
  78.101 +
  78.102  def xapi_vdi_list(*args):
  78.103      server, session = _connect()
  78.104      vdis = execute(server.VDI.get_all, session)
  78.105 @@ -420,8 +446,6 @@ def xapi_vtpm_create(*args):
  78.106      print "Has driver type '%s'" % driver
  78.107      vtpm_rec = execute(server.VTPM.get_record, session, vtpm_uuid)
  78.108      print "Has vtpm record '%s'" % vtpm_rec
  78.109 -    vm = execute(server.VTPM.get_VM, session, vtpm_uuid)
  78.110 -    print "Has VM '%s'" % vm
  78.111  
  78.112  
  78.113  #
    79.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Sat Dec 02 15:19:50 2006 -0700
    79.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Mon Dec 04 08:24:41 2006 -0700
    79.3 @@ -392,7 +392,7 @@ static PyObject *pyxc_hvm_build(XcObject
    79.4          return PyErr_SetFromErrno(xc_error);
    79.5  
    79.6      /* Set up the HVM info table. */
    79.7 -    va_map = xc_map_foreign_range(self->xc_handle, dom, PAGE_SIZE,
    79.8 +    va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
    79.9                                    PROT_READ | PROT_WRITE,
   79.10                                    HVM_INFO_PFN);
   79.11      if ( va_map == NULL )
   79.12 @@ -407,7 +407,7 @@ static PyObject *pyxc_hvm_build(XcObject
   79.13      for ( i = 0, sum = 0; i < va_hvm->length; i++ )
   79.14          sum += ((uint8_t *)va_hvm)[i];
   79.15      va_hvm->checksum = -sum;
   79.16 -    munmap(va_map, PAGE_SIZE);
   79.17 +    munmap(va_map, XC_PAGE_SIZE);
   79.18  
   79.19      xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
   79.20      xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
    80.1 --- a/tools/python/xen/util/bugtool.py	Sat Dec 02 15:19:50 2006 -0700
    80.2 +++ b/tools/python/xen/util/bugtool.py	Mon Dec 04 08:24:41 2006 -0700
    80.3 @@ -43,8 +43,9 @@ TITLE_RE = re.compile(r'<title>(.*)</tit
    80.4  
    80.5  FILES_TO_SEND = [ '/var/log/' + x for x in 
    80.6                    [ 'syslog', 'messages', 'debug',
    80.7 -                    'xen/xend.log', 'xen/xend-debug.log', 'xen/xenstored-trace.log',
    80.8 -                    'xen/xen-hotplug.log' ] ]
    80.9 +                    'xen/xend-debug.log', 'xen/xenstored-trace.log',
   80.10 +                    'xen/xen-hotplug.log', 'xen/xend.log' ] +
   80.11 +                  [ 'xen/xend.log.%d' % z for z in range(1,6) ] ]
   80.12  #FILES_TO_SEND = [  ]
   80.13  
   80.14  
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/tools/python/xen/util/mkdir.py	Mon Dec 04 08:24:41 2006 -0700
    81.3 @@ -0,0 +1,44 @@
    81.4 +#============================================================================
    81.5 +# This library is free software; you can redistribute it and/or modify
    81.6 +# it under the terms of the GNU Lesser General Public License as published by
    81.7 +# the Free Software Foundation; either version 2.1 of the License, or
    81.8 +# (at your option) any later version.
    81.9 +#
   81.10 +# This library is distributed in the hope that it will be useful,
   81.11 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   81.12 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   81.13 +# GNU Lesser General Public License for more details.
   81.14 +#
   81.15 +# You should have received a copy of the GNU Lesser General Public License
   81.16 +# along with this library; if not, write to the Free Software
   81.17 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   81.18 +#============================================================================
   81.19 +# Copyright (c) 2006 XenSource Inc.
   81.20 +#============================================================================
   81.21 +
   81.22 +import errno
   81.23 +import os
   81.24 +import os.path
   81.25 +import stat
   81.26 +
   81.27 +
   81.28 +def parents(dir, perms, enforcePermissions = False):
   81.29 +    """
   81.30 +    Ensure that the given directory exists, creating it if necessary, but not
   81.31 +    complaining if it's already there.
   81.32 +    
   81.33 +    @param dir The directory name.
   81.34 +    @param perms One of the stat.S_ constants.
   81.35 +    @param enforcePermissions Enforce our ownership and the given permissions,
   81.36 +    even if the directory pre-existed with different ones.
   81.37 +    """
   81.38 +    # Catch the exception here, rather than checking for the directory's
   81.39 +    # existence first, to avoid races.
   81.40 +    try:
   81.41 +        os.makedirs(dir, perms)
   81.42 +    except OSError, exn:
   81.43 +        if exn.args[0] != errno.EEXIST or not os.path.isdir(dir):
   81.44 +            raise
   81.45 +    if enforcePermissions:
   81.46 +        os.chown(dir, os.geteuid(), os.getegid())
   81.47 +        os.chmod(dir, stat.S_IRWXU)
    82.1 --- a/tools/python/xen/util/xmlrpclib2.py	Sat Dec 02 15:19:50 2006 -0700
    82.2 +++ b/tools/python/xen/util/xmlrpclib2.py	Mon Dec 04 08:24:41 2006 -0700
    82.3 @@ -30,6 +30,8 @@ from SimpleXMLRPCServer import SimpleXML
    82.4  import SocketServer
    82.5  import xmlrpclib, socket, os, stat
    82.6  
    82.7 +import mkdir
    82.8 +
    82.9  from xen.web import connection
   82.10  from xen.xend.XendLogging import log
   82.11  
   82.12 @@ -234,14 +236,9 @@ class UnixXMLRPCServer(TCPXMLRPCServer):
   82.13      address_family = socket.AF_UNIX
   82.14  
   82.15      def __init__(self, addr, allowed, logRequests = 1):
   82.16 -        parent = os.path.dirname(addr)
   82.17 -        if os.path.exists(parent):
   82.18 -            os.chown(parent, os.geteuid(), os.getegid())
   82.19 -            os.chmod(parent, stat.S_IRWXU)
   82.20 -            if self.allow_reuse_address and os.path.exists(addr):
   82.21 -                os.unlink(addr)
   82.22 -        else:
   82.23 -            os.makedirs(parent, stat.S_IRWXU)
   82.24 +        mkdir.parents(os.path.dirname(addr), stat.S_IRWXU, True)
   82.25 +        if self.allow_reuse_address and os.path.exists(addr):
   82.26 +            os.unlink(addr)
   82.27  
   82.28          TCPXMLRPCServer.__init__(self, addr, allowed,
   82.29                                   UnixXMLRPCRequestHandler, logRequests)
    83.1 --- a/tools/python/xen/web/unix.py	Sat Dec 02 15:19:50 2006 -0700
    83.2 +++ b/tools/python/xen/web/unix.py	Mon Dec 04 08:24:41 2006 -0700
    83.3 @@ -22,6 +22,8 @@ import os.path
    83.4  import socket
    83.5  import stat
    83.6  
    83.7 +from xen.util import mkdir
    83.8 +
    83.9  import connection
   83.10  
   83.11  
   83.12 @@ -30,13 +32,9 @@ def bind(path):
   83.13  created such that only the current user may access it."""
   83.14  
   83.15      parent = os.path.dirname(path)
   83.16 -    if os.path.exists(parent):
   83.17 -        os.chown(parent, os.geteuid(), os.getegid())
   83.18 -        os.chmod(parent, stat.S_IRWXU)
   83.19 -        if os.path.exists(path):
   83.20 -            os.unlink(path)
   83.21 -    else:
   83.22 -        os.makedirs(parent, stat.S_IRWXU)
   83.23 +    mkdir.parents(parent, stat.S_IRWXU, True)
   83.24 +    if os.path.exists(path):
   83.25 +        os.unlink(path)
   83.26  
   83.27      sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
   83.28      sock.bind(path)
    84.1 --- a/tools/python/xen/xend/XendAPI.py	Sat Dec 02 15:19:50 2006 -0700
    84.2 +++ b/tools/python/xen/xend/XendAPI.py	Mon Dec 04 08:24:41 2006 -0700
    84.3 @@ -303,8 +303,8 @@ class XendAPI:
    84.4          #    all get_by_uuid() methods.
    84.5          
    84.6          for cls in classes.keys():
    84.7 -            get_by_uuid = '%s_get_by_uuid' % cls.lower()
    84.8 -            get_uuid = '%s_get_uuid' % cls.lower()            
    84.9 +            get_by_uuid = '%s_get_by_uuid' % cls
   84.10 +            get_uuid = '%s_get_uuid' % cls
   84.11              setattr(XendAPI, get_by_uuid,
   84.12                      lambda s, sess, obj_ref: xen_api_success(obj_ref))
   84.13              setattr(XendAPI, get_uuid,
   84.14 @@ -327,7 +327,7 @@ class XendAPI:
   84.15  
   84.16              # wrap validators around readable class attributes
   84.17              for attr_name in ro_attrs + rw_attrs + self.Base_attr_ro:
   84.18 -                getter_name = '%s_get_%s' % (cls.lower(), attr_name)
   84.19 +                getter_name = '%s_get_%s' % (cls, attr_name)
   84.20                  try:
   84.21                      getter = getattr(XendAPI, getter_name)
   84.22                      for validator in validators:
   84.23 @@ -340,7 +340,7 @@ class XendAPI:
   84.24  
   84.25              # wrap validators around writable class attrributes
   84.26              for attr_name in rw_attrs + self.Base_attr_rw:
   84.27 -                setter_name = '%s_set_%s' % (cls.lower(), attr_name)
   84.28 +                setter_name = '%s_set_%s' % (cls, attr_name)
   84.29                  try:
   84.30                      setter = getattr(XendAPI, setter_name)
   84.31                      for validator in validators:
   84.32 @@ -353,7 +353,8 @@ class XendAPI:
   84.33  
   84.34              # wrap validators around methods
   84.35              for method_name in methods + self.Base_methods:
   84.36 -                method_full_name = '%s_%s' % (cls.lower(), method_name)
   84.37 +                method_full_name = '%s_%s' % (cls, method_name)
   84.38 +
   84.39                  try:
   84.40                      method = getattr(XendAPI, method_full_name)
   84.41                      for validator in validators:
   84.42 @@ -366,7 +367,7 @@ class XendAPI:
   84.43  
   84.44              # wrap validators around class functions
   84.45              for func_name in funcs + self.Base_funcs:
   84.46 -                func_full_name = '%s_%s' % (cls.lower(), func_name)
   84.47 +                func_full_name = '%s_%s' % (cls, func_name)
   84.48                  try:
   84.49                      method = getattr(XendAPI, func_full_name)
   84.50                      method = session_required(method)
   84.51 @@ -379,7 +380,7 @@ class XendAPI:
   84.52  
   84.53      Base_attr_ro = ['uuid']
   84.54      Base_attr_rw = []
   84.55 -    Base_methods = ['destroy', 'to_XML', 'get_record']
   84.56 +    Base_methods = ['destroy', 'get_record']
   84.57      Base_funcs   = ['create', 'get_by_uuid', 'get_all']
   84.58  
   84.59      # Xen API: Class Session
   84.60 @@ -411,8 +412,6 @@ class XendAPI:
   84.61          record = {'this_host': XendNode.instance().uuid,
   84.62                    'this_user': auth_manager().get_user(session)}
   84.63          return xen_api_success(record)
   84.64 -    def session_to_XML(self, session):
   84.65 -        return xen_api_todo()
   84.66  
   84.67      # attributes (ro)
   84.68      def session_get_this_host(self, session):
   84.69 @@ -536,8 +535,6 @@ class XendAPI:
   84.70                    'features': node.get_host_cpu_features(host_cpu_ref),
   84.71                    'utilisation': node.get_host_cpu_load(host_cpu_ref)}
   84.72          return xen_api_success(record)
   84.73 -    def host_cpu_to_XML(self, session, host_cpu_ref):
   84.74 -        return xen_api_todo()
   84.75  
   84.76      # class methods
   84.77      def host_cpu_get_all(self, session):
   84.78 @@ -656,304 +653,301 @@ class XendAPI:
   84.79          'otherConfig']
   84.80          
   84.81      # attributes (ro)
   84.82 -    def vm_get_power_state(self, session, vm_ref):
   84.83 +    def VM_get_power_state(self, session, vm_ref):
   84.84          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   84.85          return xen_api_success(dom.state)
   84.86      
   84.87 -    def vm_get_resident_on(self, session, vm_ref):
   84.88 +    def VM_get_resident_on(self, session, vm_ref):
   84.89          return xen_api_success(XendNode.instance().uuid)
   84.90      
   84.91 -    def vm_get_memory_actual(self, session, vm_ref):
   84.92 +    def VM_get_memory_actual(self, session, vm_ref):
   84.93          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   84.94          return xen_api_todo() # unsupported by xc
   84.95      
   84.96 -    def vm_get_memory_static_max(self, session, vm_ref):
   84.97 +    def VM_get_memory_static_max(self, session, vm_ref):
   84.98          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   84.99          return xen_api_success(dom.get_memory_static_max())
  84.100      
  84.101 -    def vm_get_memory_static_min(self, session, vm_ref):
  84.102 +    def VM_get_memory_static_min(self, session, vm_ref):
  84.103          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.104          return xen_api_success(dom.get_memory_static_min())
  84.105      
  84.106 -    def vm_get_VCPUs_number(self, session, vm_ref):
  84.107 +    def VM_get_VCPUs_number(self, session, vm_ref):
  84.108          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.109          return xen_api_success(dom.getVCpuCount())
  84.110      
  84.111 -    def vm_get_VCPUs_utilisation(self, session, vm_ref):
  84.112 +    def VM_get_VCPUs_utilisation(self, session, vm_ref):
  84.113          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.114          return xen_api_success(dom.get_vcpus_util())
  84.115      
  84.116 -    def vm_get_VCPUs_features_required(self, session, vm_ref):
  84.117 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.118 -        return xen_api_todo() # unsupported by xc
  84.119 -    
  84.120 -    def vm_get_VCPUs_can_use(self, session, vm_ref):
  84.121 +    def VM_get_VCPUs_features_required(self, session, vm_ref):
  84.122          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.123          return xen_api_todo() # unsupported by xc
  84.124      
  84.125 -    def vm_get_VIFs(self, session, vm_ref):
  84.126 +    def VM_get_VCPUs_can_use(self, session, vm_ref):
  84.127 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.128 +        return xen_api_todo() # unsupported by xc
  84.129 +    
  84.130 +    def VM_get_VIFs(self, session, vm_ref):
  84.131          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.132          return xen_api_success(dom.get_vifs())
  84.133      
  84.134 -    def vm_get_VBDs(self, session, vm_ref):
  84.135 +    def VM_get_VBDs(self, session, vm_ref):
  84.136          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.137          return xen_api_success(dom.get_vbds())
  84.138      
  84.139 -    def vm_get_VTPMs(self, session, vm_ref):
  84.140 +    def VM_get_VTPMs(self, session, vm_ref):
  84.141          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.142          return xen_api_success(dom.get_vtpms())
  84.143      
  84.144 -    def vm_get_PCI_bus(self, session, vm_ref):
  84.145 +    def VM_get_PCI_bus(self, session, vm_ref):
  84.146          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.147          return xen_api_todo() # unsupported by xc
  84.148      
  84.149 -    def vm_get_tools_version(self, session, vm_ref):
  84.150 +    def VM_get_tools_version(self, session, vm_ref):
  84.151          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.152          return xen_api_todo()
  84.153  
  84.154      # attributes (rw)
  84.155 -    def vm_get_name_label(self, session, vm_ref):
  84.156 +    def VM_get_name_label(self, session, vm_ref):
  84.157          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.158          return xen_api_success(dom.getName())
  84.159      
  84.160 -    def vm_get_name_description(self, session, vm_ref):
  84.161 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.162 -        return xen_api_todo()
  84.163 -    
  84.164 -    def vm_get_user_version(self, session, vm_ref):
  84.165 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.166 -        return xen_api_todo()
  84.167 -    
  84.168 -    def vm_get_is_a_template(self, session, vm_ref):
  84.169 +    def VM_get_name_description(self, session, vm_ref):
  84.170          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.171          return xen_api_todo()
  84.172      
  84.173 -    def vm_get_memory_dynamic_max(self, session, vm_ref):
  84.174 +    def VM_get_user_version(self, session, vm_ref):
  84.175          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.176          return xen_api_todo()
  84.177 -
  84.178 -    def vm_get_memory_dynamic_min(self, session, vm_ref):
  84.179 +    
  84.180 +    def VM_get_is_a_template(self, session, vm_ref):
  84.181          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.182 -        return xen_api_todo()    
  84.183 +        return xen_api_todo()
  84.184      
  84.185 -    def vm_get_VCPUs_policy(self, session, vm_ref):
  84.186 +    def VM_get_memory_dynamic_max(self, session, vm_ref):
  84.187 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.188 +        return xen_api_success(dom.get_memory_dynamic_max())
  84.189 +
  84.190 +    def VM_get_memory_dynamic_min(self, session, vm_ref):
  84.191 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.192 +        return xen_api_success(dom.get_memory_dynamic_min())        
  84.193 +    
  84.194 +    def VM_get_VCPUs_policy(self, session, vm_ref):
  84.195          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.196          return xen_api_todo() # need to access scheduler
  84.197      
  84.198 -    def vm_get_VCPUs_params(self, session, vm_ref):
  84.199 +    def VM_get_VCPUs_params(self, session, vm_ref):
  84.200          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.201          return xen_api_todo() # need access to scheduler
  84.202      
  84.203 -    def vm_get_VCPUs_features_force_on(self, session, vm_ref):
  84.204 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.205 -        return xen_api_todo()
  84.206 -    
  84.207 -    def vm_get_VCPUs_features_force_off(self, session, vm_ref):
  84.208 +    def VM_get_VCPUs_features_force_on(self, session, vm_ref):
  84.209          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.210          return xen_api_todo()
  84.211      
  84.212 -    def vm_get_actions_after_shutdown(self, session, vm_ref):
  84.213 +    def VM_get_VCPUs_features_force_off(self, session, vm_ref):
  84.214 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.215 +        return xen_api_todo()
  84.216 +    
  84.217 +    def VM_get_actions_after_shutdown(self, session, vm_ref):
  84.218          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.219          return xen_api_success(dom.get_on_shutdown())
  84.220      
  84.221 -    def vm_get_actions_after_reboot(self, session, vm_ref):
  84.222 +    def VM_get_actions_after_reboot(self, session, vm_ref):
  84.223          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.224          return xen_api_success(dom.get_on_reboot())
  84.225      
  84.226 -    def vm_get_actions_after_suspend(self, session, vm_ref):
  84.227 +    def VM_get_actions_after_suspend(self, session, vm_ref):
  84.228          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.229          return xen_api_success(dom.get_on_suspend())
  84.230      
  84.231 -    def vm_get_actions_after_crash(self, session, vm_ref):
  84.232 +    def VM_get_actions_after_crash(self, session, vm_ref):
  84.233          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.234          return xen_api_success(dom.get_on_crash())
  84.235      
  84.236 -    def vm_get_bios_boot(self, session, vm_ref):
  84.237 +    def VM_get_bios_boot(self, session, vm_ref):
  84.238          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.239          return xen_api_success(dom.get_bios_boot())
  84.240      
  84.241 -    def vm_get_platform_std_VGA(self, session, vm_ref):
  84.242 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.243 -        return xen_api_todo()
  84.244 -    
  84.245 -    def vm_get_platform_serial(self, session, vm_ref):
  84.246 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.247 -        return xen_api_todo()
  84.248 -    
  84.249 -    def vm_get_platform_localtime(self, session, vm_ref):
  84.250 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.251 -        return xen_api_todo()
  84.252 -    
  84.253 -    def vm_get_platform_clock_offset(self, session, vm_ref):
  84.254 +    def VM_get_platform_std_VGA(self, session, vm_ref):
  84.255          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.256          return xen_api_todo()
  84.257      
  84.258 -    def vm_get_platform_enable_audio(self, session, vm_ref):
  84.259 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.260 -        return xen_api_todo()
  84.261 -    
  84.262 -    def vm_get_platform_keymap(self, session, vm_ref):
  84.263 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.264 -        return xen_api_todo()
  84.265 -    
  84.266 -    def vm_get_builder(self, session, vm_ref):
  84.267 +    def VM_get_platform_serial(self, session, vm_ref):
  84.268          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.269          return xen_api_todo()
  84.270      
  84.271 -    def vm_get_boot_method(self, session, vm_ref):
  84.272 +    def VM_get_platform_localtime(self, session, vm_ref):
  84.273          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.274 -        return xen_api_success('')
  84.275 -    
  84.276 -    def vm_get_kernel_kernel(self, session, vm_ref):
  84.277 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.278 -        return xen_api_success('')
  84.279 +        return xen_api_todo()
  84.280      
  84.281 -    def vm_get_kernel_initrd(self, session, vm_ref):
  84.282 +    def VM_get_platform_clock_offset(self, session, vm_ref):
  84.283          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.284 -        return xen_api_success('')
  84.285 +        return xen_api_todo()
  84.286      
  84.287 -    def vm_get_kernel_args(self, session, vm_ref):
  84.288 +    def VM_get_platform_enable_audio(self, session, vm_ref):
  84.289          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.290 -        return xen_api_success('')
  84.291 +        return xen_api_todo()
  84.292      
  84.293 -    def vm_get_grub_cmdline(self, session, vm_ref):
  84.294 +    def VM_get_platform_keymap(self, session, vm_ref):
  84.295 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.296 +        return xen_api_todo()
  84.297 +    
  84.298 +    def VM_get_builder(self, session, vm_ref):
  84.299 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.300 +        return xen_api_success(dom.get_builder())
  84.301 +    
  84.302 +    def VM_get_boot_method(self, session, vm_ref):
  84.303 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.304 +        return xen_api_success(dom.get_boot_method())
  84.305 +    
  84.306 +    def VM_get_kernel_kernel(self, session, vm_ref):
  84.307          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.308          return xen_api_success('')
  84.309      
  84.310 -    def vm_get_otherConfig(self, session, vm_ref):
  84.311 +    def VM_get_kernel_initrd(self, session, vm_ref):
  84.312 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.313 +        return xen_api_success('')
  84.314 +    
  84.315 +    def VM_get_kernel_args(self, session, vm_ref):
  84.316 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.317 +        return xen_api_success('')
  84.318 +    
  84.319 +    def VM_get_grub_cmdline(self, session, vm_ref):
  84.320 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.321 +        return xen_api_success('')
  84.322 +    
  84.323 +    def VM_get_otherConfig(self, session, vm_ref):
  84.324          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.325          return xen_api_todo()
  84.326      
  84.327 -    def vm_set_name_label(self, session, vm_ref):
  84.328 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.329 -        return xen_api_success_void()
  84.330 -    
  84.331 -    def vm_set_name_description(self, session, vm_ref):
  84.332 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.333 -        return xen_api_success_void()
  84.334 -    
  84.335 -    def vm_set_user_version(self, session, vm_ref):
  84.336 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.337 -        return xen_api_success_void()
  84.338 -    
  84.339 -    def vm_set_is_a_template(self, session, vm_ref):
  84.340 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.341 -        return xen_api_success_void()
  84.342 -    
  84.343 -    def vm_set_memory_dynamic_max(self, session, vm_ref):
  84.344 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.345 -        return xen_api_success_void()
  84.346 -    
  84.347 -    def vm_set_memory_dynamic_min(self, session, vm_ref):
  84.348 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.349 -        return xen_api_success_void()
  84.350 -    
  84.351 -    def vm_set_VCPUs_policy(self, session, vm_ref):
  84.352 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.353 -        return xen_api_success_void()
  84.354 -    
  84.355 -    def vm_set_VCPUs_params(self, session, vm_ref):
  84.356 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.357 -        return xen_api_success_void()
  84.358 -    
  84.359 -    def vm_set_VCPUs_features_force_on(self, session, vm_ref):
  84.360 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.361 -        return xen_api_success_void()
  84.362 -    
  84.363 -    def vm_set_VCPUs_features_force_off(self, session, vm_ref):
  84.364 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.365 -        return xen_api_success_void()
  84.366 -    
  84.367 -    def vm_set_actions_after_shutdown(self, session, vm_ref):
  84.368 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.369 -        return xen_api_success_void()
  84.370 -    
  84.371 -    def vm_set_actions_after_reboot(self, session, vm_ref):
  84.372 +    def VM_set_name_label(self, session, vm_ref):
  84.373          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.374          return xen_api_success_void()
  84.375      
  84.376 -    def vm_set_actions_after_suspend(self, session, vm_ref):
  84.377 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.378 -        return xen_api_success_void()
  84.379 -    
  84.380 -    def vm_set_actions_after_crash(self, session, vm_ref):
  84.381 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.382 -        return xen_api_success_void()
  84.383 -    
  84.384 -    def vm_set_bios_boot(self, session, vm_ref):
  84.385 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.386 -        return xen_api_success_void()
  84.387 -    
  84.388 -    def vm_set_platform_std_VGA(self, session, vm_ref):
  84.389 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.390 -        return xen_api_success_void()
  84.391 -    
  84.392 -    def vm_set_platform_serial(self, session, vm_ref):
  84.393 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.394 -        return xen_api_success_void()
  84.395 -    
  84.396 -    def vm_set_platform_localtime(self, session, vm_ref):
  84.397 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.398 -        return xen_api_success_void()
  84.399 -    
  84.400 -    def vm_set_platform_clock_offset(self, session, vm_ref):
  84.401 +    def VM_set_name_description(self, session, vm_ref):
  84.402          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.403          return xen_api_success_void()
  84.404      
  84.405 -    def vm_set_platform_enable_audio(self, session, vm_ref):
  84.406 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.407 -        return xen_api_success_void()
  84.408 -    
  84.409 -    def vm_set_builder(self, session, vm_ref):
  84.410 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.411 -        return xen_api_success_void()
  84.412 -    
  84.413 -    def vm_set_boot_method(self, session, vm_ref):
  84.414 +    def VM_set_user_version(self, session, vm_ref):
  84.415          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.416          return xen_api_success_void()
  84.417      
  84.418 -    def vm_set_kernel_kernel(self, session, vm_ref):
  84.419 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.420 -        return xen_api_success_void()
  84.421 -    
  84.422 -    def vm_set_kernel_initrd(self, session, vm_ref):
  84.423 +    def VM_set_is_a_template(self, session, vm_ref):
  84.424          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.425          return xen_api_success_void()
  84.426      
  84.427 -    def vm_set_kernel_args(self, session, vm_ref):
  84.428 +    def VM_set_memory_dynamic_max(self, session, vm_ref):
  84.429          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.430          return xen_api_success_void()
  84.431      
  84.432 -    def vm_set_grub_cmdline(self, session, vm_ref):
  84.433 +    def VM_set_memory_dynamic_min(self, session, vm_ref):
  84.434          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.435          return xen_api_success_void()
  84.436      
  84.437 -    def vm_set_otherConfig(self, session, vm_ref):
  84.438 +    def VM_set_VCPUs_policy(self, session, vm_ref):
  84.439 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.440 +        return xen_api_success_void()
  84.441 +    
  84.442 +    def VM_set_VCPUs_params(self, session, vm_ref):
  84.443 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.444 +        return xen_api_success_void()
  84.445 +    
  84.446 +    def VM_set_VCPUs_features_force_on(self, session, vm_ref):
  84.447 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.448 +        return xen_api_success_void()
  84.449 +    
  84.450 +    def VM_set_VCPUs_features_force_off(self, session, vm_ref):
  84.451 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.452 +        return xen_api_success_void()
  84.453 +    
  84.454 +    def VM_set_actions_after_shutdown(self, session, vm_ref):
  84.455 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.456 +        return xen_api_success_void()
  84.457 +    
  84.458 +    def VM_set_actions_after_reboot(self, session, vm_ref):
  84.459 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.460 +        return xen_api_success_void()
  84.461 +    
  84.462 +    def VM_set_actions_after_suspend(self, session, vm_ref):
  84.463 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.464 +        return xen_api_success_void()
  84.465 +    
  84.466 +    def VM_set_actions_after_crash(self, session, vm_ref):
  84.467 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.468 +        return xen_api_success_void()
  84.469 +    
  84.470 +    def VM_set_bios_boot(self, session, vm_ref):
  84.471 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.472 +        return xen_api_success_void()
  84.473 +    
  84.474 +    def VM_set_platform_std_VGA(self, session, vm_ref):
  84.475 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.476 +        return xen_api_success_void()
  84.477 +    
  84.478 +    def VM_set_platform_serial(self, session, vm_ref):
  84.479 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.480 +        return xen_api_success_void()
  84.481 +    
  84.482 +    def VM_set_platform_localtime(self, session, vm_ref):
  84.483 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.484 +        return xen_api_success_void()
  84.485 +    
  84.486 +    def VM_set_platform_clock_offset(self, session, vm_ref):
  84.487 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.488 +        return xen_api_success_void()
  84.489 +    
  84.490 +    def VM_set_platform_enable_audio(self, session, vm_ref):
  84.491 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.492 +        return xen_api_success_void()
  84.493 +    
  84.494 +    def VM_set_builder(self, session, vm_ref):
  84.495 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.496 +        return xen_api_success_void()
  84.497 +    
  84.498 +    def VM_set_boot_method(self, session, vm_ref):
  84.499 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.500 +        return xen_api_success_void()
  84.501 +    
  84.502 +    def VM_set_kernel_kernel(self, session, vm_ref):
  84.503 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.504 +        return xen_api_success_void()
  84.505 +    
  84.506 +    def VM_set_kernel_initrd(self, session, vm_ref):
  84.507 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.508 +        return xen_api_success_void()
  84.509 +    
  84.510 +    def VM_set_kernel_args(self, session, vm_ref):
  84.511 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.512 +        return xen_api_success_void()
  84.513 +    
  84.514 +    def VM_set_grub_cmdline(self, session, vm_ref):
  84.515 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.516 +        return xen_api_success_void()
  84.517 +    
  84.518 +    def VM_set_otherConfig(self, session, vm_ref):
  84.519          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  84.520          return xen_api_success_void()
  84.521      
  84.522      # class methods
  84.523 -    def vm_get_all(self, session):
  84.524 -        refs = [d.get_uuid() for d in XendDomain.instance().list()]
  84.525 +    def VM_get_all(self, session):
  84.526 +        refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
  84.527          return xen_api_success(refs)
  84.528      
  84.529 -    def vm_get_by_name_label(self, session, label):
  84.530 +    def VM_get_by_name_label(self, session, label):
  84.531          xendom = XendDomain.instance()
  84.532          dom = xendom.domain_lookup_nr(label)
  84.533          if dom:
  84.534              return xen_api_success([dom.get_uuid()])
  84.535          return xen_api_error(XEND_ERROR_VM_INVALID)
  84.536      
  84.537 -    def vm_create(self, session, vm_struct):
  84.538 +    def VM_create(self, session, vm_struct):
  84.539          xendom = XendDomain.instance()
  84.540          domuuid = xendom.create_domain(vm_struct)
  84.541          return xen_api_success(domuuid)
  84.542      
  84.543      # object methods
  84.544 -    def vm_to_XML(self, session, vm_ref):
  84.545 -        return xen_api_todo()
  84.546 -    
  84.547 -    def vm_get_record(self, session, vm_ref):
  84.548 +    def VM_get_record(self, session, vm_ref):
  84.549          xendom = XendDomain.instance()
  84.550          xeninfo = xendom.get_vm_by_uuid(vm_ref)
  84.551          if not xeninfo:
  84.552 @@ -969,17 +963,17 @@ class XendAPI:
  84.553              'resident_on': XendNode.instance().uuid,
  84.554              'memory_static_min': xeninfo.get_memory_static_min(),
  84.555              'memory_static_max': xeninfo.get_memory_static_max(),
  84.556 -            'memory_dynamic_min': xeninfo.get_memory_static_min(),
  84.557 -            'memory_dynamic_max': xeninfo.get_memory_static_max(),
  84.558 +            'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
  84.559 +            'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
  84.560              'memory_actual': xeninfo.get_memory_static_min(),
  84.561 -            'vcpus_policy': xeninfo.get_vcpus_policy(),
  84.562 -            'vcpus_params': xeninfo.get_vcpus_params(),
  84.563 -            'vcpus_number': xeninfo.getVCpuCount(),
  84.564 -            'vcpus_utilisation': xeninfo.get_vcpus_util(),
  84.565 -            'vcpus_features_required': [],
  84.566 -            'vcpus_features_can_use': [],
  84.567 -            'vcpus_features_force_on': [],
  84.568 -            'vcpus_features_force_off': [],
  84.569 +            'VCPUs_policy': xeninfo.get_vcpus_policy(),
  84.570 +            'VCPUs_params': xeninfo.get_vcpus_params(),
  84.571 +            'VCPUs_number': xeninfo.getVCpuCount(),
  84.572 +            'VCPUs_utilisation': xeninfo.get_vcpus_util(),
  84.573 +            'VCPUs_features_required': [],
  84.574 +            'VCPUs_features_can_use': [],
  84.575 +            'VCPUs_features_force_on': [],
  84.576 +            'VCPUs_features_force_off': [],
  84.577              'actions_after_shutdown': xeninfo.get_on_shutdown(),
  84.578              'actions_after_reboot': xeninfo.get_on_reboot(),
  84.579              'actions_after_suspend': xeninfo.get_on_suspend(),
  84.580 @@ -1006,41 +1000,39 @@ class XendAPI:
  84.581          }
  84.582          return xen_api_success(record)
  84.583  
  84.584 -    def vm_clean_reboot(self, session, vm_ref):
  84.585 +    def VM_clean_reboot(self, session, vm_ref):
  84.586          xendom = XendDomain.instance()
  84.587          xeninfo = xendom.get_vm_by_uuid(vm_ref)
  84.588          xeninfo.shutdown("reboot")
  84.589          return xen_api_success_void()
  84.590 -    def vm_clean_shutdown(self, session, vm_ref):
  84.591 +    def VM_clean_shutdown(self, session, vm_ref):
  84.592          xendom = XendDomain.instance()
  84.593          xeninfo = xendom.get_vm_by_uuid(vm_ref)
  84.594          xeninfo.shutdown("poweroff")
  84.595          return xen_api_success_void()
  84.596 -    def vm_clone(self, session, vm_ref):
  84.597 +    def VM_clone(self, session, vm_ref):
  84.598          return xen_api_error(XEND_ERROR_UNSUPPORTED)
  84.599 -    def vm_destroy(self, session, vm_ref):
  84.600 +    def VM_destroy(self, session, vm_ref):
  84.601          return do_vm_func("domain_delete", vm_ref)
  84.602 -    def vm_hard_reboot(self, session, vm_ref):
  84.603 +    def VM_hard_reboot(self, session, vm_ref):
  84.604          return xen_api_error(XEND_ERROR_UNSUPPORTED)    
  84.605 -    def vm_hard_shutdown(self, session, vm_ref):
  84.606 +    def VM_hard_shutdown(self, session, vm_ref):
  84.607          return do_vm_func("domain_destroy", vm_ref)    
  84.608 -    def vm_pause(self, session, vm_ref):
  84.609 +    def VM_pause(self, session, vm_ref):
  84.610          return do_vm_func("domain_pause", vm_ref)
  84.611 -    def vm_resume(self, session, vm_ref, start_paused):
  84.612 +    def VM_resume(self, session, vm_ref, start_paused):
  84.613          return do_vm_func("domain_resume", vm_ref, start_paused = start_paused)    
  84.614 -    def vm_start(self, session, vm_ref, start_paused):
  84.615 +    def VM_start(self, session, vm_ref, start_paused):
  84.616          return do_vm_func("domain_start", vm_ref, start_paused = start_paused)
  84.617 -    def vm_suspend(self, session, vm_ref):
  84.618 +    def VM_suspend(self, session, vm_ref):
  84.619          return do_vm_func("domain_suspend", vm_ref)    
  84.620 -    def vm_unpause(self, session, vm_ref):
  84.621 +    def VM_unpause(self, session, vm_ref):
  84.622          return do_vm_func("domain_unpause", vm_ref)
  84.623  
  84.624 -    # Xen API: Class VDI
  84.625 -    # ----------------------------------------------------------------
  84.626 -    # TODO: NOT IMPLEMENTED.
  84.627 -
  84.628      # Xen API: Class VBD
  84.629      # ----------------------------------------------------------------
  84.630 +    # Note: accepts a non-API standard 'image' attribute to emulate
  84.631 +    #       regular xm created VBDs
  84.632  
  84.633      VBD_attr_ro = ['image',
  84.634                     'IO_bandwidth_incoming_kbs',
  84.635 @@ -1053,8 +1045,10 @@ class XendAPI:
  84.636  
  84.637      VBD_attr_inst = VBD_attr_rw + ['image']
  84.638  
  84.639 +    VBD_methods = ['media_change']
  84.640 +
  84.641      # object methods
  84.642 -    def vbd_get_record(self, session, vbd_ref):
  84.643 +    def VBD_get_record(self, session, vbd_ref):
  84.644          xendom = XendDomain.instance()
  84.645          vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
  84.646          if not vm:
  84.647 @@ -1063,9 +1057,12 @@ class XendAPI:
  84.648          if not cfg:
  84.649              return xen_api_error(XEND_ERROR_VBD_INVALID)
  84.650          return xen_api_success(cfg)
  84.651 -    
  84.652 +
  84.653 +    def VBD_media_change(self, session, vbd_ref, vdi_ref):
  84.654 +        return xen_api_error(XEND_ERROR_UNSUPPORTED)
  84.655 +
  84.656      # class methods
  84.657 -    def vbd_create(self, session, vbd_struct):
  84.658 +    def VBD_create(self, session, vbd_struct):
  84.659          xendom = XendDomain.instance()
  84.660          if not xendom.is_valid_vm(vbd_struct['VM']):
  84.661              return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
  84.662 @@ -1092,22 +1089,22 @@ class XendAPI:
  84.663          return xen_api_success(vbd_ref)
  84.664  
  84.665      # attributes (rw)
  84.666 -    def vbd_get_VM(self, session, vbd_ref):
  84.667 +    def VBD_get_VM(self, session, vbd_ref):
  84.668          xendom = XendDomain.instance()
  84.669          return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
  84.670      
  84.671 -    def vbd_get_VDI(self, session, vbd_ref):
  84.672 +    def VBD_get_VDI(self, session, vbd_ref):
  84.673          return xen_api_todo()
  84.674      
  84.675 -    def vbd_get_device(self, session, vbd_ref):
  84.676 +    def VBD_get_device(self, session, vbd_ref):
  84.677          xendom = XendDomain.instance()
  84.678          return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
  84.679                                                        'device'))
  84.680 -    def vbd_get_mode(self, session, vbd_ref):
  84.681 +    def VBD_get_mode(self, session, vbd_ref):
  84.682          xendom = XendDomain.instance()
  84.683          return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
  84.684                                                        'mode'))
  84.685 -    def vbd_get_driver(self, session, vbd_ref):
  84.686 +    def VBD_get_driver(self, session, vbd_ref):
  84.687          xendom = XendDomain.instance()
  84.688          return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
  84.689                                                        'driver'))
  84.690 @@ -1130,7 +1127,7 @@ class XendAPI:
  84.691      VIF_attr_inst = VIF_attr_rw
  84.692  
  84.693      # object methods
  84.694 -    def vif_get_record(self, session, vif_ref):
  84.695 +    def VIF_get_record(self, session, vif_ref):
  84.696          xendom = XendDomain.instance()
  84.697          vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
  84.698          if not vm:
  84.699 @@ -1147,7 +1144,7 @@ class XendAPI:
  84.700          return xen_api_success(cfg)
  84.701  
  84.702      # class methods
  84.703 -    def vif_create(self, session, vif_struct):
  84.704 +    def VIF_create(self, session, vif_struct):
  84.705          xendom = XendDomain.instance()
  84.706          if xendom.is_valid_vm(vif_struct['VM']):
  84.707              dom = xendom.get_vm_by_uuid(vif_struct['VM'])
  84.708 @@ -1180,99 +1177,96 @@ class XendAPI:
  84.709      VDI_methods = ['snapshot']
  84.710      VDI_funcs = ['get_by_name_label']
  84.711      
  84.712 -    def vdi_get_VBDs(self, session, vdi_ref):
  84.713 +    def VDI_get_VBDs(self, session, vdi_ref):
  84.714          return xen_api_todo()
  84.715      
  84.716 -    def vdi_get_physical_utilisation(self, session, vdi_ref):
  84.717 +    def VDI_get_physical_utilisation(self, session, vdi_ref):
  84.718          sr = XendNode.instance().get_sr()
  84.719          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.720          return xen_api_success(image.get_physical_utilisation())        
  84.721      
  84.722 -    def vdi_get_sector_size(self, session, vdi_ref):
  84.723 +    def VDI_get_sector_size(self, session, vdi_ref):
  84.724          sr = XendNode.instance().get_sr()
  84.725          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.726          return xen_api_success(image.sector_size)        
  84.727      
  84.728 -    def vdi_get_type(self, session, vdi_ref):
  84.729 +    def VDI_get_type(self, session, vdi_ref):
  84.730          sr = XendNode.instance().get_sr()
  84.731          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.732          return xen_api_success(image.type)
  84.733      
  84.734 -    def vdi_get_parent(self, session, vdi_ref):
  84.735 +    def VDI_get_parent(self, session, vdi_ref):
  84.736          sr = XendNode.instance().get_sr()
  84.737          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.738          return xen_api_success(image.parent)        
  84.739      
  84.740 -    def vdi_get_children(self, session, vdi_ref):
  84.741 +    def VDI_get_children(self, session, vdi_ref):
  84.742          sr = XendNode.instance().get_sr()
  84.743          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.744          return xen_api_success(image.children)        
  84.745      
  84.746 -    def vdi_get_name_label(self, session, vdi_ref):
  84.747 +    def VDI_get_name_label(self, session, vdi_ref):
  84.748          sr = XendNode.instance().get_sr()
  84.749          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.750          return xen_api_success(image.name_label)
  84.751  
  84.752 -    def vdi_get_name_description(self, session, vdi_ref):
  84.753 +    def VDI_get_name_description(self, session, vdi_ref):
  84.754          sr = XendNode.instance().get_sr()
  84.755          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.756          return xen_api_success(image.name_description)
  84.757  
  84.758 -    def vdi_get_SR(self, session, vdi_ref):
  84.759 +    def VDI_get_SR(self, session, vdi_ref):
  84.760          sr = XendNode.instance().get_sr()
  84.761          return xen_api_success(sr.uuid)
  84.762  
  84.763 -    def vdi_get_virtual_size(self, session, vdi_ref):
  84.764 +    def VDI_get_virtual_size(self, session, vdi_ref):
  84.765          sr = XendNode.instance().get_sr()
  84.766          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.767          return xen_api_success(image.virtual_size)
  84.768  
  84.769 -    def vdi_get_sharable(self, session, vdi_ref):
  84.770 +    def VDI_get_sharable(self, session, vdi_ref):
  84.771          sr = XendNode.instance().get_sr()
  84.772          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.773          return xen_api_success(image.sharable)
  84.774  
  84.775 -    def vdi_get_read_only(self, session, vdi_ref):
  84.776 +    def VDI_get_read_only(self, session, vdi_ref):
  84.777          sr = XendNode.instance().get_sr()
  84.778          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.779          return xen_api_success(image.sharable)        
  84.780  
  84.781 -    def vdi_set_name_label(self, session, vdi_ref, value):
  84.782 +    def VDI_set_name_label(self, session, vdi_ref, value):
  84.783          sr = XendNode.instance().get_sr()
  84.784          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.785          image.name_label = value
  84.786          return xen_api_success_void()
  84.787  
  84.788 -    def vdi_set_name_description(self, session, vdi_ref, value):
  84.789 +    def VDI_set_name_description(self, session, vdi_ref, value):
  84.790          sr = XendNode.instance().get_sr()
  84.791          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.792          image.name_description = value
  84.793          return xen_api_success_void()
  84.794  
  84.795 -    def vdi_set_SR(self, session, vdi_ref, value):
  84.796 +    def VDI_set_SR(self, session, vdi_ref, value):
  84.797          return xen_api_error(XEND_ERROR_UNSUPPORTED)
  84.798  
  84.799 -    def vdi_set_virtual_size(self, session, vdi_ref, value):
  84.800 +    def VDI_set_virtual_size(self, session, vdi_ref, value):
  84.801          return xen_api_error(XEND_ERROR_UNSUPPORTED)
  84.802  
  84.803 -    def vdi_set_sharable(self, session, vdi_ref, value):
  84.804 +    def VDI_set_sharable(self, session, vdi_ref, value):
  84.805          return xen_api_todo()
  84.806 -    def vdi_set_read_only(self, session, vdi_ref, value):
  84.807 +    def VDI_set_read_only(self, session, vdi_ref, value):
  84.808          return xen_api_todo()
  84.809  
  84.810      # Object Methods
  84.811 -    def vdi_snapshot(self, session, vdi_ref):
  84.812 +    def VDI_snapshot(self, session, vdi_ref):
  84.813          return xen_api_todo()
  84.814      
  84.815 -    def vdi_destroy(self, session, vdi_ref):
  84.816 +    def VDI_destroy(self, session, vdi_ref):
  84.817          sr = XendNode.instance().get_sr()
  84.818          sr.destroy_image(vdi_ref)
  84.819          return xen_api_success_void()
  84.820  
  84.821 -    def vdi_to_XML(self, session, vdi_ref):
  84.822 -        return xen_api_todo()
  84.823 -    
  84.824 -    def vdi_get_record(self, session, vdi_ref):
  84.825 +    def VDI_get_record(self, session, vdi_ref):
  84.826          sr = XendNode.instance().get_sr()
  84.827          image = sr.xen_api_get_by_uuid(vdi_ref)
  84.828          if image:
  84.829 @@ -1295,7 +1289,7 @@ class XendAPI:
  84.830          return xen_api_error(XEND_ERROR_VDI_INVALID)
  84.831  
  84.832      # Class Functions    
  84.833 -    def vdi_create(self, session, vdi_struct):
  84.834 +    def VDI_create(self, session, vdi_struct):
  84.835          sr = XendNode.instance().get_sr()
  84.836          sr_ref = vdi_struct['SR']
  84.837          if sr.uuid != sr_ref:
  84.838 @@ -1304,11 +1298,11 @@ class XendAPI:
  84.839          vdi_uuid = sr.create_image(vdi_struct)
  84.840          return xen_api_success(vdi_uuid)
  84.841  
  84.842 -    def vdi_get_all(self, session):
  84.843 +    def VDI_get_all(self, session):
  84.844          sr = XendNode.instance().get_sr()
  84.845          return xen_api_success(sr.list_images())
  84.846      
  84.847 -    def vdi_get_by_name_label(self, session, name):
  84.848 +    def VDI_get_by_name_label(self, session, name):
  84.849          sr = XendNode.instance().get_sr()
  84.850          image_uuid = sr.xen_api_get_by_name_label(name)
  84.851          if image_uuid:
  84.852 @@ -1329,7 +1323,7 @@ class XendAPI:
  84.853      VTPM_attr_inst = VTPM_attr_rw
  84.854  
  84.855      # object methods
  84.856 -    def vtpm_get_record(self, session, vtpm_ref):
  84.857 +    def VTPM_get_record(self, session, vtpm_ref):
  84.858          xendom = XendDomain.instance()
  84.859          vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
  84.860          if not vm:
  84.861 @@ -1346,7 +1340,7 @@ class XendAPI:
  84.862          return xen_api_success(cfg)
  84.863  
  84.864      # Class Functions
  84.865 -    def vtpm_get_instance(self, session, vtpm_ref):
  84.866 +    def VTPM_get_instance(self, session, vtpm_ref):
  84.867          xendom = XendDomain.instance()
  84.868          vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
  84.869          if not vm:
  84.870 @@ -1360,7 +1354,7 @@ class XendAPI:
  84.871              instance = -1
  84.872          return xen_api_success(instance)
  84.873  
  84.874 -    def vtpm_get_driver(self, session, vtpm_ref):
  84.875 +    def VTPM_get_driver(self, session, vtpm_ref):
  84.876          xendom = XendDomain.instance()
  84.877          vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
  84.878          if not vm:
  84.879 @@ -1374,7 +1368,7 @@ class XendAPI:
  84.880              driver = "Unknown"
  84.881          return xen_api_success(driver)
  84.882  
  84.883 -    def vtpm_get_backend(self, session, vtpm_ref):
  84.884 +    def VTPM_get_backend(self, session, vtpm_ref):
  84.885          xendom = XendDomain.instance()
  84.886          vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
  84.887          if not vm:
  84.888 @@ -1388,12 +1382,12 @@ class XendAPI:
  84.889              backend = "Domain-0"
  84.890          return xen_api_success(backend)
  84.891  
  84.892 -    def vtpm_get_VM(self, session, vtpm_ref):
  84.893 +    def VTPM_get_VM(self, session, vtpm_ref):
  84.894          xendom = XendDomain.instance()
  84.895          return xen_api_success(xendom.get_dev_property('vtpm', vtpm_ref, 'VM'))
  84.896  
  84.897      # class methods
  84.898 -    def vtpm_create(self, session, vtpm_struct):
  84.899 +    def VTPM_create(self, session, vtpm_struct):
  84.900          xendom = XendDomain.instance()
  84.901          if xendom.is_valid_vm(vtpm_struct['VM']):
  84.902              dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
  84.903 @@ -1429,32 +1423,30 @@ class XendAPI:
  84.904      SR_funcs = ['get_by_name_label']
  84.905  
  84.906      # Class Functions
  84.907 -    def sr_get_all(self, session):
  84.908 +    def SR_get_all(self, session):
  84.909          sr = XendNode.instance().get_sr()
  84.910          return xen_api_success([sr.uuid])
  84.911  
  84.912 -    def sr_get_by_name_label(self, session, label):
  84.913 +    def SR_get_by_name_label(self, session, label):
  84.914          sr = XendNode.instance().get_sr()
  84.915          if sr.name_label != label:
  84.916              return xen_api_error(XEND_ERROR_SR_INVALID)
  84.917          return xen_api_success([sr.uuid])
  84.918  
  84.919 -    def sr_create(self, session):
  84.920 +    def SR_create(self, session):
  84.921          return xen_api_error(XEND_ERROR_UNSUPPORTED)
  84.922  
  84.923 -    def sr_get_by_uuid(self, session):
  84.924 +    def SR_get_by_uuid(self, session):
  84.925          return xen_api_success(XendNode.instance().get_sr().uuid)
  84.926  
  84.927      # Class Methods
  84.928 -    def sr_clone(self, session, sr_ref):
  84.929 -        return xen_api_error(XEND_ERROR_UNSUPPORTED)
  84.930 -    def sr_destroy(self, session, sr_ref):
  84.931 +    def SR_clone(self, session, sr_ref):
  84.932          return xen_api_error(XEND_ERROR_UNSUPPORTED)
  84.933      
  84.934 -    def sr_to_XML(self, session, sr_ref):
  84.935 -        return xen_api_todo()
  84.936 +    def SR_destroy(self, session, sr_ref):
  84.937 +        return xen_api_error(XEND_ERROR_UNSUPPORTED)
  84.938      
  84.939 -    def sr_get_record(self, session, sr_ref):
  84.940 +    def SR_get_record(self, session, sr_ref):
  84.941          sr = XendNode.instance().get_sr()
  84.942          return xen_api_success({
  84.943              'uuid': sr.uuid,
  84.944 @@ -1469,44 +1461,44 @@ class XendAPI:
  84.945              })
  84.946  
  84.947      # Attribute acceess
  84.948 -    def sr_get_VDIs(self, session, sr_ref):
  84.949 +    def SR_get_VDIs(self, session, sr_ref):
  84.950          sr = XendNode.instance().get_sr()
  84.951          return xen_api_success(sr.list_images())
  84.952  
  84.953 -    def sr_get_virtual_allocation(self, session, sr_ref):
  84.954 +    def SR_get_virtual_allocation(self, session, sr_ref):
  84.955          sr = XendNode.instance().get_sr()        
  84.956          return sr.used_space_bytes()
  84.957  
  84.958 -    def sr_get_physical_utilisation(self, session, sr_ref):
  84.959 +    def SR_get_physical_utilisation(self, session, sr_ref):
  84.960          sr = XendNode.instance().get_sr()        
  84.961          return sr.used_space_bytes()
  84.962  
  84.963 -    def sr_get_physical_size(self, session, sr_ref):
  84.964 +    def SR_get_physical_size(self, session, sr_ref):
  84.965          sr = XendNode.instance().get_sr()        
  84.966          return sr.total_space_bytes()
  84.967      
  84.968 -    def sr_get_type(self, session, sr_ref):
  84.969 +    def SR_get_type(self, session, sr_ref):
  84.970          sr = XendNode.instance().get_sr()
  84.971          return xen_api_success(sr.type)
  84.972  
  84.973 -    def sr_get_location(self, session, sr_ref):
  84.974 +    def SR_get_location(self, session, sr_ref):
  84.975          sr = XendNode.instance().get_sr()
  84.976          return xen_api_success(sr.location)
  84.977  
  84.978 -    def sr_get_name_label(self, session, sr_ref):
  84.979 +    def SR_get_name_label(self, session, sr_ref):
  84.980          sr = XendNode.instance().get_sr()
  84.981          return xen_api_success(sr.name_label)      
  84.982      
  84.983 -    def sr_get_name_description(self, session, sr_ref):
  84.984 +    def SR_get_name_description(self, session, sr_ref):
  84.985          sr = XendNode.instance().get_sr()
  84.986          return xen_api_success(sr.name_description)        
  84.987  
  84.988 -    def sr_set_name_label(self, session, sr_ref, value):
  84.989 +    def SR_set_name_label(self, session, sr_ref, value):
  84.990          sr = XendNode.instance().get_sr()
  84.991          sr.name_label = value
  84.992          return xen_api_success_void()
  84.993      
  84.994 -    def sr_set_name_description(self, session, sr_ref, value):
  84.995 +    def SR_set_name_description(self, session, sr_ref, value):
  84.996          sr = XendNode.instance().get_sr()
  84.997          sr.name_description = value
  84.998          return xen_api_success_void()
  84.999 @@ -1525,24 +1517,24 @@ if __name__ == "__main__":
 84.1000          methods  = getattr(XendAPI, '%s_methods' % cls, [])
 84.1001          funcs    = getattr(XendAPI, '%s_funcs' % cls, [])
 84.1002  
 84.1003 -        ref = '%s_ref' % cls.lower()
 84.1004 +        ref = '%s_ref' % cls
 84.1005  
 84.1006          for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
 84.1007 -            getter_name = '%s_get_%s' % (cls.lower(), attr_name.lower())
 84.1008 +            getter_name = '%s_get_%s' % (cls, attr_name)
 84.1009              output('def %s(self, session, %s):' % (getter_name, ref))
 84.1010              output('    return xen_api_todo()')
 84.1011  
 84.1012          for attr_name in rw_attrs + XendAPI.Base_attr_rw:
 84.1013 -            setter_name = '%s_set_%s' % (cls.lower(), attr_name.lower())
 84.1014 +            setter_name = '%s_set_%s' % (cls, attr_name)
 84.1015              output('def %s(self, session, %s, value):' % (setter_name, ref))
 84.1016              output('    return xen_api_todo()')
 84.1017  
 84.1018          for method_name in methods + XendAPI.Base_methods:
 84.1019 -            method_full_name = '%s_%s' % (cls.lower(),method_name.lower())
 84.1020 +            method_full_name = '%s_%s' % (cls,method_name)
 84.1021              output('def %s(self, session, %s):' % (method_full_name, ref))
 84.1022              output('    return xen_api_todo()')
 84.1023  
 84.1024          for func_name in funcs + XendAPI.Base_funcs:
 84.1025 -            func_full_name = '%s_%s' % (cls.lower(), func_name.lower())
 84.1026 +            func_full_name = '%s_%s' % (cls, func_name)
 84.1027              output('def %s(self, session):' % func_full_name)
 84.1028              output('    return xen_api_todo()')
    85.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Sat Dec 02 15:19:50 2006 -0700
    85.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Mon Dec 04 08:24:41 2006 -0700
    85.3 @@ -18,8 +18,8 @@ import xen.lowlevel.xc
    85.4  from xen.xend import balloon, sxp
    85.5  from xen.xend.XendError import XendError, VmError
    85.6  from xen.xend.XendLogging import log
    85.7 +from xen.xend.XendConfig import XendConfig
    85.8  from xen.xend.XendConstants import *
    85.9 -from xen.xend.XendConfig import XendConfig
   85.10  
   85.11  SIGNATURE = "LinuxGuestRecord"
   85.12  XC_SAVE = "xc_save"
   85.13 @@ -137,7 +137,7 @@ def restore(xd, fd, dominfo = None, paus
   85.14      vmconfig = p.get_val()
   85.15  
   85.16      if dominfo:
   85.17 -        dominfo.update(XendConfig(sxp = vmconfig), refresh = False)
   85.18 +        dominfo.update(XendConfig(sxp_obj = vmconfig), refresh = False)
   85.19          dominfo.resume()
   85.20      else:
   85.21          dominfo = xd.restore_(vmconfig)
    86.1 --- a/tools/python/xen/xend/XendConfig.py	Sat Dec 02 15:19:50 2006 -0700
    86.2 +++ b/tools/python/xen/xend/XendConfig.py	Mon Dec 04 08:24:41 2006 -0700
    86.3 @@ -31,143 +31,197 @@ from xen.xend.XendConstants import DOM_S
    86.4  XendConfig API
    86.5  
    86.6    XendConfig will try to mirror as closely the Xen API VM Struct
    86.7 -  providing a backwards compatibility mode for SXP dumping, loading.
    86.8 +  with extra parameters for those options that are not supported.
    86.9  
   86.10  """
   86.11  
   86.12 +def reverse_dict(adict):
   86.13 +    """Return the reverse mapping of a dictionary."""
   86.14 +    return dict([(v, k) for k, v in adict.items()])
   86.15  
   86.16 -LEGACY_CFG_TO_XENAPI_CFG = {
   86.17 +def bool0(v):
   86.18 +    return v != '0' and bool(v)
   86.19 +
   86.20 +# Mapping from XendConfig configuration keys to the old
   86.21 +# legacy configuration keys that map directly.
   86.22 +
   86.23 +XENAPI_CFG_TO_LEGACY_CFG = {
   86.24      'uuid': 'uuid',
   86.25 -    'vcpus': 'vcpus_number',
   86.26 -    'maxmem': 'memory_static_max',
   86.27 -    'memory': 'memory_static_min',
   86.28 -    'name': 'name_label',
   86.29 -    'on_poweroff': 'actions_after_shutdown',            
   86.30 -    'on_reboot': 'actions_after_reboot',
   86.31 -    'on_crash': 'actions_after_crash',
   86.32 -    'bootloader': 'boot_method',
   86.33 -    'kernel_kernel': 'kernel_kernel',
   86.34 -    'kernel_initrd': 'kernel_initrd',
   86.35 -    'kernel_args': 'kernel_args',
   86.36 -    }
   86.37 +    'vcpus_number': 'vcpus',
   86.38 +    'memory_static_min': 'memory',
   86.39 +    'memory_static_max': 'maxmem',
   86.40 +    'name_label': 'name',
   86.41 +    'actions_after_shutdown': 'on_poweroff',
   86.42 +    'actions_after_reboot': 'on_reboot',
   86.43 +    'actions_after_crash': 'on_crash', 
   86.44 +    'platform_localtime': 'localtime',
   86.45 +}
   86.46  
   86.47 -XENAPI_CFG_CUSTOM_TRANSLATE = [
   86.48 -    'vifs',
   86.49 -    'vbds',
   86.50 -    ]
   86.51 +LEGACY_CFG_TO_XENAPI_CFG = reverse_dict(XENAPI_CFG_TO_LEGACY_CFG)
   86.52  
   86.53 +# Mapping from XendConfig configuration keys to the old
   86.54 +# legacy configuration keys that are found in the 'image'
   86.55 +# SXP object.
   86.56  XENAPI_HVM_CFG = {
   86.57 -    'platform_std_vga': 'std-vga',
   86.58 +    'platform_std_vga': 'stdvga',
   86.59      'platform_serial' : 'serial',
   86.60      'platform_localtime': 'localtime',
   86.61      'platform_enable_audio': 'soundhw',
   86.62      'platform_keymap' : 'keymap',
   86.63  }    
   86.64  
   86.65 -XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [
   86.66 -    'name_description',
   86.67 -    'user_version',
   86.68 -    'is_a_template',
   86.69 -    'memory_dynamic_min',
   86.70 -    'memory_dynamic_max',
   86.71 -    'memory_actual',
   86.72 -    'vcpus_policy',
   86.73 -    'vcpus_params',
   86.74 -    'vcpus_features_required',
   86.75 -    'vcpus_features_can_use',
   86.76 -    'vcpus_features_force_on',
   86.77 -    'vcpus_features_force_off',
   86.78 -    'actions_after_suspend',
   86.79 -    'bios_boot',
   86.80 -    'platform_std_vga',
   86.81 -    'platform_serial',
   86.82 -    'platform_localtime',
   86.83 -    'platform_clock_offset',
   86.84 -    'platform_enable_audio',
   86.85 -    'platform_keymap',
   86.86 -    'builder',
   86.87 -    'grub_cmdline',
   86.88 -    'pci_bus',
   86.89 -    'otherconfig'
   86.90 -    ]
   86.91 +# List of XendConfig configuration keys that have no equivalent
   86.92 +# in the old world.
   86.93  
   86.94 +XENAPI_CFG_TYPES = {
   86.95 +    'uuid': str,
   86.96 +    'power_state': str,
   86.97 +    'name_label': str,
   86.98 +    'name_description': str,
   86.99 +    'user_version': str,
  86.100 +    'is_a_template': bool0,
  86.101 +    'resident_on': str,
  86.102 +    'memory_static_min': int,
  86.103 +    'memory_static_max': int,
  86.104 +    'memory_dynamic_min': int,
  86.105 +    'memory_dynamic_max': int,
  86.106 +    'memory_actual': int,
  86.107 +    'vcpus_policy': str,
  86.108 +    'vcpus_params': str,
  86.109 +    'vcpus_number': int,
  86.110 +    'vcpus_features_required': list,
  86.111 +    'vcpus_features_can_use': list,
  86.112 +    'vcpus_features_force_on': list, 
  86.113 +    'vcpus_features_force_off': list,
  86.114 +    'actions_after_shutdown': str,
  86.115 +    'actions_after_reboot': str,
  86.116 +    'actions_after_suspend': str,
  86.117 +    'actions_after_crash': str,
  86.118 +    'tpm_instance': int,
  86.119 +    'tpm_backend': int,    
  86.120 +    'bios_boot': str,
  86.121 +    'platform_std_vga': bool0,
  86.122 +    'platform_serial': str,
  86.123 +    'platform_localtime': bool0,
  86.124 +    'platform_clock_offset': bool0,
  86.125 +    'platform_enable_audio': bool0,
  86.126 +    'platform_keymap': str,
  86.127 +    'boot_method': str,
  86.128 +    'builder': str,
  86.129 +    'kernel_kernel': str,
  86.130 +    'kernel_initrd': str,
  86.131 +    'kernel_args': str,
  86.132 +    'grub_cmdline': str,
  86.133 +    'pci_bus': str,
  86.134 +    'tools_version': dict,
  86.135 +    'otherconfig': dict,
  86.136 +}
  86.137  
  86.138 -# configuration params that need to be converted to ints
  86.139 -# since the XMLRPC transport for Xen API does not use
  86.140 -# 32 bit ints but string representation of 64 bit ints.
  86.141 -XENAPI_INT_CFG = [
  86.142 -    'user_version',
  86.143 -    'vcpus_number',
  86.144 -    'memory_static_min',
  86.145 -    'memory_static_max',
  86.146 -    'memory_dynamic_min',
  86.147 -    'memory_dynamic_max',
  86.148 -    'tpm_instance',
  86.149 -    'tpm_backend',
  86.150 -]    
  86.151 +# List of legacy configuration keys that have no equivalent in the
  86.152 +# Xen API, but are still stored in XendConfig.
  86.153  
  86.154 -##
  86.155 -## Xend Configuration Parameters
  86.156 -##
  86.157 -
  86.158 -
  86.159 -# All parameters of VMs that may be configured on-the-fly, or at start-up.
  86.160 -VM_CONFIG_ENTRIES = [
  86.161 -    ('name',        str),
  86.162 -    ('on_crash',    str),
  86.163 -    ('on_poweroff', str),
  86.164 -    ('on_reboot',   str),
  86.165 -    ('on_xend_start', str),
  86.166 -    ('on_xend_stop', str),        
  86.167 +LEGACY_UNSUPPORTED_BY_XENAPI_CFG = [
  86.168 +    # roundtripped (dynamic, unmodified)
  86.169 +    'shadow_memory',
  86.170 +    'security',
  86.171 +    'vcpu_avail',
  86.172 +    'cpu_weight',
  86.173 +    'cpu_cap',
  86.174 +    'bootloader',
  86.175 +    'bootloader_args',
  86.176 +    'features',
  86.177 +    # read/write
  86.178 +    'on_xend_start',
  86.179 +    'on_xend_stop',
  86.180 +    # read-only
  86.181 +    'domid',
  86.182 +    'start_time',
  86.183 +    'cpu_time',
  86.184 +    'online_vcpus',
  86.185 +    # write-once
  86.186 +    'cpu',
  86.187 +    'cpus',
  86.188  ]
  86.189  
  86.190 -# All entries written to the store.  This is VM_CONFIG_ENTRIES, plus those
  86.191 -# entries written to the store that cannot be reconfigured on-the-fly.
  86.192 -VM_STORE_ENTRIES = [
  86.193 -    ('uuid',       str),
  86.194 -    ('vcpus',      int),
  86.195 -    ('vcpu_avail', int),
  86.196 -    ('memory',     int),
  86.197 -    ('maxmem',     int),
  86.198 -    ('start_time', float),
  86.199 +LEGACY_CFG_TYPES = {
  86.200 +    'uuid':          str,
  86.201 +    'name':          str,
  86.202 +    'vcpus':         int,
  86.203 +    'vcpu_avail':    int,
  86.204 +    'memory':        int,
  86.205 +    'shadow_memory': int,
  86.206 +    'maxmem':        int,
  86.207 +    'start_time':    float,
  86.208 +    'cpu_cap':         int,
  86.209 +    'cpu_weight':      int,
  86.210 +    'cpu_time':      float,
  86.211 +    'bootloader':      str,
  86.212 +    'bootloader_args': str,
  86.213 +    'features':        str,
  86.214 +    'localtime':       int,
  86.215 +    'name':        str,
  86.216 +    'on_poweroff': str,
  86.217 +    'on_reboot':   str,
  86.218 +    'on_crash':    str,
  86.219 +    'on_xend_stop': str,
  86.220 +    'on_xend_start': str,
  86.221 +    'online_vcpus': int,
  86.222 +}
  86.223 +
  86.224 +# Values that should be stored in xenstore's /vm/<uuid> that is used
  86.225 +# by Xend. Used in XendDomainInfo to restore running VM state from
  86.226 +# xenstore.
  86.227 +LEGACY_XENSTORE_VM_PARAMS = [
  86.228 +    'uuid',
  86.229 +    'name',
  86.230 +    'vcpus',
  86.231 +    'vcpu_avail',
  86.232 +    'memory',
  86.233 +    'shadow_memory',
  86.234 +    'maxmem',
  86.235 +    'start_time',
  86.236 +    'name',
  86.237 +    'on_poweroff',
  86.238 +    'on_crash',
  86.239 +    'on_reboot',
  86.240 +    'on_xend_start',
  86.241 +    'on_xend_stop',
  86.242  ]
  86.243  
  86.244 -VM_STORED_ENTRIES = VM_CONFIG_ENTRIES + VM_STORE_ENTRIES
  86.245 -
  86.246 -# Configuration entries that we expect to round-trip -- be read from the
  86.247 -# config file or xc, written to save-files (i.e. through sxpr), and reused as
  86.248 -# config on restart or restore, all without munging.  Some configuration
  86.249 -# entries are munged for backwards compatibility reasons, or because they
  86.250 -# don't come out of xc in the same form as they are specified in the config
  86.251 -# file, so those are handled separately.
  86.252 -
  86.253 -ROUNDTRIPPING_CONFIG_ENTRIES = [
  86.254 -    ('uuid',       str),
  86.255 -    ('vcpus',      int),
  86.256 -    ('vcpu_avail', int),
  86.257 -    ('cpu_cap',    int),
  86.258 -    ('cpu_weight', int),
  86.259 -    ('memory',     int),
  86.260 -    ('shadow_memory', int),
  86.261 -    ('maxmem',     int),
  86.262 -    ('bootloader', str),
  86.263 -    ('bootloader_args', str),
  86.264 -    ('features', str),
  86.265 -    ('localtime', int),
  86.266 -]
  86.267 -ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_ENTRIES
  86.268 -
  86.269 -## Static Configuration
  86.270 -
  86.271 -STATIC_CONFIG_ENTRIES = [
  86.272 -    ('cpu',      int),
  86.273 -    ('cpus',     str),
  86.274 -    ('image',    list),
  86.275 -    ('security', list), # TODO: what if null?
  86.276 +LEGACY_IMAGE_CFG = [
  86.277 +    ('root', str),
  86.278 +    ('ip', str),
  86.279 +    ('nographic', int),
  86.280 +    ('vnc', int),
  86.281 +    ('sdl', int),
  86.282 +    ('vncdisplay', int),
  86.283 +    ('vncunused', int),
  86.284 +    ('vncpasswd', str),    
  86.285  ]
  86.286  
  86.287 -DEPRECATED_ENTRIES = [
  86.288 -    ('restart', str),
  86.289 +LEGACY_IMAGE_HVM_CFG = [
  86.290 +    ('device_model', str),
  86.291 +    ('display', str),
  86.292 +    ('xauthority', str),
  86.293 +    ('vncconsole', int),
  86.294 +    ('pae', int),
  86.295 +    ('apic', int),
  86.296 +]
  86.297 +
  86.298 +LEGACY_IMAGE_HVM_DEVICES_CFG = [
  86.299 +    ('acpi', int),    
  86.300 +    ('boot', str),
  86.301 +    ('fda', str),
  86.302 +    ('fdb', str),
  86.303 +    ('isa', str),
  86.304 +    ('keymap', str),    
  86.305 +    ('localtime', str),    
  86.306 +    ('serial', str),
  86.307 +    ('stdvga', int),
  86.308 +    ('soundhw', str),
  86.309 +    ('usb', str),
  86.310 +    ('usbdevice', str),    
  86.311 +    ('vcpus', int),
  86.312  ]
  86.313  
  86.314  ##
  86.315 @@ -178,245 +232,172 @@ CONFIG_RESTART_MODES = ('restart', 'dest
  86.316  CONFIG_OLD_DOM_STATES = ('running', 'blocked', 'paused', 'shutdown',
  86.317                           'crashed', 'dying')
  86.318  
  86.319 -##
  86.320 -## Defaults
  86.321 -##
  86.322 -
  86.323 -def DEFAULT_VCPUS(info):
  86.324 -    if 'max_vcpu_id' in info: return int(info['max_vcpu_id']) + 1
  86.325 -    else: return 1
  86.326 -
  86.327 -DEFAULT_CONFIGURATION = (
  86.328 -    ('uuid',         lambda info: uuid.createString()),
  86.329 -    ('name',         lambda info: 'Domain-' + info['uuid']),
  86.330 -
  86.331 -    ('on_poweroff',  lambda info: 'destroy'),
  86.332 -    ('on_reboot',    lambda info: 'restart'),
  86.333 -    ('on_crash',     lambda info: 'restart'),
  86.334 -    ('features',     lambda info: ''),
  86.335 -
  86.336 -    
  86.337 -    ('memory',       lambda info: 0),
  86.338 -    ('shadow_memory',lambda info: 0),
  86.339 -    ('maxmem',       lambda info: 0),
  86.340 -    ('bootloader',   lambda info: None),
  86.341 -    ('bootloader_args', lambda info: None),            
  86.342 -    ('backend',      lambda info: []),
  86.343 -    ('device',       lambda info: {}),
  86.344 -    ('image',        lambda info: None),
  86.345 -    ('security',     lambda info: []),
  86.346 -    ('on_xend_start', lambda info: 'ignore'),    
  86.347 -    ('on_xend_stop', lambda info: 'ignore'),
  86.348 -
  86.349 -    ('cpus',         lambda info: []),
  86.350 -    ('cpu_cap',      lambda info: 0),
  86.351 -    ('cpu_weight',   lambda info: 256),
  86.352 -    ('vcpus',        lambda info: DEFAULT_VCPUS(info)),
  86.353 -    ('online_vcpus', lambda info: info['vcpus']),
  86.354 -    ('max_vcpu_id',  lambda info: info['vcpus']-1),
  86.355 -    ('vcpu_avail',   lambda info: (1<<info['vcpus'])-1),
  86.356 -
  86.357 -    # New for Xen API
  86.358 -    ('kernel_kernel', lambda info: ''),
  86.359 -    ('kernel_initrd', lambda info: ''),
  86.360 -    ('kernel_args',   lambda info: ''),
  86.361 -    
  86.362 -)
  86.363 -    
  86.364  class XendConfigError(VmError):
  86.365      def __str__(self):
  86.366          return 'Invalid Configuration: %s' % str(self.value)
  86.367  
  86.368  ##
  86.369 -## XendConfig SXP Config Compat
  86.370 -##
  86.371 -
  86.372 -class XendSXPConfig:
  86.373 -    def get_domid(self):
  86.374 -        pass
  86.375 -    def get_handle(self):
  86.376 -        return self['uuid']
  86.377 -        
  86.378 -
  86.379 -##
  86.380  ## XendConfig Class (an extended dictionary)
  86.381  ##
  86.382  
  86.383  class XendConfig(dict):
  86.384 -    """ Generic Configuration Parser accepting SXP, Python or XML.
  86.385 -    This is a dictionary-like object that is populated.
  86.386 -
  86.387 -    @ivar legacy: dictionary holding legacy xen domain info
  86.388 -    @ivar xenapi: dictionary holding xen api config info
  86.389 -    """
  86.390 -
  86.391 -    def __init__(self, filename = None, fd = None,
  86.392 -                 sxp = None, xml = None, pycfg = None, xenapi_vm = None,
  86.393 -                 cfg = {}):
  86.394 -        """Constructor. Provide either the filename, fd or sxp.
  86.395 +    """ The new Xend VM Configuration.
  86.396  
  86.397 -        @keyword filename: filename of an SXP file
  86.398 -        @keyword fd: file descriptor of an SXP file
  86.399 -        @keyword sxp: a list of list of a parsed SXP
  86.400 -        @keyword xml: an XML tree object
  86.401 -        @keyword xenapi_vm: a struct passed from an XMLRPC call (Xen API)
  86.402 -        @keyword cfg: a dictionary of configuration (eg. from xc)
  86.403 -        """
  86.404 -        format = 'unknown'
  86.405 -
  86.406 -        self.xenapi = {}
  86.407 -
  86.408 -        if filename and not fd:
  86.409 -            fd = open(filename, 'r')
  86.410 -
  86.411 -        if fd:
  86.412 -            format = self._detect_format(fd)
  86.413 +    Stores the configuration in xenapi compatible format but retains
  86.414 +    import and export functions for SXP.
  86.415 +    """
  86.416 +    def __init__(self, filename = None, sxp_obj = None,
  86.417 +                 xapi = None, dominfo = None):
  86.418          
  86.419 -        if fd:
  86.420 -            if format == 'sxp':
  86.421 -                sxp = self._read_sxp(fd)
  86.422 -            elif format == 'python' and filename != None:
  86.423 -                pycfg = self._read_python(filename)
  86.424 -            elif format == 'python' and filename == None:
  86.425 -                raise XendConfigError("Python files must be passed as a "
  86.426 -                                      "filename rather than file descriptor.")
  86.427 -            elif format == 'xml':
  86.428 -                xml = self._read_xml(fd)
  86.429 -            else:
  86.430 -                raise XendConfigError("Unable to determine format of file")
  86.431 -                
  86.432 -        if sxp:
  86.433 -            cfg = self._populate_from_sxp(sxp)
  86.434 -        if xml:
  86.435 -            cfg = self._populate_from_xml(xml)
  86.436 -        if pycfg:
  86.437 -            cfg = self._populate_from_python_config(pycfg)
  86.438 -        if xenapi_vm:
  86.439 -            cfg = self._populate_from_xenapi_vm(xenapi_vm)
  86.440 -            
  86.441 -        if cfg:
  86.442 -            self.update(cfg)
  86.443 -            
  86.444 -        if xenapi_vm:
  86.445 -            self.xenapi.update(xenapi_vm)
  86.446 +        dict.__init__(self)
  86.447 +        self.update(self._defaults())
  86.448  
  86.449 -        log.debug('XendConfig: %s' % str(self))
  86.450 +        if filename:
  86.451 +            try:
  86.452 +                sxp_obj = sxp.parse(open(filename,'r'))
  86.453 +                sxp_obj = sxp_obj[0]
  86.454 +            except IOError, e:
  86.455 +                raise XendConfigError("Unable to read file: %s" % filename)
  86.456 +        
  86.457 +        if sxp_obj:
  86.458 +            self._sxp_to_xapi(sxp_obj)
  86.459 +            self._sxp_to_xapi_unsupported(sxp_obj)
  86.460 +        elif xapi:
  86.461 +            self.update_with_xenapi_config(xapi)
  86.462 +            self._add_xapi_unsupported()
  86.463 +        elif dominfo:
  86.464 +            # output from xc.domain_getinfo
  86.465 +            self._dominfo_to_xapi(dominfo)
  86.466 +
  86.467 +        log.debug('XendConfig.init: %s' % self)
  86.468 +
  86.469 +        # validators go here
  86.470          self.validate()
  86.471  
  86.472 -    #
  86.473 -    # Xen API Attribute Access
  86.474 -    #
  86.475 -
  86.476 -    def __getattr__(self, name):
  86.477 -        try:
  86.478 -            return dict.__getattr__(self, name)
  86.479 -        except AttributeError:
  86.480 +    """ In time, we should enable this type checking addition. It is great
  86.481 +        also for tracking bugs and unintended writes to XendDomainInfo.info
  86.482 +    def __setitem__(self, key, value):
  86.483 +        type_conv = XENAPI_CFG_TYPES.get(key)
  86.484 +        if callable(type_conv):
  86.485              try:
  86.486 -                return  self.__dict__['xenapi'][name]
  86.487 -            except KeyError:
  86.488 -                raise AttributeError("XendConfig Xen API has no attribute "
  86.489 -                                     "'%s'" % name)
  86.490 -            
  86.491 -
  86.492 -    def __setattr__(self, name, value):
  86.493 -        try:
  86.494 -            return dict.__setattr__(self, name, value)
  86.495 -        except AttributeError:
  86.496 -            self.xenapi[name] = value
  86.497 -            #self.set_legacy_api_with_xen_api_value(name, value)
  86.498 -
  86.499 -    def __delattr__(self, name):
  86.500 -        try:
  86.501 -            dict.__delattr__(self, name)
  86.502 -        except AttributeError:
  86.503 -            del self.xenapi[name]
  86.504 -        #self.del_legacy_api_with_xen_api_key(name)
  86.505 -
  86.506 -
  86.507 +                dict.__setitem__(self, key, type_conv(value))
  86.508 +            except (ValueError, TypeError):
  86.509 +                raise XendConfigError("Wrong type for configuration value " +
  86.510 +                                      "%s. Expected %s" %
  86.511 +                                      (key, type_conv.__name__))
  86.512 +        else:
  86.513 +            dict.__setitem__(self, key, value)
  86.514      """
  86.515 -    #
  86.516 -    # Legacy API Attribute Access
  86.517 -    #
  86.518 -
  86.519 -    def __getitem__(self, key):
  86.520 -        try:
  86.521 -            return self.legacy[key]
  86.522 -        except KeyError:
  86.523 -            raise AttributeError, "XendConfig Legacy has no attribute '%s'"\
  86.524 -                  % key
  86.525 -
  86.526 -    def __setitem__(self, key, value):
  86.527 -        self.legacy[key] = value
  86.528 -        self.set_xen_api_with_legacy_api_value(key, value)
  86.529 -
  86.530 -    def __delitem__(self, key):
  86.531 -        del self.legacy[key]
  86.532 -        self.del_xen_api_with_legacy_api_key(key)
  86.533 -    """
  86.534 -    
  86.535  
  86.536 -    def _detect_format(self, fd):
  86.537 -        """Detect the format of the configuration passed.
  86.538 -
  86.539 -        @param fd: file descriptor of contents to detect
  86.540 -        @rtype: string, 'sxp', 'xml', 'python' or 'unknown'
  86.541 -        """
  86.542 -        format = 'unknown'
  86.543 +    def _defaults(self):
  86.544 +        defaults = {
  86.545 +            'uuid': uuid.createString(),
  86.546 +            'name_label': 'Domain-Unnamed',
  86.547 +            'actions_after_shutdown': 'destroy',
  86.548 +            'actions_after_reboot': 'restart',
  86.549 +            'actions_after_crash': 'restart',
  86.550 +            'actions_after_suspend': '',
  86.551 +            'features': '',
  86.552 +            'builder': 'linux',
  86.553 +            'memory_static_min': 0,
  86.554 +            'memory_dynamic_min': 0,
  86.555 +            'shadow_memory': 0,
  86.556 +            'memory_static_max': 0,
  86.557 +            'memory_dynamic_max': 0,
  86.558 +            'memory_actual': 0,
  86.559 +            'boot_method': None,
  86.560 +            'bootloader': None,
  86.561 +            'bootloader_args': None,
  86.562 +            'devices': {},
  86.563 +            'image': {},
  86.564 +            'security': None,
  86.565 +            'on_xend_start': 'ignore',
  86.566 +            'on_xend_stop': 'ignore',
  86.567 +            'cpus': [],
  86.568 +            'cpu_weight': 256,
  86.569 +            'cpu_cap': 0,
  86.570 +            'vcpus_number': 1,
  86.571 +            'online_vcpus': 1,
  86.572 +            'max_vcpu_id': 0,
  86.573 +            'vcpu_avail': 1,
  86.574 +            'vif_refs': [],
  86.575 +            'vbd_refs': [],
  86.576 +            'vtpm_refs': [],
  86.577 +        }
  86.578          
  86.579 -        fd.seek(0)
  86.580 -        for line in fd:
  86.581 -            stripped = line.strip()
  86.582 -            if stripped:
  86.583 -                if re.search(r'^\(', stripped): 
  86.584 -                    format = 'sxp'
  86.585 -                elif re.search(r'^\<?xml', stripped):
  86.586 -                    format = 'xml'
  86.587 -                else:
  86.588 -                    format = 'python'
  86.589 -                break
  86.590 -
  86.591 -        fd.seek(0)
  86.592 -        return format
  86.593 -
  86.594 -    def _read_sxp(self, fd):
  86.595 -        """ Read and parse SXP (from SXP to list of lists)
  86.596 +        defaults['name_label'] = 'Domain-' + defaults['uuid']
  86.597 +        return defaults
  86.598  
  86.599 -        @rtype: list of lists.
  86.600 -        """
  86.601 -        try:
  86.602 -            parsed = sxp.parse(fd)[0]
  86.603 -            return parsed
  86.604 -        except:
  86.605 -            raise
  86.606 -            return None
  86.607 -
  86.608 -    def _read_xml(self, fd):
  86.609 -        """TODO: Read and parse XML (from XML to dict)
  86.610 +    def _memory_sanity_check(self):
  86.611 +        if self['memory_static_min'] == 0:
  86.612 +            self['memory_static_min'] = self['memory_dynamic_min']
  86.613  
  86.614 -        @rtype: dict
  86.615 -        """
  86.616 -        raise NotImplementedError
  86.617 -
  86.618 -    def _read_python(self, filename):
  86.619 -        """Read and parse python module that represents the config.
  86.620 +        # If the static max is not set, let's set it to dynamic max.
  86.621 +        # If the static max is smaller than static min, then fix it!
  86.622 +        self['memory_static_max'] = max(self['memory_static_max'],
  86.623 +                                        self['memory_dynamic_max'],
  86.624 +                                        self['memory_static_min'])
  86.625  
  86.626 -        @rtype: dict
  86.627 -        """
  86.628 -        cfg_globals = {}
  86.629 -        execfile(filename, cfg_globals, {})
  86.630 -        return cfg_globals
  86.631 +        for mem_type in ('memory_static_min', 'memory_static_max'):
  86.632 +            if self[mem_type] <= 0:
  86.633 +                raise XendConfigError('Memory value too low for %s: %d' %
  86.634 +                                      (mem_type, self[mem_type]))
  86.635  
  86.636 -    def _populate_from_sxp(self, parsed):
  86.637 +    def _actions_sanity_check(self):
  86.638 +        for event in ['shutdown', 'reboot', 'crash']:
  86.639 +            if self['actions_after_' + event] not in CONFIG_RESTART_MODES:
  86.640 +                raise XendConfigError('Invalid event handling mode: ' +
  86.641 +                                      event)
  86.642 +
  86.643 +    def _builder_sanity_check(self):
  86.644 +        if self['builder'] not in ('hvm', 'linux'):
  86.645 +            raise XendConfigError('Invalid builder configuration')
  86.646 +
  86.647 +    def validate(self):
  86.648 +        self._memory_sanity_check()
  86.649 +        self._actions_sanity_check()
  86.650 +        self._builder_sanity_check()
  86.651 +
  86.652 +    def _dominfo_to_xapi(self, dominfo):
  86.653 +        self['domid'] = dominfo['domid']
  86.654 +        self['online_vcpus'] = dominfo['online_vcpus']
  86.655 +        self['max_vcpu_id'] = dominfo['max_vcpu_id']
  86.656 +        self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024
  86.657 +        self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024
  86.658 +        self['cpu_time'] = dominfo['cpu_time']/1e9
  86.659 +        # TODO: i don't know what the security stuff expects here
  86.660 +        if dominfo.get('ssidref'):
  86.661 +            self['security'] = [['ssidref', dominfo['ssidref']]]
  86.662 +        self['shutdown_reason'] = dominfo['shutdown_reason']
  86.663 +
  86.664 +        # parse state into Xen API states
  86.665 +        self['running'] = dominfo['running']
  86.666 +        self['crashed'] = dominfo['crashed']
  86.667 +        self['dying'] = dominfo['dying']
  86.668 +        self['shutdown'] = dominfo['shutdown']
  86.669 +        self['paused'] = dominfo['paused']
  86.670 +        self['blocked'] = dominfo['blocked']
  86.671 +
  86.672 +        if 'name' in dominfo:
  86.673 +            self['name_label'] = dominfo['name']
  86.674 +
  86.675 +        if 'handle' in dominfo:
  86.676 +            self['uuid'] = uuid.toString(dominfo['handle'])
  86.677 +            
  86.678 +    def _parse_sxp(self, sxp_cfg):
  86.679          """ Populate this XendConfig using the parsed SXP.
  86.680  
  86.681 +        @param sxp_cfg: Parsed SXP Configuration
  86.682 +        @type sxp_cfg: list of lists
  86.683          @rtype: dictionary
  86.684 +        @return: A dictionary containing the parsed options of the SXP.
  86.685          """
  86.686          cfg = {}
  86.687  
  86.688          # First step is to convert deprecated options to
  86.689          # current equivalents.
  86.690          
  86.691 -        restart = sxp.child_value(parsed, 'restart')
  86.692 +        restart = sxp.child_value(sxp_cfg, 'restart')
  86.693          if restart:
  86.694              if restart == 'onreboot':
  86.695                  cfg['on_poweroff'] = 'destroy'
  86.696 @@ -433,23 +414,19 @@ class XendConfig(dict):
  86.697                           'restart = \'%s\'', restart)
  86.698  
  86.699          # Only extract options we know about.
  86.700 -        all_params = VM_CONFIG_ENTRIES + ROUNDTRIPPING_CONFIG_ENTRIES + \
  86.701 -                     STATIC_CONFIG_ENTRIES
  86.702 -                     
  86.703 -        for key, typeconv in all_params:
  86.704 -            val = sxp.child_value(parsed, key)
  86.705 -            if val:
  86.706 +        extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG
  86.707 +        extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values()
  86.708 +        
  86.709 +        for key in extract_keys:
  86.710 +            val = sxp.child_value(sxp_cfg, key)
  86.711 +            if val != None:
  86.712                  try:
  86.713 -                    cfg[key] = typeconv(val)
  86.714 -                except ValueError:
  86.715 -                    pass
  86.716 -
  86.717 -        # Manually extract other complex configuration
  86.718 -        # options.
  86.719 -
  86.720 -        cfg['backend'] = []
  86.721 -        for c in sxp.children(parsed, 'backend'):
  86.722 -            cfg['backend'].append(sxp.name(sxp.child0(c)))
  86.723 +                    cfg[key] = LEGACY_CFG_TYPES[key](val)
  86.724 +                except KeyError:
  86.725 +                    cfg[key] = val
  86.726 +                except (TypeError, ValueError), e:
  86.727 +                    log.warn("Unable to parse key %s: %s: %s" %
  86.728 +                             (key, str(val), e))
  86.729  
  86.730          # Parsing the device SXP's. In most cases, the SXP looks
  86.731          # like this:
  86.732 @@ -472,65 +449,52 @@ class XendConfig(dict):
  86.733          # Hence we deal with pci device configurations outside of
  86.734          # the regular device parsing.
  86.735          
  86.736 -        cfg['device'] = {}
  86.737 -        for dev in sxp.children(parsed, 'device'):
  86.738 +        cfg['devices'] = {}
  86.739 +        for dev in sxp.children(sxp_cfg, 'device'):
  86.740              config = sxp.child0(dev)
  86.741              dev_type = sxp.name(config)
  86.742              dev_info = {}
  86.743              
  86.744              if dev_type == 'pci':
  86.745 -                continue 
  86.746 -            
  86.747 -            for opt, val in config[1:]:
  86.748 -                dev_info[opt] = val
  86.749 -            log.debug("XendConfig: reading device: %s" % dev_info)
  86.750 -            # create uuid if it doesn't
  86.751 -            dev_uuid = dev_info.get('uuid', uuid.createString())
  86.752 -            dev_info['uuid'] = dev_uuid
  86.753 -            cfg['device'][dev_uuid] = (dev_type, dev_info)
  86.754 -
  86.755 -        # deal with PCI device configurations if they exist
  86.756 -        for dev in sxp.children(parsed, 'device'):
  86.757 -            config = sxp.child0(dev)
  86.758 -            dev_type = sxp.name(config)
  86.759 -
  86.760 -            if dev_type != 'pci':
  86.761 -                continue
  86.762 -            
  86.763 -            dev_attr = sxp.child_value(config, 'dev')
  86.764 -            if isinstance(dev_attr, (types.ListType, types.TupleType)):
  86.765 +                pci_devs_uuid = sxp.child_value(config, 'uuid',
  86.766 +                                                uuid.createString())
  86.767 +                pci_devs = []
  86.768                  for pci_dev in sxp.children(config, 'dev'):
  86.769 -                    dev_info = {}
  86.770 +                    pci_dev_info = {}
  86.771                      for opt, val in pci_dev[1:]:
  86.772 -                        dev_info[opt] = val
  86.773 -                    log.debug("XendConfig: reading device: %s" % dev_info)
  86.774 -                    dev_uuid = dev_info.get('uuid', uuid.createString())
  86.775 -                    dev_info['uuid'] = dev_uuid
  86.776 -                    cfg['device'][dev_uuid] = (dev_type, dev_info)
  86.777 -                    
  86.778 -            else: # Xen 2.0 PCI device configuration
  86.779 +                        pci_dev_info[opt] = val
  86.780 +                    pci_devs.append(pci_dev_info)
  86.781 +                
  86.782 +                cfg['devices'][pci_devs_uuid] = (dev_type,
  86.783 +                                                 {'devs': pci_devs,
  86.784 +                                                  'uuid': pci_devs_uuid})
  86.785 +                
  86.786 +                log.debug("XendConfig: reading device: %s" % pci_devs)
  86.787 +            else:
  86.788                  for opt, val in config[1:]:
  86.789                      dev_info[opt] = val
  86.790                  log.debug("XendConfig: reading device: %s" % dev_info)
  86.791                  # create uuid if it doesn't
  86.792                  dev_uuid = dev_info.get('uuid', uuid.createString())
  86.793                  dev_info['uuid'] = dev_uuid
  86.794 -                cfg['device'][dev_uuid] = (dev_type, dev_info)
  86.795 +                cfg['devices'][dev_uuid] = (dev_type, dev_info)
  86.796 +
  86.797  
  86.798          # Extract missing data from configuration entries
  86.799 -        if 'image' in cfg:
  86.800 -            image_vcpus = sxp.child_value(cfg['image'], 'vcpus')
  86.801 -            if image_vcpus is not None:
  86.802 +        image_sxp = sxp.child_value(sxp_cfg, 'image', [])
  86.803 +        if image_sxp:
  86.804 +            image_vcpus = sxp.child_value(image_sxp, 'vcpus')
  86.805 +            if image_vcpus != None:
  86.806                  try:
  86.807 -                    if 'vcpus' not in cfg:
  86.808 -                        cfg['vcpus'] = int(image_vcpus)
  86.809 -                    elif cfg['vcpus'] != int(image_vcpus):
  86.810 -                        cfg['vcpus'] = int(image_vcpus)
  86.811 +                    if 'vcpus_number' not in cfg:
  86.812 +                        cfg['vcpus_number'] = int(image_vcpus)
  86.813 +                    elif cfg['vcpus_number'] != int(image_vcpus):
  86.814 +                        cfg['vcpus_number'] = int(image_vcpus)
  86.815                          log.warn('Overriding vcpus from %d to %d using image'
  86.816 -                                 'vcpus value.', cfg['vcpus'])
  86.817 +                                 'vcpus value.', cfg['vcpus_number'])
  86.818                  except ValueError, e:
  86.819                      raise XendConfigError('integer expeceted: %s: %s' %
  86.820 -                                        str(cfg['image']), e)
  86.821 +                                          image_sxp, e)
  86.822  
  86.823          # Deprecated cpu configuration
  86.824          if 'cpu' in cfg:
  86.825 @@ -564,101 +528,188 @@ class XendConfig(dict):
  86.826          except ValueError, e:
  86.827              raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
  86.828  
  86.829 -        # Parse image SXP outside of image.py
  86.830 -        # - used to be only done in image.py
  86.831 -        if 'image' in cfg:
  86.832 -            cfg['kernel_kernel'] = sxp.child_value(cfg['image'], 'kernel','')
  86.833 -            cfg['kernel_initrd'] = sxp.child_value(cfg['image'], 'ramdisk','')
  86.834 -            kernel_args = sxp.child_value(cfg['image'], 'args', '')
  86.835 -
  86.836 -            # attempt to extract extra arguments from SXP config
  86.837 -            arg_ip = sxp.child_value(cfg['image'], 'ip')
  86.838 -            if arg_ip: kernel_args += ' ip=%s' % arg_ip
  86.839 -            arg_root = sxp.child_value(cfg['image'], 'root')
  86.840 -            if arg_root: kernel_args += ' root=%s' % arg_root
  86.841 -            
  86.842 -            cfg['kernel_args'] = kernel_args
  86.843 +        if 'security' in cfg and isinstance(cfg['security'], str):
  86.844 +            cfg['security'] = sxp.from_string(cfg['security'])
  86.845  
  86.846          # TODO: get states
  86.847 -        old_state = sxp.child_value(parsed, 'state')
  86.848 +        old_state = sxp.child_value(sxp_cfg, 'state')
  86.849          if old_state:
  86.850              for i in range(len(CONFIG_OLD_DOM_STATES)):
  86.851                  cfg[CONFIG_OLD_DOM_STATES[i]] = int(old_state[i] != '-')
  86.852  
  86.853 -        # Xen API extra cfgs
  86.854 -        # ------------------
  86.855 -        cfg['vif_refs'] = []
  86.856 -        cfg['vbd_refs'] = []
  86.857 -        cfg['vtpm_refs'] = []
  86.858 -        for dev_uuid, (dev_type, dev_info) in cfg['device'].items():
  86.859 -            if dev_type == 'vif':
  86.860 -                cfg['vif_refs'].append(dev_uuid)
  86.861 -            elif dev_type in ('vbd','tap'):
  86.862 -                cfg['vbd_refs'].append(dev_uuid)
  86.863 -            elif dev_type == 'vtpm':
  86.864 -                cfg['vtpm_refs'].append(dev_uuid)
  86.865 -                
  86.866          return cfg
  86.867 -
  86.868 -
  86.869 -    def _populate_from_xenapi_vm(self, xenapi_vm):
  86.870 -        cfg = {}
  86.871 +    
  86.872  
  86.873 -        for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():
  86.874 +    def _sxp_to_xapi(self, sxp_cfg):
  86.875 +        """Read in an SXP Configuration object and
  86.876 +        populate at much of the Xen API with valid values.
  86.877 +        """
  86.878 +        cfg = self._parse_sxp(sxp_cfg)
  86.879 +
  86.880 +        # Convert parameters that can be directly mapped from
  86.881 +        # the Legacy Config to Xen API Config
  86.882 +        
  86.883 +        for apikey, cfgkey in XENAPI_CFG_TO_LEGACY_CFG.items():
  86.884              try:
  86.885 -                if apikey in XENAPI_INT_CFG:
  86.886 -                    cfg[cfgkey] = int(xenapi_vm[apikey])
  86.887 +                type_conv = XENAPI_CFG_TYPES.get(apikey)
  86.888 +                if callable(type_conv):
  86.889 +                    self[apikey] = type_conv(cfg[cfgkey])
  86.890                  else:
  86.891 -                    cfg[cfgkey] = xenapi_vm[apikey]                    
  86.892 +                    log.warn("Unconverted key: " + apikey)
  86.893 +                    self[apikey] = cfg[cfgkey]
  86.894              except KeyError:
  86.895                  pass
  86.896  
  86.897 -        # Reconstruct image SXP 
  86.898 -        # TODO: get rid of SXP altogether from here
  86.899 -        sxp_image = ['linux']
  86.900 -        if xenapi_vm['kernel_kernel']:
  86.901 -            sxp_image.append(['kernel', xenapi_vm['kernel_kernel']])
  86.902 -        if xenapi_vm['kernel_initrd']:
  86.903 -            sxp_image.append(['ramdisk', xenapi_vm['kernel_initrd']])
  86.904 -        if xenapi_vm['kernel_args']:
  86.905 -            sxp_image.append(['args', xenapi_vm['kernel_args']])
  86.906 -
  86.907 -        cfg['image'] = prettyprintstring(sxp_image)
  86.908 -
  86.909 -        # make sure device structures are there.
  86.910 -        if 'device' not in cfg:
  86.911 -            cfg['device'] = {}
  86.912 -        if 'vif_refs' not in cfg:
  86.913 -            cfg['vif_refs'] = []
  86.914 -        if 'vbd_refs' not in cfg:
  86.915 -            cfg['vbd_refs'] = []
  86.916 -        if 'vtpm_refs' not in cfg:
  86.917 -            cfg['vtpm_refs'] = []
  86.918 +        # Convert Legacy "image" config to Xen API kernel_*
  86.919 +        # configuration
  86.920 +        image_sxp = sxp.child_value(sxp_cfg, 'image', [])
  86.921 +        if image_sxp:
  86.922 +            self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
  86.923 +            self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
  86.924 +            kernel_args = sxp.child_value(image_sxp, 'args', '')
  86.925  
  86.926 -        return cfg
  86.927 -
  86.928 -
  86.929 -    def _sync_xen_api_from_legacy_api(self):
  86.930 -        """ Sync all the attributes that is supported by the Xen API
  86.931 -        from the legacy API configuration.
  86.932 -        """
  86.933 -        for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():        
  86.934 -            if cfgkey in self:
  86.935 -                self.xenapi[apikey] = self[cfgkey]
  86.936 +            # attempt to extract extra arguments from SXP config
  86.937 +            arg_ip = sxp.child_value(image_sxp, 'ip')
  86.938 +            if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
  86.939 +                kernel_args += ' ip=%s' % arg_ip
  86.940 +            arg_root = sxp.child_value(image_sxp, 'root')
  86.941 +            if arg_root and not re.search(r'root=[^ ]+', kernel_args):
  86.942 +                kernel_args += ' root=%s' % arg_root
  86.943 +            
  86.944 +            self['kernel_args'] = kernel_args
  86.945  
  86.946 -    def _sync_legacy_api_from_xen_api(self):
  86.947 -        for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():
  86.948 -            if apikey in self.xenapi:
  86.949 -                self[cfgkey] = self.xenapi[apikey]
  86.950 +        # Convert Legacy HVM parameters to Xen API configuration
  86.951 +        self['platform_std_vga'] = bool0(cfg.get('stdvga', 0))
  86.952 +        self['platform_serial'] = str(cfg.get('serial', ''))
  86.953 +        self['platform_localtime'] = bool0(cfg.get('localtime', 0))
  86.954 +        self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0))
  86.955  
  86.956 +        # Convert path to bootloader to boot_method
  86.957 +        if not cfg.get('bootloader'):
  86.958 +            if self.get('kernel_kernel','').endswith('hvmloader'):
  86.959 +                self['boot_method'] = 'bios'
  86.960 +            else:
  86.961 +                self['boot_method'] = 'kernel_external'
  86.962 +        else:
  86.963 +            self['boot_method'] = 'grub'
  86.964  
  86.965 -    def _populate_from_xml(self, parsed_xml):
  86.966 -        raise NotImplementedError
  86.967 +        # make sure a sane maximum is set
  86.968 +        if self['memory_static_max'] <= 0:
  86.969 +            self['memory_static_max'] = self['memory_static_min']
  86.970 +            
  86.971 +        self['memory_dynamic_max'] = self['memory_static_max']
  86.972 +        self['memory_dynamic_min'] = self['memory_static_min']
  86.973  
  86.974 -    def _populate_from_python_config(self, parsed_py):
  86.975 -        raise NotImplementedError
  86.976 +        # set device references in the configuration
  86.977 +        self['devices'] = cfg.get('devices', {})
  86.978 +        
  86.979 +        self['vif_refs'] = []
  86.980 +        self['vbd_refs'] = []
  86.981 +        self['vtpm_refs'] = []
  86.982 +        for dev_uuid, (dev_type, dev_info) in self['devices'].items():
  86.983 +            if dev_type == 'vif':
  86.984 +                self['vif_refs'].append(dev_uuid)
  86.985 +            elif dev_type in ('vbd','tap'):
  86.986 +                self['vbd_refs'].append(dev_uuid)
  86.987 +            elif dev_type in ('vtpm',):
  86.988 +                self['vtpm_refs'].append(dev_uuid)
  86.989 +        
  86.990 +
  86.991 +    def _sxp_to_xapi_unsupported(self, sxp_cfg):
  86.992 +        """Read in an SXP configuration object and populate
  86.993 +        values are that not related directly supported in
  86.994 +        the Xen API.
  86.995 +        """
  86.996 +
  86.997 +        # Parse and convert parameters used to configure
  86.998 +        # the image (as well as HVM images)
  86.999 +        image_sxp = sxp.child_value(sxp_cfg, 'image', [])
 86.1000 +        if image_sxp:
 86.1001 +            image = {}
 86.1002 +            image['type'] = sxp.name(image_sxp)
 86.1003 +            for arg, conv in LEGACY_IMAGE_CFG:
 86.1004 +                val = sxp.child_value(image_sxp, arg, None)
 86.1005 +                if val != None:
 86.1006 +                    image[arg] = conv(val)
 86.1007 +
 86.1008 +            image_hvm = {}
 86.1009 +            for arg, conv in LEGACY_IMAGE_HVM_CFG:
 86.1010 +                val = sxp.child_value(image_sxp, arg, None)
 86.1011 +                if val != None:
 86.1012 +                    image_hvm[arg] = conv(val)
 86.1013 +                    
 86.1014 +            image_hvm_devices = {}
 86.1015 +            for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
 86.1016 +                val = sxp.child_value(image_sxp, arg, None)
 86.1017 +                if val != None:
 86.1018 +                    image_hvm_devices[arg] = conv(val)
 86.1019 +
 86.1020 +            if image_hvm or image_hvm_devices:
 86.1021 +                image['hvm'] = image_hvm
 86.1022 +                image['hvm']['devices'] = image_hvm_devices
 86.1023 +
 86.1024 +            self['image'] = image
 86.1025 +
 86.1026 +            for apikey, imgkey in XENAPI_HVM_CFG.items():
 86.1027 +                val = sxp.child_value(image_sxp, imgkey, None)
 86.1028 +                if val != None:
 86.1029 +                    self[apikey] = val
 86.1030 +
 86.1031 +        # extract backend value
 86.1032 +                    
 86.1033 +        backend = []
 86.1034 +        for c in sxp.children(sxp_cfg, 'backend'):
 86.1035 +            backend.append(sxp.name(sxp.child0(c)))
 86.1036 +        if backend:
 86.1037 +            self['backend'] = backend
 86.1038 +
 86.1039 +        if self['image'].has_key('hvm'):
 86.1040 +            self['builder'] = 'hvm'
 86.1041 +            
 86.1042 +        # Parse and convert other Non Xen API parameters.
 86.1043 +        def _set_cfg_if_exists(sxp_arg):
 86.1044 +            val = sxp.child_value(sxp_cfg, sxp_arg)
 86.1045 +            if val != None:
 86.1046 +                if LEGACY_CFG_TYPES.get(sxp_arg):
 86.1047 +                    self[sxp_arg] = LEGACY_CFG_TYPES[sxp_arg](val)
 86.1048 +                else:
 86.1049 +                    self[sxp_arg] = val
 86.1050 +
 86.1051 +        _set_cfg_if_exists('shadow_memory')
 86.1052 +        _set_cfg_if_exists('security')
 86.1053 +        _set_cfg_if_exists('features')
 86.1054 +        _set_cfg_if_exists('on_xend_stop')
 86.1055 +        _set_cfg_if_exists('on_xend_start')
 86.1056 +        _set_cfg_if_exists('vcpu_avail')
 86.1057 +        _set_cfg_if_exists('max_vcpu_id') # TODO, deprecated?
 86.1058 +        
 86.1059 +        # Parse and store runtime configuration 
 86.1060 +        _set_cfg_if_exists('start_time')
 86.1061 +        _set_cfg_if_exists('online_vcpus')
 86.1062 +        _set_cfg_if_exists('cpu_time')
 86.1063 +        _set_cfg_if_exists('shutdown_reason')
 86.1064 +        _set_cfg_if_exists('up_time')
 86.1065 +        _set_cfg_if_exists('status') # TODO, deprecated  
 86.1066 +
 86.1067 +    def _add_xapi_unsupported(self):
 86.1068 +        """Updates the configuration object with entries that are not
 86.1069 +        officially supported by the Xen API but is required for
 86.1070 +        the rest of Xend to function.
 86.1071 +        """
 86.1072 +
 86.1073 +        # populate image
 86.1074 +        self['image']['type'] = self['builder']
 86.1075 +        if self['builder'] == 'hvm':
 86.1076 +            self['image']['hvm'] = {}
 86.1077 +            for xapi, cfgapi in XENAPI_HVM_CFG.items():
 86.1078 +                self['image']['hvm'][cfgapi] = self[xapi]
 86.1079 +            
 86.1080  
 86.1081      def _get_old_state_string(self):
 86.1082 +        """Returns the old xm state string.
 86.1083 +        @rtype: string
 86.1084 +        @return: old state string
 86.1085 +        """
 86.1086          state_string = ''
 86.1087          for state_name in CONFIG_OLD_DOM_STATES:
 86.1088              on_off = self.get(state_name, 0)
 86.1089 @@ -669,9 +720,41 @@ class XendConfig(dict):
 86.1090  
 86.1091          return state_string
 86.1092  
 86.1093 -    def get_sxp(self, domain = None, ignore_devices = False, ignore = []):
 86.1094 +
 86.1095 +    def update_config(self, dominfo):
 86.1096 +        """Update configuration with the output from xc.domain_getinfo().
 86.1097 +
 86.1098 +        @param dominfo: Domain information via xc.domain_getinfo()
 86.1099 +        @type dominfo: dict
 86.1100 +        """
 86.1101 +        self._dominfo_to_xapi(dominfo)
 86.1102 +        self.validate()
 86.1103 +
 86.1104 +    def update_with_xenapi_config(self, xapi):
 86.1105 +        """Update configuration with a Xen API VM struct
 86.1106 +
 86.1107 +        @param xapi: Xen API VM Struct
 86.1108 +        @type xapi: dict
 86.1109 +        """
 86.1110 +        for key, val in xapi.items():
 86.1111 +            key = key.lower()
 86.1112 +            type_conv = XENAPI_CFG_TYPES.get(key)
 86.1113 +            if callable(type_conv):
 86.1114 +                self[key] = type_conv(val)
 86.1115 +            else:
 86.1116 +                self[key] = val
 86.1117 +
 86.1118 +        self.validate()
 86.1119 +
 86.1120 +    def to_xml(self):
 86.1121 +        """Return an XML string representing the configuration."""
 86.1122 +        pass
 86.1123 +
 86.1124 +    def to_sxp(self, domain = None, ignore_devices = False, ignore = []):
 86.1125          """ Get SXP representation of this config object.
 86.1126  
 86.1127 +        Incompat: removed store_mfn, console_mfn
 86.1128 +
 86.1129          @keyword domain: (optional) XendDomainInfo to get extra information
 86.1130                           from such as domid and running devices.
 86.1131          @type    domain: XendDomainInfo
 86.1132 @@ -688,45 +771,37 @@ class XendConfig(dict):
 86.1133          if domain.getDomid() is not None:
 86.1134              sxpr.append(['domid', domain.getDomid()])
 86.1135  
 86.1136 -        for cfg, typefunc in ROUNDTRIPPING_CONFIG_ENTRIES:
 86.1137 -            if cfg in self:
 86.1138 -                if self[cfg] is not None:
 86.1139 -                    sxpr.append([cfg, self[cfg]])
 86.1140 +        for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
 86.1141 +            if self.has_key(xenapi) and self[xenapi] not in (None, []):
 86.1142 +                if type(self[xenapi]) == bool:
 86.1143 +                    # convert booleans to ints before making an sxp item
 86.1144 +                    sxpr.append([legacy, int(self[xenapi])])
 86.1145 +                else:
 86.1146 +                    sxpr.append([legacy, self[xenapi]])
 86.1147  
 86.1148 -        if 'image' in self and self['image'] is not None:
 86.1149 -            sxpr.append(['image', self['image']])
 86.1150 -        if 'security' in self and self['security']:
 86.1151 -            sxpr.append(['security', self['security']])
 86.1152 -        if 'shutdown_reason' in self:
 86.1153 -            sxpr.append(['shutdown_reason', self['shutdown_reason']])
 86.1154 -        if 'cpu_time' in self:
 86.1155 -            sxpr.append(['cpu_time', self['cpu_time']/1e9])
 86.1156 +        for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
 86.1157 +            if legacy in ('domid', 'uuid'): # skip these
 86.1158 +                continue
 86.1159 +            if self.has_key(legacy) and self[legacy] not in (None, []):
 86.1160 +                sxpr.append([legacy, self[legacy]])
 86.1161  
 86.1162 -        sxpr.append(['online_vcpus', self['online_vcpus']])
 86.1163 +        if 'image' in self and self['image']:
 86.1164 +            sxpr.append(['image', self.image_sxpr()])
 86.1165  
 86.1166 -        if 'start_time' in self:
 86.1167 -            uptime = time.time() - self['start_time']
 86.1168 -            sxpr.append(['up_time', str(uptime)])
 86.1169 -            sxpr.append(['start_time', str(self['start_time'])])
 86.1170 -
 86.1171 -        if domain:
 86.1172 -            sxpr.append(['status', str(domain.state)])
 86.1173 -        else:
 86.1174 -            sxpr.append(['status', str(DOM_STATE_HALTED)])
 86.1175 +        sxpr.append(['status', domain.state])
 86.1176 +        sxpr.append(['memory_dynamic_min',  self.get('memory_dynamic_min')])
 86.1177 +        sxpr.append(['memory_dynamic_max',  self.get('memory_dynamic_max')])
 86.1178  
 86.1179          if domain.getDomid() is not None:
 86.1180              sxpr.append(['state', self._get_old_state_string()])
 86.1181  
 86.1182 -        sxpr.append(['memory_dynamic_max', self.get('memory_dynamic_max',
 86.1183 -                                                    self['memory'])])
 86.1184 -
 86.1185 -        # For save/restore migration
 86.1186          if domain:
 86.1187              if domain.store_mfn:
 86.1188                  sxpr.append(['store_mfn', domain.store_mfn])
 86.1189              if domain.console_mfn:
 86.1190                  sxpr.append(['console_mfn', domain.console_mfn])
 86.1191  
 86.1192 +
 86.1193          # Marshall devices (running or from configuration)
 86.1194          if not ignore_devices:
 86.1195              for cls in XendDevices.valid_devices():
 86.1196 @@ -743,7 +818,7 @@ class XendConfig(dict):
 86.1197                      except:
 86.1198                          log.exception("dumping sxp from device controllers")
 86.1199                          pass
 86.1200 -                        
 86.1201 +                    
 86.1202                  # if we didn't find that device, check the existing config
 86.1203                  # for a device in the same class
 86.1204                  if not found:
 86.1205 @@ -751,58 +826,28 @@ class XendConfig(dict):
 86.1206                          if dev_type == cls:
 86.1207                              sxpr.append(['device', dev_info])
 86.1208  
 86.1209 -        return sxpr
 86.1210 -
 86.1211 -    def validate(self):
 86.1212 -        """ Validate the configuration and fill in missing configuration
 86.1213 -        with defaults.
 86.1214 -        """
 86.1215 -
 86.1216 -        # Fill in default values
 86.1217 -        for key, default_func in DEFAULT_CONFIGURATION:
 86.1218 -            if key not in self or self[key] == None:
 86.1219 -                self[key] = default_func(self)
 86.1220 -
 86.1221 -        # Basic sanity checks
 86.1222 -        if 'image' in self and isinstance(self['image'], str):
 86.1223 -            self['image'] = sxp.from_string(self['image'])
 86.1224 -        if 'security' in self and isinstance(self['security'], str):
 86.1225 -            self['security'] = sxp.from_string(self['security'])
 86.1226 -        if self['memory'] == 0 and 'mem_kb' in self:
 86.1227 -            self['memory'] = (self['mem_kb'] + 1023)/1024
 86.1228 -        if self['memory'] <= 0:
 86.1229 -            raise XendConfigError('Invalid memory size: %s' %
 86.1230 -                                  str(self['memory']))
 86.1231 -
 86.1232 -        self['maxmem'] = max(self['memory'], self['maxmem'])
 86.1233 +        return sxpr    
 86.1234 +    
 86.1235 +    def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
 86.1236 +        """Add a device configuration in SXP format or XenAPI struct format.
 86.1237  
 86.1238 -        # convert mem_kb from domain_getinfo to something more descriptive
 86.1239 -        if 'mem_kb' in self:
 86.1240 -            self['memory_dynamic_max'] = (self['mem_kb'] + 1023)/1024
 86.1241 -
 86.1242 -        # Verify devices
 86.1243 -        for d_uuid, (d_type, d_info) in self['device'].items():
 86.1244 -            if d_type not in XendDevices.valid_devices() and \
 86.1245 -               d_type not in XendDevices.pseudo_devices():
 86.1246 -                raise XendConfigError('Invalid device (%s)' % d_type)
 86.1247 +        For SXP, it could be either:
 86.1248  
 86.1249 -        # Verify restart modes
 86.1250 -        for event in ('on_poweroff', 'on_reboot', 'on_crash'):
 86.1251 -            if self[event] not in CONFIG_RESTART_MODES:
 86.1252 -                raise XendConfigError('Invalid restart event: %s = %s' % \
 86.1253 -                                      (event, str(self[event])))
 86.1254 +        [device, [vbd, [uname ...]]
 86.1255  
 86.1256 -        # Verify that {vif,vbd}_refs are here too
 86.1257 -        if 'vif_refs' not in self:
 86.1258 -            self['vif_refs'] = []
 86.1259 -        if 'vbd_refs' not in self:
 86.1260 -            self['vbd_refs'] = []
 86.1261 -        if 'vtpm_refs' not in self:
 86.1262 -            self['vtpm_refs'] = []
 86.1263 +        or:
 86.1264  
 86.1265 -    def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
 86.1266 +        [vbd, [uname ..]]
 86.1267 +
 86.1268 +        @type cfg_sxp: list of lists (parsed sxp object)
 86.1269 +        @param cfg_sxp: SXP configuration object
 86.1270 +        @type cfg_xenapi: dict
 86.1271 +        @param cfg_xenapi: A device configuration from Xen API (eg. vbd,vif)
 86.1272 +        @rtype: string
 86.1273 +        @return: Assigned UUID of the device.
 86.1274 +        """
 86.1275          if dev_type not in XendDevices.valid_devices() and \
 86.1276 -           dev_type not in XendDevices.pseudo_devices():
 86.1277 +           dev_type not in XendDevices.pseudo_devices():        
 86.1278              raise XendConfigError("XendConfig: %s not a valid device type" %
 86.1279                              dev_type)
 86.1280  
 86.1281 @@ -816,22 +861,48 @@ class XendConfig(dict):
 86.1282              log.debug("XendConfig.device_add: %s" % str(cfg_xenapi))
 86.1283  
 86.1284          if cfg_sxp:
 86.1285 +            if sxp.child0(cfg_sxp) == 'device':
 86.1286 +                config = sxp.child0(cfg_sxp)
 86.1287 +            else:
 86.1288 +                config = cfg_sxp
 86.1289 +
 86.1290 +            dev_type = sxp.name(config)
 86.1291              dev_info = {}
 86.1292  
 86.1293              try:
 86.1294 -                for opt, val in cfg_sxp[1:]:
 86.1295 +                for opt, val in config[1:]:
 86.1296                      dev_info[opt] = val
 86.1297              except ValueError:
 86.1298                  pass # SXP has no options for this device
 86.1299  
 86.1300 +            
 86.1301 +            def _get_config_ipaddr(config):
 86.1302 +                val = []
 86.1303 +                for ipaddr in sxp.children(config, elt='ip'):
 86.1304 +                    val.append(sxp.child0(ipaddr))
 86.1305 +                return val
 86.1306 +
 86.1307 +            if dev_type == 'vif' and 'ip' in dev_info:
 86.1308 +                dev_info['ip'] = _get_config_ipaddr(config)
 86.1309 +
 86.1310 +            if dev_type == 'vbd':
 86.1311 +                if dev_info.get('dev', '').startswith('ioemu:'):
 86.1312 +                    dev_info['driver'] = 'ioemu'
 86.1313 +                else:
 86.1314 +                    dev_info['driver'] = 'paravirtualised'
 86.1315 +                    
 86.1316 +
 86.1317              # create uuid if it doesn't exist
 86.1318              dev_uuid = dev_info.get('uuid', uuid.createString())
 86.1319              dev_info['uuid'] = dev_uuid
 86.1320 -            self['device'][dev_uuid] = (dev_type, dev_info)
 86.1321 -            if dev_type in ('vif', 'vbd'):
 86.1322 +
 86.1323 +            # store dev references by uuid for certain device types
 86.1324 +            self['devices'][dev_uuid] = (dev_type, dev_info)
 86.1325 +            if dev_type in ('vif', 'vbd', 'vtpm'):
 86.1326                  self['%s_refs' % dev_type].append(dev_uuid)
 86.1327              elif dev_type in ('tap',):
 86.1328                  self['vbd_refs'].append(dev_uuid)
 86.1329 +
 86.1330              return dev_uuid
 86.1331  
 86.1332          if cfg_xenapi:
 86.1333 @@ -849,13 +920,21 @@ class XendConfig(dict):
 86.1334                  
 86.1335                  dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
 86.1336                  dev_info['uuid'] = dev_uuid
 86.1337 -                self['device'][dev_uuid] = (dev_type, dev_info)
 86.1338 +                self['devices'][dev_uuid] = (dev_type, dev_info)
 86.1339                  self['vif_refs'].append(dev_uuid)
 86.1340                  return dev_uuid
 86.1341              
 86.1342 -            elif dev_type == 'vbd':
 86.1343 -                dev_info['uname'] = cfg_xenapi.get('image', None)
 86.1344 -                dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
 86.1345 +            elif dev_type in ('vbd', 'tap'):
 86.1346 +                if dev_type == 'vbd':
 86.1347 +                    dev_info['uname'] = cfg_xenapi.get('image', '')
 86.1348 +                    dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
 86.1349 +                elif dev_type == 'tap':
 86.1350 +                    dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
 86.1351 +                    dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
 86.1352 +                    
 86.1353 +                dev_info['driver'] = cfg_xenapi.get('driver')
 86.1354 +                dev_info['VDI'] = cfg_xenapi.get('VDI', '')
 86.1355 +                    
 86.1356                  if cfg_xenapi.get('mode') == 'RW':
 86.1357                      dev_info['mode'] = 'w'
 86.1358                  else:
 86.1359 @@ -863,35 +942,43 @@ class XendConfig(dict):
 86.1360  
 86.1361                  dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
 86.1362                  dev_info['uuid'] = dev_uuid
 86.1363 -                self['device'][dev_uuid] = (dev_type, dev_info)
 86.1364 +                self['devices'][dev_uuid] = (dev_type, dev_info)
 86.1365                  self['vbd_refs'].append(dev_uuid)                
 86.1366                  return dev_uuid
 86.1367  
 86.1368 -            elif dev_type == 'vtpm':
 86.1369 +            elif dev_type in ('vtpm'):
 86.1370                  if cfg_xenapi.get('type'):
 86.1371                      dev_info['type'] = cfg_xenapi.get('type')
 86.1372 +
 86.1373                  dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
 86.1374                  dev_info['uuid'] = dev_uuid
 86.1375 -                self['device'][dev_uuid] = (dev_type, dev_info)
 86.1376 +                self['devices'][dev_uuid] = (dev_type, dev_info)
 86.1377                  self['vtpm_refs'].append(dev_uuid)
 86.1378                  return dev_uuid
 86.1379  
 86.1380 -            elif dev_type == 'tap':
 86.1381 -                dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
 86.1382 -                dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
 86.1383 -                
 86.1384 -                if cfg_xenapi.get('mode') == 'RW':
 86.1385 -                    dev_info['mode'] = 'w'
 86.1386 -                else:
 86.1387 -                    dev_info['mode'] = 'r'
 86.1388 +        return ''
 86.1389  
 86.1390 -                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
 86.1391 -                dev_info['uuid'] = dev_uuid
 86.1392 -                self['device'][dev_uuid] = (dev_type, dev_info)
 86.1393 -                self['vbd_refs'].append(dev_uuid)                
 86.1394 -                return dev_uuid                
 86.1395 -                
 86.1396 -        return ''
 86.1397 +    def device_update(self, dev_uuid, cfg_sxp):
 86.1398 +        """Update an existing device with the new configuration.
 86.1399 +
 86.1400 +        @rtype: boolean
 86.1401 +        @return: Returns True if succesfully found and updated a device conf
 86.1402 +        """
 86.1403 +        if dev_uuid in self['devices']:
 86.1404 +            config = sxp.child0(cfg_sxp)
 86.1405 +            dev_type = sxp.name(config)
 86.1406 +            dev_info = {}
 86.1407 +
 86.1408 +            try:
 86.1409 +                for opt, val in config[1:]:
 86.1410 +                    self['devices'][opt] = val
 86.1411 +            except ValueError:
 86.1412 +                pass # SXP has no options for this device
 86.1413 +            
 86.1414 +            return True
 86.1415 +
 86.1416 +        return False
 86.1417 +
 86.1418  
 86.1419      def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None):
 86.1420          """Get Device SXPR by either giving the device UUID or (type, config).
 86.1421 @@ -900,8 +987,8 @@ class XendConfig(dict):
 86.1422          @return: device config sxpr
 86.1423          """
 86.1424          sxpr = []
 86.1425 -        if dev_uuid != None and dev_uuid in self['device']:
 86.1426 -            dev_type, dev_info = self['device'][dev_uuid]
 86.1427 +        if dev_uuid != None and dev_uuid in self['devices']:
 86.1428 +            dev_type, dev_info = self['devices'][dev_uuid]
 86.1429  
 86.1430          if dev_type == None or dev_info == None:
 86.1431              raise XendConfigError("Required either UUID or device type and "
 86.1432 @@ -917,27 +1004,106 @@ class XendConfig(dict):
 86.1433          """Returns the SXPR for all devices in the current configuration."""
 86.1434          sxprs = []
 86.1435          pci_devs = []
 86.1436 -        for dev_type, dev_info in self['device'].values():
 86.1437 +
 86.1438 +        if 'devices' not in self:
 86.1439 +            return sxprs
 86.1440 +        
 86.1441 +        for dev_type, dev_info in self['devices'].values():
 86.1442              if dev_type == 'pci': # special case for pci devices
 86.1443 -                pci_devs.append(dev_info)
 86.1444 +                sxpr = [['uuid', dev_info['uuid']]]
 86.1445 +                for pci_dev_info in dev_info['devs']:
 86.1446 +                    pci_dev_sxpr = ['dev']
 86.1447 +                    for opt, val in pci_dev_info.items():
 86.1448 +                        pci_dev_sxpr.append([opt, val])
 86.1449 +                    sxpr.append(pci_dev_sxpr)
 86.1450 +                sxprs.append((dev_type, sxpr))
 86.1451              else:
 86.1452                  sxpr = self.device_sxpr(dev_type = dev_type,
 86.1453                                          dev_info = dev_info)
 86.1454                  sxprs.append((dev_type, sxpr))
 86.1455  
 86.1456 -        # if we have any pci_devs, we parse them differently into
 86.1457 -        # one single pci SXP entry.
 86.1458 -        if pci_devs:
 86.1459 -            sxpr = ['pci',]
 86.1460 -            for dev_info in pci_devs:
 86.1461 -                dev_sxpr = self.device_sxpr(dev_type = 'dev',
 86.1462 -                                            dev_info = dev_info)
 86.1463 -                sxpr.append(dev_sxpr)
 86.1464 -            sxprs.append(('pci', sxpr))
 86.1465 -            
 86.1466          return sxprs
 86.1467  
 86.1468 -                     
 86.1469 +    def image_sxpr(self):
 86.1470 +        """Returns a backwards compatible image SXP expression that is
 86.1471 +        used in xenstore's /vm/<uuid>/image value and xm list."""
 86.1472 +        image = [self['image'].get('type', 'linux')]
 86.1473 +        if self.has_key('kernel_kernel'):
 86.1474 +            image.append(['kernel', self['kernel_kernel']])
 86.1475 +        if self.has_key('kernel_initrd') and self['kernel_initrd']:
 86.1476 +            image.append(['ramdisk', self['kernel_initrd']])
 86.1477 +        if self.has_key('kernel_args') and self['kernel_args']:
 86.1478 +            image.append(['args', self['kernel_args']])
 86.1479 +
 86.1480 +        for arg, conv in LEGACY_IMAGE_CFG:
 86.1481 +            if self['image'].has_key(arg):
 86.1482 +                image.append([arg, self['image'][arg]])
 86.1483 +
 86.1484 +        if 'hvm' in self['image']:
 86.1485 +            for arg, conv in LEGACY_IMAGE_HVM_CFG:
 86.1486 +                if self['image']['hvm'].get(arg):
 86.1487 +                    image.append([arg, self['image']['hvm'][arg]])
 86.1488 +
 86.1489 +        if 'hvm' in self['image'] and 'devices' in self['image']['hvm']:
 86.1490 +            for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
 86.1491 +                if self['image']['hvm']['devices'].get(arg):
 86.1492 +                    image.append([arg,
 86.1493 +                                  self['image']['hvm']['devices'][arg]])
 86.1494 +
 86.1495 +        return image
 86.1496 +
 86.1497 +    def update_with_image_sxp(self, image_sxp):
 86.1498 +        # Convert Legacy "image" config to Xen API kernel_*
 86.1499 +        # configuration
 86.1500 +        self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
 86.1501 +        self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
 86.1502 +        kernel_args = sxp.child_value(image_sxp, 'args', '')
 86.1503 +        
 86.1504 +        # attempt to extract extra arguments from SXP config
 86.1505 +        arg_ip = sxp.child_value(image_sxp, 'ip')
 86.1506 +        if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
 86.1507 +            kernel_args += ' ip=%s' % arg_ip
 86.1508 +        arg_root = sxp.child_value(image_sxp, 'root')
 86.1509 +        if arg_root and not re.search(r'root=', kernel_args):
 86.1510 +            kernel_args += ' root=%s' % arg_root
 86.1511 +        self['kernel_args'] = kernel_args
 86.1512 +
 86.1513 +        # Store image SXP in python dictionary format
 86.1514 +        image = {}
 86.1515 +        image['type'] = sxp.name(image_sxp)
 86.1516 +        for arg, conv in LEGACY_IMAGE_CFG:
 86.1517 +            val = sxp.child_value(image_sxp, arg, None)
 86.1518 +            if val != None:
 86.1519 +                image[arg] = conv(val)
 86.1520 +
 86.1521 +        image_hvm = {}
 86.1522 +        for arg, conv in LEGACY_IMAGE_HVM_CFG:
 86.1523 +            val = sxp.child_value(image_sxp, arg, None)
 86.1524 +            if val != None:
 86.1525 +                image_hvm[arg] = conv(val)
 86.1526 +                    
 86.1527 +        image_hvm_devices = {}
 86.1528 +        for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
 86.1529 +            val = sxp.child_value(image_sxp, arg, None)
 86.1530 +            if val != None:
 86.1531 +                image_hvm_devices[arg] = conv(val)
 86.1532 +
 86.1533 +        if image_hvm or image_hvm_devices:
 86.1534 +            image['hvm'] = image_hvm
 86.1535 +            image['hvm']['devices'] = image_hvm_devices
 86.1536 +
 86.1537 +        self['image'] = image
 86.1538 +
 86.1539 +        for apikey, imgkey in XENAPI_HVM_CFG.items():
 86.1540 +            val = sxp.child_value(image_sxp, imgkey, None)
 86.1541 +            if val != None:
 86.1542 +                type_conv = XENAPI_CFG_TYPES[apikey]
 86.1543 +                if callable(conv):
 86.1544 +                    self[apikey] = type_conv(val)
 86.1545 +                else:
 86.1546 +                    self[apikey] = val
 86.1547 +
 86.1548 +        
 86.1549  #
 86.1550  # debugging 
 86.1551  #
    87.1 --- a/tools/python/xen/xend/XendConstants.py	Sat Dec 02 15:19:50 2006 -0700
    87.2 +++ b/tools/python/xen/xend/XendConstants.py	Mon Dec 04 08:24:41 2006 -0700
    87.3 @@ -34,6 +34,8 @@ DOMAIN_SHUTDOWN_REASONS = {
    87.4      DOMAIN_CRASH   : "crash",
    87.5      DOMAIN_HALT    : "halt"
    87.6  }
    87.7 +REVERSE_DOMAIN_SHUTDOWN_REASONS = \
    87.8 +    dict([(y, x) for x, y in DOMAIN_SHUTDOWN_REASONS.items()])
    87.9  
   87.10  restart_modes = [
   87.11      "restart",
    88.1 --- a/tools/python/xen/xend/XendDevices.py	Sat Dec 02 15:19:50 2006 -0700
    88.2 +++ b/tools/python/xen/xend/XendDevices.py	Mon Dec 04 08:24:41 2006 -0700
    88.3 @@ -19,7 +19,7 @@
    88.4  # A collection of DevControllers 
    88.5  #
    88.6  
    88.7 -from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif
    88.8 +from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif, vfbif
    88.9  from xen.xend.server.BlktapController import BlktapController
   88.10  
   88.11  class XendDevices:
   88.12 @@ -41,6 +41,8 @@ class XendDevices:
   88.13          'irq': irqif.IRQController,
   88.14          'usb': usbif.UsbifController,
   88.15          'tap': BlktapController,
   88.16 +        'vfb': vfbif.VfbifController,
   88.17 +        'vkbd': vfbif.VkbdifController,
   88.18      }
   88.19  
   88.20      #@classmethod
    89.1 --- a/tools/python/xen/xend/XendDomain.py	Sat Dec 02 15:19:50 2006 -0700
    89.2 +++ b/tools/python/xen/xend/XendDomain.py	Mon Dec 04 08:24:41 2006 -0700
    89.3 @@ -23,6 +23,7 @@
    89.4  """
    89.5  
    89.6  import os
    89.7 +import stat
    89.8  import shutil
    89.9  import socket
   89.10  import threading
   89.11 @@ -44,7 +45,7 @@ from xen.xend.XendDevices import XendDev
   89.12  
   89.13  from xen.xend.xenstore.xstransact import xstransact
   89.14  from xen.xend.xenstore.xswatch import xswatch
   89.15 -from xen.util import security
   89.16 +from xen.util import mkdir, security
   89.17  from xen.xend import uuid
   89.18  
   89.19  xc = xen.lowlevel.xc.xc()
   89.20 @@ -99,11 +100,7 @@ class XendDomain:
   89.21          """Singleton initialisation function."""
   89.22  
   89.23          dom_path = self._managed_path()
   89.24 -        try:
   89.25 -            os.stat(dom_path)
   89.26 -        except OSError:
   89.27 -            log.info("Making %s", dom_path)
   89.28 -            os.makedirs(dom_path, 0755)
   89.29 +        mkdir.parents(dom_path, stat.S_IRWXU)
   89.30  
   89.31          xstransact.Mkdir(XS_VMROOT)
   89.32          xstransact.SetPermissions(XS_VMROOT, {'dom': DOM0_ID})
   89.33 @@ -184,7 +181,7 @@ class XendDomain:
   89.34                  if not dom_uuid:
   89.35                      continue
   89.36                  
   89.37 -                dom_name = dom.get('name', 'Domain-%s' % dom_uuid)
   89.38 +                dom_name = dom.get('name_label', 'Domain-%s' % dom_uuid)
   89.39                  try:
   89.40                      running_dom = self.domain_lookup_nr(dom_name)
   89.41                      if not running_dom:
   89.42 @@ -271,25 +268,17 @@ class XendDomain:
   89.43              domains_dir = self._managed_path()
   89.44              dom_uuid = dominfo.get_uuid()            
   89.45              domain_config_dir = self._managed_path(dom_uuid)
   89.46 -        
   89.47 -            # make sure the domain dir exists
   89.48 -            if not os.path.exists(domains_dir):
   89.49 -                os.makedirs(domains_dir, 0755)
   89.50 -            elif not os.path.isdir(domains_dir):
   89.51 -                log.error("xend_domain_dir is not a directory.")
   89.52 -                raise XendError("Unable to save managed configuration "
   89.53 -                                "because %s is not a directory." %
   89.54 -                                domains_dir)
   89.55 -            
   89.56 -            if not os.path.exists(domain_config_dir):
   89.57 +
   89.58 +            def make_or_raise(path):
   89.59                  try:
   89.60 -                    os.makedirs(domain_config_dir, 0755)
   89.61 -                except IOError:
   89.62 -                    log.exception("Failed to create directory: %s" %
   89.63 -                                  domain_config_dir)
   89.64 -                    raise XendError("Failed to create directory: %s" %
   89.65 -                                    domain_config_dir)
   89.66 -                
   89.67 +                    mkdir.parents(path, stat.S_IRWXU)
   89.68 +                except:
   89.69 +                    log.exception("%s could not be created." % path)
   89.70 +                    raise XendError("%s could not be created." % path)
   89.71 +
   89.72 +            make_or_raise(domains_dir)
   89.73 +            make_or_raise(domain_config_dir)
   89.74 +
   89.75              try:
   89.76                  sxp_cache_file = open(self._managed_config_path(dom_uuid),'w')
   89.77                  prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78)
   89.78 @@ -423,7 +412,6 @@ class XendDomain:
   89.79                  self._remove_domain(dom, domid)
   89.80  
   89.81  
   89.82 -
   89.83      def _add_domain(self, info):
   89.84          """Add a domain to the list of running domains
   89.85          
   89.86 @@ -433,6 +421,11 @@ class XendDomain:
   89.87          """
   89.88          log.debug("Adding Domain: %s" % info.getDomid())
   89.89          self.domains[info.getDomid()] = info
   89.90 +        
   89.91 +        # update the managed domains with a new XendDomainInfo object
   89.92 +        # if we are keeping track of it.
   89.93 +        if info.get_uuid() in self.managed_domains:
   89.94 +            self._managed_domain_register(info)
   89.95  
   89.96      def _remove_domain(self, info, domid = None):
   89.97          """Remove the domain from the list of running domains
   89.98 @@ -669,7 +662,7 @@ class XendDomain:
   89.99          self.domains_lock.acquire()
  89.100          try:
  89.101              try:
  89.102 -                xeninfo = XendConfig(xenapi_vm = xenapi_vm)
  89.103 +                xeninfo = XendConfig(xapi = xenapi_vm)
  89.104                  dominfo = XendDomainInfo.createDormant(xeninfo)
  89.105                  log.debug("Creating new managed domain: %s: %s" %
  89.106                            (dominfo.getName(), dominfo.get_uuid()))
  89.107 @@ -873,8 +866,8 @@ class XendDomain:
  89.108          self.domains_lock.acquire()
  89.109          try:
  89.110              try:
  89.111 -                xeninfo = XendConfig(sxp = config)
  89.112 -                dominfo = XendDomainInfo.createDormant(xeninfo)
  89.113 +                domconfig = XendConfig(sxp_obj = config)
  89.114 +                dominfo = XendDomainInfo.createDormant(domconfig)
  89.115                  log.debug("Creating new managed domain: %s" %
  89.116                            dominfo.getName())
  89.117                  self._managed_domain_register(dominfo)
  89.118 @@ -936,6 +929,9 @@ class XendDomain:
  89.119                  if dominfo.state != DOM_STATE_HALTED:
  89.120                      raise XendError("Domain is still running")
  89.121  
  89.122 +                log.info("Domain %s (%s) deleted." %
  89.123 +                         (dominfo.getName(), dominfo.info.get('uuid')))
  89.124 +
  89.125                  self._managed_domain_unregister(dominfo)
  89.126                  self._remove_domain(dominfo)
  89.127                  XendDevices.destroy_device_state(dominfo)
    90.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Sat Dec 02 15:19:50 2006 -0700
    90.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Dec 04 08:24:41 2006 -0700
    90.3 @@ -38,10 +38,9 @@ from xen.util.blkif import blkdev_uname_
    90.4  from xen.util import security
    90.5  
    90.6  from xen.xend import balloon, sxp, uuid, image, arch
    90.7 -from xen.xend import XendRoot, XendNode
    90.8 +from xen.xend import XendRoot, XendNode, XendConfig
    90.9  
   90.10  from xen.xend.XendBootloader import bootloader
   90.11 -from xen.xend.XendConfig import XendConfig
   90.12  from xen.xend.XendError import XendError, VmError
   90.13  from xen.xend.XendDevices import XendDevices
   90.14  from xen.xend.xenstore.xstransact import xstransact, complete
   90.15 @@ -58,6 +57,11 @@ xroot = XendRoot.instance()
   90.16  log = logging.getLogger("xend.XendDomainInfo")
   90.17  #log.setLevel(logging.TRACE)
   90.18  
   90.19 +
   90.20 +def bool0(v):
   90.21 +    return v != "0" and bool(v)
   90.22 +
   90.23 +
   90.24  ##
   90.25  # All parameters of VMs that may be configured on-the-fly, or at start-up.
   90.26  # 
   90.27 @@ -88,7 +92,7 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [
   90.28      ('bootloader',      str),
   90.29      ('bootloader_args', str),
   90.30      ('features',        str),
   90.31 -    ('localtime',       int),
   90.32 +    ('localtime',       bool0),
   90.33      ]
   90.34  
   90.35  ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS
   90.36 @@ -145,7 +149,7 @@ def create(config):
   90.37      """
   90.38  
   90.39      log.debug("XendDomainInfo.create(%s)", config)
   90.40 -    vm = XendDomainInfo(XendConfig(sxp = config))
   90.41 +    vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config))
   90.42      try:
   90.43          vm.start()
   90.44      except:
   90.45 @@ -175,10 +179,9 @@ def recreate(info, priv):
   90.46  
   90.47      assert not info['dying']
   90.48  
   90.49 -    xeninfo = XendConfig(cfg = info)
   90.50 +    xeninfo = XendConfig.XendConfig(dominfo = info)
   90.51      domid = xeninfo['domid']
   90.52 -    uuid1 = xeninfo['handle']
   90.53 -    xeninfo['uuid'] = uuid.toString(uuid1)
   90.54 +    uuid1 = uuid.fromString(xeninfo['uuid'])
   90.55      needs_reinitialising = False
   90.56      
   90.57      dompath = GetDomainPath(domid)
   90.58 @@ -228,6 +231,15 @@ def recreate(info, priv):
   90.59          vm._storeVmDetails()
   90.60          vm._storeDomDetails()
   90.61          
   90.62 +    if vm.info['image']: # Only dom0 should be without an image entry when
   90.63 +                         # recreating, but we cope with missing ones
   90.64 +                         # elsewhere just in case.
   90.65 +        vm.image = image.create(vm,
   90.66 +                                vm.info,
   90.67 +                                vm.info['image'],
   90.68 +                                vm.info['devices'])
   90.69 +        vm.image.recreate()
   90.70 +
   90.71      vm._registerWatches()
   90.72      vm.refreshShutdown(xeninfo)
   90.73      return vm
   90.74 @@ -236,7 +248,7 @@ def recreate(info, priv):
   90.75  def restore(config):
   90.76      """Create a domain and a VM object to do a restore.
   90.77  
   90.78 -    @param config: Domain configuration object
   90.79 +    @param config: Domain SXP configuration
   90.80      @type  config: list of lists. (see C{create})
   90.81  
   90.82      @rtype:  XendDomainInfo
   90.83 @@ -246,7 +258,8 @@ def restore(config):
   90.84      """
   90.85  
   90.86      log.debug("XendDomainInfo.restore(%s)", config)
   90.87 -    vm = XendDomainInfo(XendConfig(sxp = config), resume = True)
   90.88 +    vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config),
   90.89 +                        resume = True)
   90.90      try:
   90.91          vm.resume()
   90.92          return vm
   90.93 @@ -254,24 +267,24 @@ def restore(config):
   90.94          vm.destroy()
   90.95          raise
   90.96  
   90.97 -def createDormant(xeninfo):
   90.98 +def createDormant(domconfig):
   90.99      """Create a dormant/inactive XenDomainInfo without creating VM.
  90.100      This is for creating instances of persistent domains that are not
  90.101      yet start.
  90.102  
  90.103 -    @param xeninfo: Parsed configuration
  90.104 -    @type  xeninfo: dictionary
  90.105 +    @param domconfig: Parsed configuration
  90.106 +    @type  domconfig: XendConfig object
  90.107      
  90.108      @rtype:  XendDomainInfo
  90.109      @return: A up and running XendDomainInfo instance
  90.110      @raise XendError: Errors with configuration.    
  90.111      """
  90.112      
  90.113 -    log.debug("XendDomainInfo.createDormant(%s)", xeninfo)
  90.114 +    log.debug("XendDomainInfo.createDormant(%s)", domconfig)
  90.115      
  90.116      # domid does not make sense for non-running domains.
  90.117 -    xeninfo.pop('domid', None)
  90.118 -    vm = XendDomainInfo(XendConfig(cfg = xeninfo))
  90.119 +    domconfig.pop('domid', None)
  90.120 +    vm = XendDomainInfo(domconfig)
  90.121      return vm    
  90.122  
  90.123  def domain_by_name(name):
  90.124 @@ -383,14 +396,6 @@ class XendDomainInfo:
  90.125          #if not self._infoIsSet('uuid'):
  90.126          #    self.info['uuid'] = uuid.toString(uuid.create())
  90.127  
  90.128 -        #REMOVE: domid logic can be shortened 
  90.129 -        #if domid is not None:
  90.130 -        #    self.domid = domid
  90.131 -        #elif info.has_key('dom'):
  90.132 -        #    self.domid = int(info['dom'])
  90.133 -        #else:
  90.134 -        #    self.domid = None
  90.135 -
  90.136          self.vmpath  = XS_VMROOT + self.info['uuid']
  90.137          self.dompath = dompath
  90.138  
  90.139 @@ -403,6 +408,7 @@ class XendDomainInfo:
  90.140          self.vmWatch = None
  90.141          self.shutdownWatch = None
  90.142          self.shutdownStartTime = None
  90.143 +        self._resume = resume
  90.144  
  90.145          self.state = DOM_STATE_HALTED
  90.146          self.state_updated = threading.Condition()
  90.147 @@ -416,8 +422,7 @@ class XendDomainInfo:
  90.148          if augment:
  90.149              self._augmentInfo(priv)
  90.150  
  90.151 -        self._checkName(self.info['name'])
  90.152 -        self.setResume(resume)
  90.153 +        self._checkName(self.info['name_label'])
  90.154              
  90.155  
  90.156      #
  90.157 @@ -477,10 +482,11 @@ class XendDomainInfo:
  90.158          if self.domid == 0:
  90.159              raise XendError('Domain 0 cannot be shutdown')
  90.160          
  90.161 -        if not reason in DOMAIN_SHUTDOWN_REASONS.values():
  90.162 +        if reason not in DOMAIN_SHUTDOWN_REASONS.values():
  90.163              raise XendError('Invalid reason: %s' % reason)
  90.164 -        self._storeDom("control/shutdown", reason)
  90.165 -                
  90.166 +        self._removeVm('xend/previous_restart_time')
  90.167 +        self.storeDom("control/shutdown", reason)
  90.168 +
  90.169      def pause(self):
  90.170          """Pause domain
  90.171          
  90.172 @@ -506,18 +512,20 @@ class XendDomainInfo:
  90.173      def send_sysrq(self, key):
  90.174          """ Send a Sysrq equivalent key via xenstored."""
  90.175          asserts.isCharConvertible(key)
  90.176 -        self._storeDom("control/sysrq", '%c' % key)
  90.177 +        self.storeDom("control/sysrq", '%c' % key)
  90.178  
  90.179      def device_create(self, dev_config):
  90.180          """Create a new device.
  90.181  
  90.182          @param dev_config: device configuration
  90.183 -        @type  dev_config: dictionary (parsed config)
  90.184 +        @type  dev_config: SXP object (parsed config)
  90.185          """
  90.186          log.debug("XendDomainInfo.device_create: %s" % dev_config)
  90.187          dev_type = sxp.name(dev_config)
  90.188 -        devid = self._createDevice(dev_type, dev_config)
  90.189 -        self.info.device_add(dev_type, cfg_sxp = dev_config)        
  90.190 +        dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
  90.191 +        dev_config_dict = self.info['devices'][dev_uuid][1]
  90.192 +        log.debug("XendDomainInfo.device_create: %s" % dev_config_dict)
  90.193 +        devid = self._createDevice(dev_type, dev_config_dict)
  90.194          self._waitForDevice(dev_type, devid)
  90.195          return self.getDeviceController(dev_type).sxpr(devid)
  90.196  
  90.197 @@ -525,12 +533,26 @@ class XendDomainInfo:
  90.198          """Configure an existing device.
  90.199          
  90.200          @param dev_config: device configuration
  90.201 -        @type  dev_config: dictionary (parsed config)
  90.202 +        @type  dev_config: SXP object (parsed config)
  90.203          @param devid:      device id
  90.204          @type  devid:      int
  90.205 +        @return: Returns True if successfully updated device
  90.206 +        @rtype: boolean
  90.207          """
  90.208          deviceClass = sxp.name(dev_config)
  90.209 -        self._reconfigureDevice(deviceClass, devid, dev_config)
  90.210 +        
  90.211 +        # look up uuid of the device
  90.212 +        dev_control =  self.getDeviceController(deviceClass)
  90.213 +        dev_sxpr = dev_control.sxpr(devid)
  90.214 +        dev_uuid = sxp.child_value(sxpr, 'uuid')
  90.215 +        if not dev_uuid:
  90.216 +            return False
  90.217 +
  90.218 +        self.info.device_update(dev_uuid, dev_config)
  90.219 +        dev_config_dict = self.info['devices'].get(dev_uuid)
  90.220 +        if dev_config_dict:
  90.221 +            dev_control.reconfigureDevice(devid, dev_config_dict[1])
  90.222 +        return True
  90.223  
  90.224      def waitForDevices(self):
  90.225          """Wait for this domain's configured devices to connect.
  90.226 @@ -558,8 +580,18 @@ class XendDomainInfo:
  90.227          return self.getDeviceController(deviceClass).destroyDevice(devid)
  90.228  
  90.229  
  90.230 +
  90.231      def getDeviceSxprs(self, deviceClass):
  90.232 -        return self.getDeviceController(deviceClass).sxprs()
  90.233 +        if self.state == DOM_STATE_RUNNING:
  90.234 +            return self.getDeviceController(deviceClass).sxprs()
  90.235 +        else:
  90.236 +            sxprs = []
  90.237 +            dev_num = 0
  90.238 +            for dev_type, dev_info in self.info.all_devices_sxpr():
  90.239 +                if dev_type == deviceClass:
  90.240 +                    sxprs.append([dev_num, dev_info])
  90.241 +                    dev_num += 1
  90.242 +            return sxprs
  90.243  
  90.244  
  90.245      def setMemoryTarget(self, target):
  90.246 @@ -567,22 +599,22 @@ class XendDomainInfo:
  90.247          @param target: In MiB.
  90.248          """
  90.249          log.debug("Setting memory target of domain %s (%d) to %d MiB.",
  90.250 -                  self.info['name'], self.domid, target)
  90.251 +                  self.info['name_label'], self.domid, target)
  90.252          
  90.253          if target <= 0:
  90.254              raise XendError('Invalid memory size')
  90.255          
  90.256 -        self.info['memory'] = target
  90.257 +        self.info['memory_static_min'] = target
  90.258          self.storeVm("memory", target)
  90.259 -        self._storeDom("memory/target", target << 10)
  90.260 +        self.storeDom("memory/target", target << 10)
  90.261  
  90.262      def getVCPUInfo(self):
  90.263          try:
  90.264              # We include the domain name and ID, to help xm.
  90.265              sxpr = ['domain',
  90.266                      ['domid',      self.domid],
  90.267 -                    ['name',       self.info['name']],
  90.268 -                    ['vcpu_count', self.info['online_vcpus']]]
  90.269 +                    ['name',       self.info['name_label']],
  90.270 +                    ['vcpu_count', self.info['vcpus_number']]]
  90.271  
  90.272              for i in range(0, self.info['max_vcpu_id']+1):
  90.273                  info = xc.vcpu_getinfo(self.domid, i)
  90.274 @@ -610,30 +642,40 @@ class XendDomainInfo:
  90.275          values taken from the store.  This recovers those values known
  90.276          to xend but not to the hypervisor.
  90.277          """
  90.278 -        def useIfNeeded(name, val):
  90.279 -            if not self._infoIsSet(name) and val is not None:
  90.280 -                self.info[name] = val
  90.281 -
  90.282 +        augment_entries = XendConfig.LEGACY_XENSTORE_VM_PARAMS[:]
  90.283          if priv:
  90.284 -            entries = VM_STORE_ENTRIES[:]
  90.285 -            entries.remove(('memory', int))
  90.286 -            entries.remove(('maxmem', int))
  90.287 -        else:
  90.288 -            entries = VM_STORE_ENTRIES
  90.289 -        entries.append(('image', str))
  90.290 -        entries.append(('security', str))
  90.291 +            augment_entries.remove('memory')
  90.292 +            augment_entries.remove('maxmem')
  90.293  
  90.294 -        map(lambda x, y: useIfNeeded(x[0], y), entries,
  90.295 -            self._readVMDetails(entries))
  90.296 +        vm_config = self._readVMDetails([(k, XendConfig.LEGACY_CFG_TYPES[k])
  90.297 +                                         for k in augment_entries])
  90.298 +        
  90.299 +        # make returned lists into a dictionary
  90.300 +        vm_config = dict(zip(augment_entries, vm_config))
  90.301 +        
  90.302 +        for arg in augment_entries:
  90.303 +            xapicfg = arg
  90.304 +            val = vm_config[arg]
  90.305 +            if val != None:
  90.306 +                if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
  90.307 +                    xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
  90.308 +                    self.info[xapiarg] = val
  90.309 +                else:
  90.310 +                    self.info[arg] = val
  90.311  
  90.312 +        # read image value
  90.313 +        image_sxp = self._readVm('image')
  90.314 +        if image_sxp:
  90.315 +            self.info.update_with_image_sxp(sxp.from_string(image_sxp))
  90.316 +
  90.317 +        # read devices
  90.318          devices = []
  90.319 -
  90.320          for devclass in XendDevices.valid_devices():
  90.321              devconfig = self.getDeviceController(devclass).configurations()
  90.322              if devconfig:
  90.323 -                devices.extend(map(lambda conf: (devclass, conf), devconfig))
  90.324 +                devices.extend(devconfig)
  90.325  
  90.326 -        if not self.info['device'] and devices is not None:
  90.327 +        if not self.info['devices'] and devices is not None:
  90.328              for device in devices:
  90.329                  self.info.device_add(device[0], cfg_sxp = device)
  90.330  
  90.331 @@ -660,16 +702,19 @@ class XendDomainInfo:
  90.332      # Function to update xenstore /dom/*
  90.333      #
  90.334  
  90.335 -    def _readDom(self, *args):
  90.336 +    def readDom(self, *args):
  90.337          return xstransact.Read(self.dompath, *args)
  90.338  
  90.339 +    def gatherDom(self, *args):
  90.340 +        return xstransact.Gather(self.dompath, *args)
  90.341 +
  90.342      def _writeDom(self, *args):
  90.343          return xstransact.Write(self.dompath, *args)
  90.344  
  90.345      def _removeDom(self, *args):
  90.346          return xstransact.Remove(self.dompath, *args)
  90.347  
  90.348 -    def _storeDom(self, *args):
  90.349 +    def storeDom(self, *args):
  90.350          return xstransact.Store(self.dompath, *args)
  90.351  
  90.352      def _recreateDom(self):
  90.353 @@ -678,16 +723,16 @@ class XendDomainInfo:
  90.354      def _recreateDomFunc(self, t):
  90.355          t.remove()
  90.356          t.mkdir()
  90.357 -        t.set_permissions({ 'dom' : self.domid })
  90.358 +        t.set_permissions({'dom' : self.domid})
  90.359          t.write('vm', self.vmpath)
  90.360  
  90.361      def _storeDomDetails(self):
  90.362          to_store = {
  90.363              'domid':              str(self.domid),
  90.364              'vm':                 self.vmpath,
  90.365 -            'name':               self.info['name'],
  90.366 +            'name':               self.info['name_label'],
  90.367              'console/limit':      str(xroot.get_console_limit() * 1024),
  90.368 -            'memory/target':      str(self.info['memory'] * 1024)
  90.369 +            'memory/target':      str(self.info['memory_static_min'] * 1024)
  90.370              }
  90.371  
  90.372          def f(n, v):
  90.373 @@ -713,7 +758,7 @@ class XendDomainInfo:
  90.374                  return 'offline'
  90.375  
  90.376          result = {}
  90.377 -        for v in range(0, self.info['vcpus']):
  90.378 +        for v in range(0, self.info['vcpus_number']):
  90.379              result["cpu/%d/availability" % v] = availability(v)
  90.380          return result
  90.381  
  90.382 @@ -735,19 +780,29 @@ class XendDomainInfo:
  90.383          log.trace("XendDomainInfo.storeChanged");
  90.384  
  90.385          changed = False
  90.386 -        
  90.387 -        def f(x, y):
  90.388 -            if y is not None and self.info[x[0]] != y:
  90.389 -                self.info[x[0]] = y
  90.390 -                changed = True
  90.391  
  90.392 -        map(f, VM_CONFIG_PARAMS, self._readVMDetails(VM_CONFIG_PARAMS))
  90.393 +        # Check whether values in the configuration have
  90.394 +        # changed in Xenstore.
  90.395 +        
  90.396 +        cfg_vm = ['name', 'on_poweroff', 'on_reboot', 'on_crash']
  90.397 +        
  90.398 +        vm_details = self._readVMDetails([(k,XendConfig.LEGACY_CFG_TYPES[k])
  90.399 +                                           for k in cfg_vm])
  90.400  
  90.401 -        im = self._readVm('image')
  90.402 -        current_im = self.info['image']
  90.403 -        if (im is not None and
  90.404 -            (current_im is None or sxp.to_string(current_im) != im)):
  90.405 -            self.info['image'] = sxp.from_string(im)
  90.406 +        # convert two lists into a python dictionary
  90.407 +        vm_details = dict(zip(cfg_vm, vm_details))
  90.408 +        
  90.409 +        for arg, val in vm_details.items():
  90.410 +            if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
  90.411 +                xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
  90.412 +                if val != None and val != self.info[xapiarg]:
  90.413 +                    self.info[xapiarg] = val
  90.414 +                    changed= True
  90.415 +
  90.416 +        # Check whether image definition has been updated
  90.417 +        image_sxp = self._readVm('image')
  90.418 +        if image_sxp and image_sxp != self.info.image_sxpr():
  90.419 +            self.info.update_with_image_sxp(sxp.from_string(image_sxp))
  90.420              changed = True
  90.421  
  90.422          if changed:
  90.423 @@ -760,17 +815,17 @@ class XendDomainInfo:
  90.424      def _handleShutdownWatch(self, _):
  90.425          log.debug('XendDomainInfo.handleShutdownWatch')
  90.426          
  90.427 -        reason = self._readDom('control/shutdown')
  90.428 +        reason = self.readDom('control/shutdown')
  90.429  
  90.430          if reason and reason != 'suspend':
  90.431 -            sst = self._readDom('xend/shutdown_start_time')
  90.432 +            sst = self.readDom('xend/shutdown_start_time')
  90.433              now = time.time()
  90.434              if sst:
  90.435                  self.shutdownStartTime = float(sst)
  90.436                  timeout = float(sst) + SHUTDOWN_TIMEOUT - now
  90.437              else:
  90.438                  self.shutdownStartTime = now
  90.439 -                self._storeDom('xend/shutdown_start_time', now)
  90.440 +                self.storeDom('xend/shutdown_start_time', now)
  90.441                  timeout = SHUTDOWN_TIMEOUT
  90.442  
  90.443              log.trace(
  90.444 @@ -791,17 +846,17 @@ class XendDomainInfo:
  90.445  
  90.446      def setName(self, name):
  90.447          self._checkName(name)
  90.448 -        self.info['name'] = name
  90.449 +        self.info['name_label'] = name
  90.450          self.storeVm("name", name)
  90.451  
  90.452      def getName(self):
  90.453 -        return self.info['name']
  90.454 +        return self.info['name_label']
  90.455  
  90.456      def getDomainPath(self):
  90.457          return self.dompath
  90.458  
  90.459      def getShutdownReason(self):
  90.460 -        return self._readDom('control/shutdown')
  90.461 +        return self.readDom('control/shutdown')
  90.462  
  90.463      def getStorePort(self):
  90.464          """For use only by image.py and XendCheckpoint.py."""
  90.465 @@ -816,11 +871,13 @@ class XendDomainInfo:
  90.466          return self.info['features']
  90.467  
  90.468      def getVCpuCount(self):
  90.469 -        return self.info['vcpus']
  90.470 +        return self.info['vcpus_number']
  90.471  
  90.472      def setVCpuCount(self, vcpus):
  90.473          self.info['vcpu_avail'] = (1 << vcpus) - 1
  90.474 +        self.info['vcpus_number'] = vcpus
  90.475          self.storeVm('vcpu_avail', self.info['vcpu_avail'])
  90.476 +        self.storeVm('vcpus', self.info['vcpus_number'])
  90.477          self._writeDom(self._vcpuDomDetails())
  90.478  
  90.479      def getLabel(self):
  90.480 @@ -828,19 +885,19 @@ class XendDomainInfo:
  90.481  
  90.482      def getMemoryTarget(self):
  90.483          """Get this domain's target memory size, in KB."""
  90.484 -        return self.info['memory'] * 1024
  90.485 +        return self.info['memory_static_min'] * 1024
  90.486  
  90.487      def getResume(self):
  90.488 -        return "%s" % self.info['resume']
  90.489 +        return str(self._resume)
  90.490  
  90.491      def getCap(self):
  90.492 -        return self.info['cpu_cap']
  90.493 +        return self.info.get('cpu_cap', 0)
  90.494  
  90.495      def getWeight(self):
  90.496          return self.info['cpu_weight']
  90.497  
  90.498      def setResume(self, state):
  90.499 -        self.info['resume'] = state
  90.500 +        self._resume = state
  90.501  
  90.502      def getRestartCount(self):
  90.503          return self._readVm('xend/restart_count')
  90.504 @@ -885,13 +942,13 @@ class XendDomainInfo:
  90.505                  return
  90.506  
  90.507              elif xeninfo['crashed']:
  90.508 -                if self._readDom('xend/shutdown_completed'):
  90.509 +                if self.readDom('xend/shutdown_completed'):
  90.510                      # We've seen this shutdown already, but we are preserving
  90.511                      # the domain for debugging.  Leave it alone.
  90.512                      return
  90.513  
  90.514                  log.warn('Domain has crashed: name=%s id=%d.',
  90.515 -                         self.info['name'], self.domid)
  90.516 +                         self.info['name_label'], self.domid)
  90.517  
  90.518                  if xroot.get_enable_dump():
  90.519                      self.dumpCore()
  90.520 @@ -901,7 +958,7 @@ class XendDomainInfo:
  90.521  
  90.522              elif xeninfo['shutdown']:
  90.523                  self._stateSet(DOM_STATE_SHUTDOWN)
  90.524 -                if self._readDom('xend/shutdown_completed'):
  90.525 +                if self.readDom('xend/shutdown_completed'):
  90.526                      # We've seen this shutdown already, but we are preserving
  90.527                      # the domain for debugging.  Leave it alone.
  90.528                      return
  90.529 @@ -910,7 +967,7 @@ class XendDomainInfo:
  90.530                      reason = shutdown_reason(xeninfo['shutdown_reason'])
  90.531  
  90.532                      log.info('Domain has shutdown: name=%s id=%d reason=%s.',
  90.533 -                             self.info['name'], self.domid, reason)
  90.534 +                             self.info['name_label'], self.domid, reason)
  90.535  
  90.536                      self._clearRestart()
  90.537  
  90.538 @@ -945,7 +1002,7 @@ class XendDomainInfo:
  90.539                      if timeout < 0:
  90.540                          log.info(
  90.541                              "Domain shutdown timeout expired: name=%s id=%s",
  90.542 -                            self.info['name'], self.domid)
  90.543 +                            self.info['name_label'], self.domid)
  90.544                          self.destroy()
  90.545          finally:
  90.546              self.refresh_shutdown_lock.release()
  90.547 @@ -965,11 +1022,23 @@ class XendDomainInfo:
  90.548      def _maybeRestart(self, reason):
  90.549          # Dispatch to the correct method based upon the configured on_{reason}
  90.550          # behaviour.
  90.551 -        {"destroy"        : self.destroy,
  90.552 -         "restart"        : self._restart,
  90.553 -         "preserve"       : self._preserve,
  90.554 -         "rename-restart" : self._renameRestart}[self.info['on_' + reason]]()
  90.555 +        actions =  {"destroy"        : self.destroy,
  90.556 +                    "restart"        : self._restart,
  90.557 +                    "preserve"       : self._preserve,
  90.558 +                    "rename-restart" : self._renameRestart}
  90.559  
  90.560 +        action_conf = {
  90.561 +            'poweroff': 'actions_after_shutdown',
  90.562 +            'reboot': 'actions_after_reboot',
  90.563 +            'crash': 'actions_after_crash',
  90.564 +        }
  90.565 +
  90.566 +        action_target = self.info.get(action_conf.get(reason))
  90.567 +        func = actions.get(action_target, None)
  90.568 +        if func and callable(func):
  90.569 +            func()
  90.570 +        else:
  90.571 +            self.destroy() # default to destroy
  90.572  
  90.573      def _renameRestart(self):
  90.574          self._restart(True)
  90.575 @@ -1008,7 +1077,7 @@ class XendDomainInfo:
  90.576                  log.error(
  90.577                      'VM %s restarting too fast (%f seconds since the last '
  90.578                      'restart).  Refusing to restart to avoid loops.',
  90.579 -                    self.info['name'], timeout)
  90.580 +                    self.info['name_label'], timeout)
  90.581                  self.destroy()
  90.582                  return
  90.583  
  90.584 @@ -1055,11 +1124,11 @@ class XendDomainInfo:
  90.585          new_uuid = uuid.createString()
  90.586          new_name = 'Domain-%s' % new_uuid
  90.587          log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
  90.588 -                 self.info['name'], self.domid, self.info['uuid'],
  90.589 +                 self.info['name_label'], self.domid, self.info['uuid'],
  90.590                   new_name, new_uuid)
  90.591          self._unwatchVm()
  90.592          self._releaseDevices()
  90.593 -        self.info['name'] = new_name
  90.594 +        self.info['name_label'] = new_name
  90.595          self.info['uuid'] = new_uuid
  90.596          self.vmpath = XS_VMROOT + new_uuid
  90.597          self._storeVmDetails()
  90.598 @@ -1067,10 +1136,10 @@ class XendDomainInfo:
  90.599  
  90.600  
  90.601      def _preserve(self):
  90.602 -        log.info("Preserving dead domain %s (%d).", self.info['name'],
  90.603 +        log.info("Preserving dead domain %s (%d).", self.info['name_label'],
  90.604                   self.domid)
  90.605          self._unwatchVm()
  90.606 -        self._storeDom('xend/shutdown_completed', 'True')
  90.607 +        self.storeDom('xend/shutdown_completed', 'True')
  90.608          self._stateSet(DOM_STATE_HALTED)
  90.609  
  90.610      #
  90.611 @@ -1084,7 +1153,7 @@ class XendDomainInfo:
  90.612              if not corefile:
  90.613                  this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
  90.614                  corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
  90.615 -                                  self.info['name'], self.domid)
  90.616 +                                  self.info['name_label'], self.domid)
  90.617                  
  90.618              if os.path.isdir(corefile):
  90.619                  raise XendError("Cannot dump core in a directory: %s" %
  90.620 @@ -1095,7 +1164,7 @@ class XendDomainInfo:
  90.621              corefile_incomp = corefile+'-incomplete'
  90.622              os.rename(corefile, corefile_incomp)
  90.623              log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
  90.624 -                          self.domid, self.info['name'])
  90.625 +                          self.domid, self.info['name_label'])
  90.626              raise XendError("Failed to dump core: %s" %  str(ex))
  90.627  
  90.628      #
  90.629 @@ -1117,8 +1186,8 @@ class XendDomainInfo:
  90.630  
  90.631          @raise: VmError for invalid devices
  90.632          """
  90.633 -        for (devclass, config) in self.info.all_devices_sxpr():
  90.634 -            if devclass in XendDevices.valid_devices():
  90.635 +        for (devclass, config) in self.info.get('devices', {}).values():
  90.636 +            if devclass in XendDevices.valid_devices():            
  90.637                  log.info("createDevice: %s : %s" % (devclass, config))
  90.638                  self._createDevice(devclass, config)
  90.639  
  90.640 @@ -1139,7 +1208,7 @@ class XendDomainInfo:
  90.641                          # there's nothing more we can do.
  90.642                          log.exception(
  90.643                             "Device release failed: %s; %s; %s",
  90.644 -                           self.info['name'], devclass, dev)
  90.645 +                           self.info['name_label'], devclass, dev)
  90.646              if t.commit():
  90.647                  break
  90.648  
  90.649 @@ -1211,11 +1280,12 @@ class XendDomainInfo:
  90.650  
  90.651          log.debug('XendDomainInfo.constructDomain')
  90.652  
  90.653 -        hvm = (self._infoIsSet('image') and
  90.654 -               sxp.name(self.info['image']) == "hvm")
  90.655 +        image_cfg = self.info.get('image', {})
  90.656 +        hvm = image_cfg.has_key('hvm')
  90.657 +
  90.658          if hvm:
  90.659              info = xc.xeninfo()
  90.660 -            if not 'hvm' in info['xen_caps']:
  90.661 +            if 'hvm' not in info['xen_caps']:
  90.662                  raise VmError("HVM guest support is unavailable: is VT/AMD-V "
  90.663                                "supported by your CPU and enabled in your "
  90.664                                "BIOS?")
  90.665 @@ -1228,14 +1298,14 @@ class XendDomainInfo:
  90.666  
  90.667          if self.domid < 0:
  90.668              raise VmError('Creating domain failed: name=%s' %
  90.669 -                          self.info['name'])
  90.670 +                          self.info['name_label'])
  90.671  
  90.672          self.dompath = GetDomainPath(self.domid)
  90.673  
  90.674          self._recreateDom()
  90.675  
  90.676          # Set maximum number of vcpus in domain
  90.677 -        xc.domain_max_vcpus(self.domid, int(self.info['vcpus']))
  90.678 +        xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number']))
  90.679  
  90.680  
  90.681      def _introduceDomain(self):
  90.682 @@ -1256,7 +1326,7 @@ class XendDomainInfo:
  90.683  
  90.684          # if we have a boot loader but no image, then we need to set things
  90.685          # up by running the boot loader non-interactively
  90.686 -        if self._infoIsSet('bootloader') and not self._infoIsSet('image'):
  90.687 +        if self.info.get('bootloader') and self.info.get('image'):
  90.688              self._configureBootloader()
  90.689  
  90.690          if not self._infoIsSet('image'):
  90.691 @@ -1264,11 +1334,12 @@ class XendDomainInfo:
  90.692  
  90.693          try:
  90.694              self.image = image.create(self,
  90.695 +                                      self.info,
  90.696                                        self.info['image'],
  90.697 -                                      self.info.all_devices_sxpr())
  90.698 +                                      self.info['devices'])
  90.699  
  90.700 -            localtime = self.info.get('localtime', 0)
  90.701 -            if localtime is not None and localtime == 1:
  90.702 +            localtime = self.info.get('localtime', False)
  90.703 +            if localtime:
  90.704                  xc.domain_set_time_offset(self.domid)
  90.705  
  90.706              xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
  90.707 @@ -1284,12 +1355,12 @@ class XendDomainInfo:
  90.708              # the various headrooms necessary, given the raw configured
  90.709              # values. maxmem, memory, and shadow are all in KiB.
  90.710              maxmem = self.image.getRequiredAvailableMemory(
  90.711 -                self.info['maxmem'] * 1024)
  90.712 +                self.info['memory_static_min'] * 1024)
  90.713              memory = self.image.getRequiredAvailableMemory(
  90.714 -                self.info['memory'] * 1024)
  90.715 +                self.info['memory_static_max'] * 1024)
  90.716              shadow = self.image.getRequiredShadowMemory(
  90.717                  self.info['shadow_memory'] * 1024,
  90.718 -                self.info['maxmem'] * 1024)
  90.719 +                self.info['memory_static_max'] * 1024)
  90.720  
  90.721              # Round shadow up to a multiple of a MiB, as shadow_mem_control
  90.722              # takes MiB and we must not round down and end up under-providing.
  90.723 @@ -1317,7 +1388,7 @@ class XendDomainInfo:
  90.724  
  90.725              self._createDevices()
  90.726  
  90.727 -            if self.info['bootloader'] not in [None, 'kernel_external']:
  90.728 +            if self.info['bootloader']:
  90.729                  self.image.cleanupBootloading()
  90.730  
  90.731              self.info['start_time'] = time.time()
  90.732 @@ -1325,7 +1396,7 @@ class XendDomainInfo:
  90.733              self._stateSet(DOM_STATE_RUNNING)
  90.734          except RuntimeError, exn:
  90.735              log.exception("XendDomainInfo.initDomain: exception occurred")
  90.736 -            if self.info['bootloader'] not in [None, 'kernel_external'] \
  90.737 +            if self.info['bootloader'] not in (None, 'kernel_external') \
  90.738                     and self.image is not None:
  90.739                  self.image.cleanupBootloading()
  90.740              raise VmError(str(exn))
  90.741 @@ -1338,7 +1409,6 @@ class XendDomainInfo:
  90.742          self.refresh_shutdown_lock.acquire()
  90.743          try:
  90.744              self.unwatchShutdown()
  90.745 -
  90.746              self._releaseDevices()
  90.747  
  90.748              if self.image:
  90.749 @@ -1459,14 +1529,14 @@ class XendDomainInfo:
  90.750  
  90.751      def _configureBootloader(self):
  90.752          """Run the bootloader if we're configured to do so."""
  90.753 -        if not self.info['bootloader']:
  90.754 +        if not self.info.get('bootloader'):
  90.755              return
  90.756          blcfg = None
  90.757          # FIXME: this assumes that we want to use the first disk device
  90.758 -        for (n, c) in self.info.all_devices_sxpr():
  90.759 -            if not n or not c or not(n in ["vbd", "tap"]):
  90.760 +        for devuuid, (devtype, devinfo) in self.info.all_devices_sxpr():
  90.761 +            if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
  90.762                  continue
  90.763 -            disk = sxp.child_value(c, "uname")
  90.764 +            disk = devinfo.get('uname')
  90.765              if disk is None:
  90.766                  continue
  90.767              fn = blkdev_uname_to_file(disk)
  90.768 @@ -1478,7 +1548,8 @@ class XendDomainInfo:
  90.769              msg = "Had a bootloader specified, but can't find disk"
  90.770              log.error(msg)
  90.771              raise VmError(msg)
  90.772 -        self.info['image'] = blcfg
  90.773 +        
  90.774 +        self.info.update_with_image_sxp(blcfg)
  90.775  
  90.776      # 
  90.777      # VM Functions
  90.778 @@ -1516,7 +1587,8 @@ class XendDomainInfo:
  90.779          if arch.type == "x86":
  90.780              # 1MB per vcpu plus 4Kib/Mib of RAM.  This is higher than 
  90.781              # the minimum that Xen would allocate if no value were given.
  90.782 -            overhead_kb = self.info['vcpus'] * 1024 + self.info['maxmem'] * 4
  90.783 +            overhead_kb = self.info['vcpus_number'] * 1024 + \
  90.784 +                          self.info['memory_static_max'] * 4
  90.785              overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
  90.786              # The domain might already have some shadow memory
  90.787              overhead_kb -= xc.shadow_mem_control(self.domid) * 1024
  90.788 @@ -1558,12 +1630,15 @@ class XendDomainInfo:
  90.789      def _storeVmDetails(self):
  90.790          to_store = {}
  90.791  
  90.792 -        for k in VM_STORE_ENTRIES:
  90.793 -            if self._infoIsSet(k[0]):
  90.794 -                to_store[k[0]] = str(self.info[k[0]])
  90.795 +        for key in XendConfig.LEGACY_XENSTORE_VM_PARAMS:
  90.796 +            info_key = XendConfig.LEGACY_CFG_TO_XENAPI_CFG.get(key, key)
  90.797 +            if self._infoIsSet(info_key):
  90.798 +                to_store[key] = str(self.info[info_key])
  90.799  
  90.800 -        if self._infoIsSet('image'):
  90.801 -            to_store['image'] = sxp.to_string(self.info['image'])
  90.802 +        if self.info.get('image'):
  90.803 +            image_sxpr = self.info.image_sxpr()
  90.804 +            if image_sxpr:
  90.805 +                to_store['image'] = sxp.to_string(image_sxpr)
  90.806  
  90.807          if self._infoIsSet('security'):
  90.808              secinfo = self.info['security']
  90.809 @@ -1633,8 +1708,9 @@ class XendDomainInfo:
  90.810              raise VmError('Invalid VM Name')
  90.811  
  90.812          dom =  XendDomain.instance().domain_lookup_nr(name)
  90.813 -        if dom and dom != self and not dom.info['dying']:
  90.814 -            raise VmError("VM name '%s' already exists" % name)
  90.815 +        if dom and dom.info['uuid'] != self.info['uuid']:
  90.816 +            raise VmError("VM name '%s' already exists as domain %s" %
  90.817 +                          (name, str(dom.domid)))
  90.818          
  90.819  
  90.820      def update(self, info = None, refresh = True):
  90.821 @@ -1656,6 +1732,7 @@ class XendDomainInfo:
  90.822                      #create new security element
  90.823                      self.info.update({'security':
  90.824                                        [['ssidref', str(info['ssidref'])]]})
  90.825 +                    
  90.826          #ssidref field not used any longer
  90.827          if 'ssidref' in info:
  90.828              info.pop('ssidref')
  90.829 @@ -1663,8 +1740,7 @@ class XendDomainInfo:
  90.830          # make sure state is reset for info
  90.831          # TODO: we should eventually get rid of old_dom_states
  90.832  
  90.833 -        self.info.update(info)
  90.834 -        self.info.validate()
  90.835 +        self.info.update_config(info)
  90.836  
  90.837          if refresh:
  90.838              self.refreshShutdown(info)
  90.839 @@ -1673,11 +1749,11 @@ class XendDomainInfo:
  90.840                    str(self.domid), self.info)
  90.841  
  90.842      def sxpr(self, ignore_store = False):
  90.843 -        result = self.info.get_sxp(domain = self,
  90.844 +        result = self.info.to_sxp(domain = self,
  90.845                                     ignore_devices = ignore_store)
  90.846  
  90.847          if not ignore_store and self.dompath:
  90.848 -            vnc_port = self._readDom('console/vnc-port')
  90.849 +            vnc_port = self.readDom('console/vnc-port')
  90.850              if vnc_port is not None:
  90.851                  result.append(['device',
  90.852                                 ['console', ['vnc-port', str(vnc_port)]]])
  90.853 @@ -1695,9 +1771,15 @@ class XendDomainInfo:
  90.854          return dom_uuid
  90.855      
  90.856      def get_memory_static_max(self):
  90.857 -        return self.info['maxmem']
  90.858 +        return self.info.get('memory_static_max')
  90.859      def get_memory_static_min(self):
  90.860 -        return self.info['memory']
  90.861 +        return self.info.get('memory_static_min')
  90.862 +    def get_memory_dynamic_max(self):
  90.863 +        return self.info.get('memory_dynamic_min')
  90.864 +    def get_memory_dynamic_min(self):
  90.865 +        return self.info.get('memory_dynamic_max')
  90.866 +    
  90.867 +    
  90.868      def get_vcpus_policy(self):
  90.869          sched_id = xc.sched_id_get()
  90.870          if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
  90.871 @@ -1713,31 +1795,29 @@ class XendDomainInfo:
  90.872      def get_bios_boot(self):
  90.873          return '' # TODO
  90.874      def get_platform_std_vga(self):
  90.875 -        return False
  90.876 +        return self.info.get('platform_std_vga', False)    
  90.877      def get_platform_keymap(self):
  90.878          return ''
  90.879      def get_platform_serial(self):
  90.880 -        return '' # TODO
  90.881 +        return self.info.get('platform_serial', '')
  90.882      def get_platform_localtime(self):
  90.883 -        return False # TODO
  90.884 +        return self.info.get('platform_localtime', False)
  90.885      def get_platform_clock_offset(self):
  90.886 -        return False # TODO
  90.887 +        return self.info.get('platform_clock_offset', False)
  90.888      def get_platform_enable_audio(self):
  90.889 -        return False # TODO
  90.890 +        return self.info.get('platform_enable_audio', False)
  90.891 +    def get_platform_keymap(self):
  90.892 +        return self.info.get('platform_keymap', '')
  90.893      def get_builder(self):
  90.894 -        return 'Linux' # TODO
  90.895 +        return self.info.get('builder', 0)
  90.896      def get_boot_method(self):
  90.897 -        bootloader = self.info['bootloader']
  90.898 -        if not bootloader or bootloader not in XEN_API_BOOT_TYPE:
  90.899 -            return 'kernel_external'
  90.900 -        return bootloader
  90.901 -    
  90.902 +        return self.info.get('boot_method', '')
  90.903      def get_kernel_image(self):
  90.904 -        return self.info['kernel_kernel']
  90.905 +        return self.info.get('kernel_kernel', '')
  90.906      def get_kernel_initrd(self):
  90.907 -        return self.info['kernel_initrd']
  90.908 +        return self.info.get('kernel_initrd', '')
  90.909      def get_kernel_args(self):
  90.910 -        return self.info['kernel_args']
  90.911 +        return self.info.get('kernel_args', '')
  90.912      def get_grub_cmdline(self):
  90.913          return '' # TODO
  90.914      def get_pci_bus(self):
  90.915 @@ -1748,25 +1828,26 @@ class XendDomainInfo:
  90.916          return {} # TODO
  90.917      
  90.918      def get_on_shutdown(self):
  90.919 -        after_shutdown = self.info.get('on_poweroff')
  90.920 +        after_shutdown = self.info.get('action_after_shutdown')
  90.921          if not after_shutdown or after_shutdown not in XEN_API_ON_NORMAL_EXIT:
  90.922              return XEN_API_ON_NORMAL_EXIT[-1]
  90.923          return after_shutdown
  90.924  
  90.925      def get_on_reboot(self):
  90.926 -        after_reboot = self.info.get('on_reboot')
  90.927 +        after_reboot = self.info.get('action_after_reboot')
  90.928          if not after_reboot or after_reboot not in XEN_API_ON_NORMAL_EXIT:
  90.929              return XEN_API_ON_NORMAL_EXIT[-1]
  90.930          return after_reboot
  90.931  
  90.932      def get_on_suspend(self):
  90.933 -        after_suspend = self.info.get('on_suspend') # TODO: not supported
  90.934 +        # TODO: not supported        
  90.935 +        after_suspend = self.info.get('action_after_suspend') 
  90.936          if not after_suspend or after_suspend not in XEN_API_ON_NORMAL_EXIT:
  90.937              return XEN_API_ON_NORMAL_EXIT[-1]
  90.938          return after_suspend        
  90.939  
  90.940      def get_on_crash(self):
  90.941 -        after_crash = self.info.get('on_crash')
  90.942 +        after_crash = self.info.get('action_after_crash')
  90.943          if not after_crash or after_crash not in XEN_API_ON_CRASH_BEHAVIOUR:
  90.944              return XEN_API_ON_CRASH_BEHAVIOUR[0]
  90.945          return after_crash
  90.946 @@ -1780,7 +1861,7 @@ class XendDomainInfo:
  90.947  
  90.948          @rtype: dictionary
  90.949          """
  90.950 -        dev_type_config = self.info['device'].get(dev_uuid)
  90.951 +        dev_type_config = self.info['devices'].get(dev_uuid)
  90.952  
  90.953          # shortcut if the domain isn't started because
  90.954          # the devcontrollers will have no better information
  90.955 @@ -1840,7 +1921,7 @@ class XendDomainInfo:
  90.956              config['IO_bandwidth_incoming_kbs'] = 0.0
  90.957              config['IO_bandwidth_outgoing_kbs'] = 0.0
  90.958  
  90.959 -        if dev_class =='vbd':
  90.960 +        if dev_class == 'vbd':
  90.961              config['VDI'] = '' # TODO
  90.962              config['device'] = config.get('dev', '')
  90.963              config['driver'] = 'paravirtualised' # TODO
  90.964 @@ -1984,8 +2065,8 @@ class XendDomainInfo:
  90.965  
  90.966      def __str__(self):
  90.967          return '<domain id=%s name=%s memory=%s state=%s>' % \
  90.968 -               (str(self.domid), self.info['name'],
  90.969 -                str(self.info['memory']), DOM_STATES[self.state])
  90.970 +               (str(self.domid), self.info['name_label'],
  90.971 +                str(self.info['memory_static_min']), DOM_STATES[self.state])
  90.972  
  90.973      __repr__ = __str__
  90.974  
    91.1 --- a/tools/python/xen/xend/XendLogging.py	Sat Dec 02 15:19:50 2006 -0700
    91.2 +++ b/tools/python/xen/xend/XendLogging.py	Mon Dec 04 08:24:41 2006 -0700
    91.3 @@ -16,13 +16,15 @@
    91.4  # Copyright (C) 2005, 2006 XenSource Ltd.
    91.5  #============================================================================
    91.6  
    91.7 -
    91.8 +import os
    91.9 +import stat
   91.10  import tempfile
   91.11  import types
   91.12  import logging
   91.13  import logging.handlers
   91.14  import fcntl
   91.15  
   91.16 +from xen.util import mkdir
   91.17  from xen.xend.server import params
   91.18  
   91.19  
   91.20 @@ -80,6 +82,7 @@ def init(filename, level):
   91.21      global logfilename
   91.22  
   91.23      def openFileHandler(fname):
   91.24 +        mkdir.parents(os.path.dirname(fname), stat.S_IRWXU)
   91.25          return XendRotatingFileHandler(fname, mode = 'a',
   91.26                                         maxBytes = MAX_BYTES,
   91.27                                         backupCount = BACKUP_COUNT)
    92.1 --- a/tools/python/xen/xend/XendStorageRepository.py	Sat Dec 02 15:19:50 2006 -0700
    92.2 +++ b/tools/python/xen/xend/XendStorageRepository.py	Mon Dec 04 08:24:41 2006 -0700
    92.3 @@ -19,10 +19,12 @@
    92.4  # The default QCOW Xen API Storage Repository
    92.5  #
    92.6  
    92.7 +import commands
    92.8  import os
    92.9 -import commands
   92.10 +import stat
   92.11  import threading
   92.12  
   92.13 +from xen.util import mkdir
   92.14  from xen.xend import uuid
   92.15  from xen.xend.XendError import XendError
   92.16  from xen.xend.XendVDI import *
   92.17 @@ -98,10 +100,7 @@ class XendStorageRepository:
   92.18          """
   92.19          self.lock.acquire()
   92.20          try:
   92.21 -            # create directory if /var/lib/xend/storage does not exist
   92.22 -            if not os.path.exists(XEND_STORAGE_DIR):
   92.23 -                os.makedirs(XEND_STORAGE_DIR)
   92.24 -                os.chmod(XEND_STORAGE_DIR, 0700)
   92.25 +            mkdir.parents(XEND_STORAGE_DIR, stat.S_IRWXU)
   92.26  
   92.27              # scan the directory and populate self.images
   92.28              total_used = 0
    93.1 --- a/tools/python/xen/xend/image.py	Sat Dec 02 15:19:50 2006 -0700
    93.2 +++ b/tools/python/xen/xend/image.py	Mon Dec 04 08:24:41 2006 -0700
    93.3 @@ -23,7 +23,7 @@ import math
    93.4  import signal
    93.5  
    93.6  import xen.lowlevel.xc
    93.7 -from xen.xend import sxp
    93.8 +from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
    93.9  from xen.xend.XendError import VmError, XendError
   93.10  from xen.xend.XendLogging import log
   93.11  from xen.xend.server.netif import randomMAC
   93.12 @@ -31,19 +31,18 @@ from xen.xend.xenstore.xswatch import xs
   93.13  from xen.xend import arch
   93.14  from xen.xend import FlatDeviceTree
   93.15  
   93.16 -
   93.17  xc = xen.lowlevel.xc.xc()
   93.18  
   93.19 -
   93.20  MAX_GUEST_CMDLINE = 1024
   93.21  
   93.22  
   93.23 -def create(vm, imageConfig, deviceConfig):
   93.24 +def create(vm, vmConfig, imageConfig, deviceConfig):
   93.25      """Create an image handler for a vm.
   93.26  
   93.27      @return ImageHandler instance
   93.28      """
   93.29 -    return findImageHandlerClass(imageConfig)(vm, imageConfig, deviceConfig)
   93.30 +    return findImageHandlerClass(imageConfig)(vm, vmConfig, imageConfig,
   93.31 +                                              deviceConfig)
   93.32  
   93.33  
   93.34  class ImageHandler:
   93.35 @@ -66,34 +65,20 @@ class ImageHandler:
   93.36      ostype = None
   93.37  
   93.38  
   93.39 -    def __init__(self, vm, imageConfig, deviceConfig):
   93.40 +    def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
   93.41          self.vm = vm
   93.42  
   93.43          self.kernel = None
   93.44          self.ramdisk = None
   93.45          self.cmdline = None
   93.46  
   93.47 -        self.configure(imageConfig, deviceConfig)
   93.48 -
   93.49 -    def configure(self, imageConfig, _):
   93.50 -        """Config actions common to all unix-like domains."""
   93.51 -
   93.52 -        def get_cfg(name, default = None):
   93.53 -            return sxp.child_value(imageConfig, name, default)
   93.54 +        self.configure(vmConfig, imageConfig, deviceConfig)
   93.55  
   93.56 -        self.kernel = get_cfg("kernel")
   93.57 -        self.cmdline = ""
   93.58 -        ip = get_cfg("ip")
   93.59 -        if ip:
   93.60 -            self.cmdline += " ip=" + ip
   93.61 -        root = get_cfg("root")
   93.62 -        if root:
   93.63 -            self.cmdline += " root=" + root
   93.64 -        args = get_cfg("args")
   93.65 -        if args:
   93.66 -            self.cmdline += " " + args
   93.67 -        self.ramdisk = get_cfg("ramdisk", '')
   93.68 -        
   93.69 +    def configure(self, vmConfig, imageConfig, _):
   93.70 +        """Config actions common to all unix-like domains."""
   93.71 +        self.kernel = vmConfig['kernel_kernel']
   93.72 +        self.cmdline = vmConfig['kernel_args']
   93.73 +        self.ramdisk = vmConfig['kernel_initrd']
   93.74          self.vm.storeVm(("image/ostype", self.ostype),
   93.75                          ("image/kernel", self.kernel),
   93.76                          ("image/cmdline", self.cmdline),
   93.77 @@ -181,6 +166,10 @@ class ImageHandler:
   93.78          pass
   93.79  
   93.80  
   93.81 +    def recreate(self):
   93.82 +        pass
   93.83 +
   93.84 +
   93.85  class LinuxImageHandler(ImageHandler):
   93.86  
   93.87      ostype = "linux"
   93.88 @@ -214,8 +203,8 @@ class PPC_LinuxImageHandler(LinuxImageHa
   93.89  
   93.90      ostype = "linux"
   93.91  
   93.92 -    def configure(self, imageConfig, deviceConfig):
   93.93 -        LinuxImageHandler.configure(self, imageConfig, deviceConfig)
   93.94 +    def configure(self, vmConfig, imageConfig, deviceConfig):
   93.95 +        LinuxImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
   93.96          self.imageConfig = imageConfig
   93.97  
   93.98      def buildDomain(self):
   93.99 @@ -248,37 +237,42 @@ class PPC_LinuxImageHandler(LinuxImageHa
  93.100  
  93.101  class HVMImageHandler(ImageHandler):
  93.102  
  93.103 -    def __init__(self, vm, imageConfig, deviceConfig):
  93.104 -        ImageHandler.__init__(self, vm, imageConfig, deviceConfig)
  93.105 +    ostype = "hvm"
  93.106 +
  93.107 +    def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
  93.108 +        ImageHandler.__init__(self, vm, vmConfig, imageConfig, deviceConfig)
  93.109          self.shutdownWatch = None
  93.110 +        self.rebootFeatureWatch = None
  93.111  
  93.112 -    def configure(self, imageConfig, deviceConfig):
  93.113 -        ImageHandler.configure(self, imageConfig, deviceConfig)
  93.114 +    def configure(self, vmConfig, imageConfig, deviceConfig):
  93.115 +        ImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
  93.116  
  93.117          info = xc.xeninfo()
  93.118 -        if not 'hvm' in info['xen_caps']:
  93.119 +        if 'hvm' not in info['xen_caps']:
  93.120              raise VmError("HVM guest support is unavailable: is VT/AMD-V "
  93.121                            "supported by your CPU and enabled in your BIOS?")
  93.122  
  93.123          self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
  93.124 -        self.device_model = sxp.child_value(imageConfig, 'device_model')
  93.125 +        self.device_model = imageConfig['hvm'].get('device_model')
  93.126          if not self.device_model:
  93.127              raise VmError("hvm: missing device model")
  93.128 -        self.display = sxp.child_value(imageConfig, 'display')
  93.129 -        self.xauthority = sxp.child_value(imageConfig, 'xauthority')
  93.130 -        self.vncconsole = sxp.child_value(imageConfig, 'vncconsole')
  93.131 +        
  93.132 +        self.display = imageConfig['hvm'].get('display')
  93.133 +        self.xauthority = imageConfig['hvm'].get('xauthority')
  93.134 +        self.vncconsole = imageConfig['hvm'].get('vncconsole')
  93.135  
  93.136          self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
  93.137                          ("image/device-model", self.device_model),
  93.138                          ("image/display", self.display))
  93.139  
  93.140 -        self.pid = 0
  93.141 +        self.pid = None
  93.142  
  93.143          self.dmargs += self.configVNC(imageConfig)
  93.144  
  93.145 -        self.pae  = int(sxp.child_value(imageConfig, 'pae',  1))
  93.146 -        self.acpi = int(sxp.child_value(imageConfig, 'acpi', 1))
  93.147 -        self.apic = int(sxp.child_value(imageConfig, 'apic', 1))
  93.148 +        self.pae  = imageConfig['hvm'].get('pae', 0)
  93.149 +        self.apic  = imageConfig['hvm'].get('apic', 0)
  93.150 +        self.acpi  = imageConfig['hvm']['devices'].get('acpi', 0)
  93.151 +        
  93.152  
  93.153      def buildDomain(self):
  93.154          store_evtchn = self.vm.getStorePort()
  93.155 @@ -295,6 +289,7 @@ class HVMImageHandler(ImageHandler):
  93.156          log.debug("apic           = %d", self.apic)
  93.157  
  93.158          self.register_shutdown_watch()
  93.159 +        self.register_reboot_feature_watch()
  93.160  
  93.161          return xc.hvm_build(domid          = self.vm.getDomid(),
  93.162                              image          = self.kernel,
  93.163 @@ -312,8 +307,10 @@ class HVMImageHandler(ImageHandler):
  93.164                     'localtime', 'serial', 'stdvga', 'isa', 'vcpus',
  93.165                     'acpi', 'usb', 'usbdevice', 'keymap' ]
  93.166          ret = []
  93.167 +        hvmDeviceConfig = imageConfig['hvm']['devices']
  93.168 +        
  93.169          for a in dmargs:
  93.170 -            v = sxp.child_value(imageConfig, a)
  93.171 +            v = hvmDeviceConfig.get(a)
  93.172  
  93.173              # python doesn't allow '-' in variable names
  93.174              if a == 'stdvga': a = 'std-vga'
  93.175 @@ -328,7 +325,7 @@ class HVMImageHandler(ImageHandler):
  93.176                      ret.append("-%s" % a)
  93.177                      ret.append("%s" % v)
  93.178  
  93.179 -            if a in ['fda', 'fdb' ]:
  93.180 +            if a in ['fda', 'fdb']:
  93.181                  if v:
  93.182                      if not os.path.isabs(v):
  93.183                          raise VmError("Floppy file %s does not exist." % v)
  93.184 @@ -336,26 +333,27 @@ class HVMImageHandler(ImageHandler):
  93.185  
  93.186          # Handle disk/network related options
  93.187          mac = None
  93.188 -        ret = ret + ["-domain-name", "%s" % self.vm.info['name']]
  93.189 +        ret = ret + ["-domain-name", str(self.vm.info['name_label'])]
  93.190          nics = 0
  93.191 -        for (name, info) in deviceConfig:
  93.192 -            if name == 'vbd':
  93.193 -                uname = sxp.child_value(info, 'uname')
  93.194 +        
  93.195 +        for devuuid, (devtype, devinfo) in deviceConfig.items():
  93.196 +            if devtype == 'vbd':
  93.197 +                uname = devinfo['uname']
  93.198                  if uname is not None and 'file:' in uname:
  93.199                      (_, vbdparam) = string.split(uname, ':', 1)
  93.200                      if not os.path.isfile(vbdparam):
  93.201                          raise VmError('Disk image does not exist: %s' %
  93.202                                        vbdparam)
  93.203 -            if name == 'vif':
  93.204 -                type = sxp.child_value(info, 'type')
  93.205 -                if type != 'ioemu':
  93.206 +            if devtype == 'vif':
  93.207 +                dtype = devinfo.get('type', 'ioemu')
  93.208 +                if dtype != 'ioemu':
  93.209                      continue
  93.210                  nics += 1
  93.211 -                mac = sxp.child_value(info, 'mac')
  93.212 +                mac = devinfo.get('mac')
  93.213                  if mac == None:
  93.214                      mac = randomMAC()
  93.215 -                bridge = sxp.child_value(info, 'bridge', 'xenbr0')
  93.216 -                model = sxp.child_value(info, 'model', 'rtl8139')
  93.217 +                bridge = devinfo.get('bridge', 'xenbr0')
  93.218 +                model = devinfo.get('model', 'rtl8139')
  93.219                  ret.append("-net")
  93.220                  ret.append("nic,vlan=%d,macaddr=%s,model=%s" %
  93.221                             (nics, mac, model))
  93.222 @@ -363,31 +361,32 @@ class HVMImageHandler(ImageHandler):
  93.223                  ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
  93.224          return ret
  93.225  
  93.226 -    def configVNC(self, config):
  93.227 +    def configVNC(self, imageConfig):
  93.228          # Handle graphics library related options
  93.229 -        vnc = sxp.child_value(config, 'vnc')
  93.230 -        sdl = sxp.child_value(config, 'sdl')
  93.231 +        vnc = imageConfig.get('vnc')
  93.232 +        sdl = imageConfig.get('sdl')
  93.233          ret = []
  93.234 -        nographic = sxp.child_value(config, 'nographic')
  93.235 +        nographic = imageConfig.get('nographic')
  93.236  
  93.237          # get password from VM config (if password omitted, None)
  93.238 -        vncpasswd_vmconfig = sxp.child_value(config, 'vncpasswd')
  93.239 +        vncpasswd_vmconfig = imageConfig.get('vncpasswd')
  93.240  
  93.241          if nographic:
  93.242              ret.append('-nographic')
  93.243              return ret
  93.244  
  93.245          if vnc:
  93.246 -            vncdisplay = int(sxp.child_value(config, 'vncdisplay',
  93.247 -                                             self.vm.getDomid()))
  93.248 +            vncdisplay = imageConfig.get('vncdisplay',
  93.249 +                                         int(self.vm.getDomid()))
  93.250 +            vncunused = imageConfig.get('vncunused')
  93.251  
  93.252 -            vncunused = sxp.child_value(config, 'vncunused')
  93.253              if vncunused:
  93.254                  ret += ['-vncunused']
  93.255              else:
  93.256                  ret += ['-vnc', '%d' % vncdisplay]
  93.257  
  93.258 -            vnclisten = sxp.child_value(config, 'vnclisten')
  93.259 +            vnclisten = imageConfig.get('vnclisten')
  93.260 +
  93.261              if not(vnclisten):
  93.262                  vnclisten = (xen.xend.XendRoot.instance().
  93.263                               get_vnclisten_address())
  93.264 @@ -423,21 +422,37 @@ class HVMImageHandler(ImageHandler):
  93.265          if self.vncconsole:
  93.266              args = args + ([ "-vncviewer" ])
  93.267          log.info("spawning device models: %s %s", self.device_model, args)
  93.268 +        # keep track of pid and spawned options to kill it later
  93.269          self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
  93.270 +        self.vm.storeDom("image/device-model-pid", self.pid)
  93.271          log.info("device model pid: %d", self.pid)
  93.272  
  93.273 +    def recreate(self):
  93.274 +        self.register_shutdown_watch()
  93.275 +        self.register_reboot_feature_watch()
  93.276 +        self.pid = self.vm.gatherDom(('image/device-model-pid', int))
  93.277 +
  93.278      def destroy(self):
  93.279 -        self.unregister_shutdown_watch();
  93.280 -        if not self.pid:
  93.281 -            return
  93.282 -        os.kill(self.pid, signal.SIGKILL)
  93.283 -        os.waitpid(self.pid, 0)
  93.284 -        self.pid = 0
  93.285 +        self.unregister_shutdown_watch()
  93.286 +        self.unregister_reboot_feature_watch();
  93.287 +        if self.pid:
  93.288 +            try:
  93.289 +                os.kill(self.pid, signal.SIGKILL)
  93.290 +            except OSError, exn:
  93.291 +                log.exception(exn)
  93.292 +            try:
  93.293 +                os.waitpid(self.pid, 0)
  93.294 +            except OSError, exn:
  93.295 +                # This is expected if Xend has been restarted within the
  93.296 +                # life of this domain.  In this case, we can kill the process,
  93.297 +                # but we can't wait for it because it's not our child.
  93.298 +                pass
  93.299 +            self.pid = None
  93.300  
  93.301      def register_shutdown_watch(self):
  93.302          """ add xen store watch on control/shutdown """
  93.303 -        self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", \
  93.304 -                                    self.hvm_shutdown)
  93.305 +        self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown",
  93.306 +                                     self.hvm_shutdown)
  93.307          log.debug("hvm shutdown watch registered")
  93.308  
  93.309      def unregister_shutdown_watch(self):
  93.310 @@ -456,28 +471,55 @@ class HVMImageHandler(ImageHandler):
  93.311          """ watch call back on node control/shutdown,
  93.312              if node changed, this function will be called
  93.313          """
  93.314 -        from xen.xend.XendConstants import DOMAIN_SHUTDOWN_REASONS
  93.315          xd = xen.xend.XendDomain.instance()
  93.316          try:
  93.317              vm = xd.domain_lookup( self.vm.getDomid() )
  93.318          except XendError:
  93.319              # domain isn't registered, no need to clean it up.
  93.320 -            return
  93.321 +            return False
  93.322  
  93.323          reason = vm.getShutdownReason()
  93.324          log.debug("hvm_shutdown fired, shutdown reason=%s", reason)
  93.325 -        for x in DOMAIN_SHUTDOWN_REASONS.keys():
  93.326 -            if DOMAIN_SHUTDOWN_REASONS[x] == reason:
  93.327 -                vm.info['shutdown'] = 1
  93.328 -                vm.info['shutdown_reason'] = x
  93.329 -                vm.refreshShutdown(vm.info)
  93.330 +        if reason in REVERSE_DOMAIN_SHUTDOWN_REASONS:
  93.331 +            vm.info['shutdown'] = 1
  93.332 +            vm.info['shutdown_reason'] = \
  93.333 +                REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]
  93.334 +            vm.refreshShutdown(vm.info)
  93.335  
  93.336 -        return 1 # Keep watching
  93.337 +        return True # Keep watching
  93.338 +
  93.339 +    def register_reboot_feature_watch(self):
  93.340 +        """ add xen store watch on control/feature-reboot """
  93.341 +        self.rebootFeatureWatch = xswatch(self.vm.dompath + "/control/feature-reboot", \
  93.342 +                                         self.hvm_reboot_feature)
  93.343 +        log.debug("hvm reboot feature watch registered")
  93.344 +
  93.345 +    def unregister_reboot_feature_watch(self):
  93.346 +        """Remove the watch on the control/feature-reboot, if any. Nothrow
  93.347 +        guarantee."""
  93.348 +
  93.349 +        try:
  93.350 +            if self.rebootFeatureWatch:
  93.351 +                self.rebootFeatureWatch.unwatch()
  93.352 +        except:
  93.353 +            log.exception("Unwatching hvm reboot feature watch failed.")
  93.354 +        self.rebootFeatureWatch = None
  93.355 +        log.debug("hvm reboot feature watch unregistered")
  93.356 +
  93.357 +    def hvm_reboot_feature(self, _):
  93.358 +        """ watch call back on node control/feature-reboot,
  93.359 +            if node changed, this function will be called
  93.360 +        """
  93.361 +        status = self.vm.readDom('control/feature-reboot')
  93.362 +        log.debug("hvm_reboot_feature fired, module status=%s", status)
  93.363 +        if status == '1':
  93.364 +            self.unregister_shutdown_watch()
  93.365 +
  93.366 +        return True # Keep watching
  93.367 +
  93.368  
  93.369  class IA64_HVM_ImageHandler(HVMImageHandler):
  93.370  
  93.371 -    ostype = "hvm"
  93.372 -
  93.373      def getRequiredAvailableMemory(self, mem_kb):
  93.374          page_kb = 16
  93.375          # ROM size for guest firmware, ioreq page and xenstore page
  93.376 @@ -490,8 +532,6 @@ class IA64_HVM_ImageHandler(HVMImageHand
  93.377  
  93.378  class X86_HVM_ImageHandler(HVMImageHandler):
  93.379  
  93.380 -    ostype = "hvm"
  93.381 -
  93.382      def getRequiredAvailableMemory(self, mem_kb):
  93.383          # Add 8 MiB overhead for QEMU's video RAM.
  93.384          return mem_kb + 8192
  93.385 @@ -529,10 +569,10 @@ def findImageHandlerClass(image):
  93.386      @param image config
  93.387      @return ImageHandler subclass or None
  93.388      """
  93.389 -    type = sxp.name(image)
  93.390 -    if type is None:
  93.391 +    image_type = image['type']
  93.392 +    if image_type is None:
  93.393          raise VmError('missing image type')
  93.394      try:
  93.395 -        return _handlers[arch.type][type]
  93.396 +        return _handlers[arch.type][image_type]
  93.397      except KeyError:
  93.398 -        raise VmError('unknown image type: ' + type)
  93.399 +        raise VmError('unknown image type: ' + image_type)
    94.1 --- a/tools/python/xen/xend/server/DevController.py	Sat Dec 02 15:19:50 2006 -0700
    94.2 +++ b/tools/python/xen/xend/server/DevController.py	Mon Dec 04 08:24:41 2006 -0700
    94.3 @@ -17,6 +17,7 @@
    94.4  #============================================================================
    94.5  
    94.6  from threading import Event
    94.7 +import types
    94.8  
    94.9  from xen.xend import sxp
   94.10  from xen.xend.XendError import VmError
   94.11 @@ -86,7 +87,7 @@ class DevController:
   94.12  
   94.13          import xen.xend.XendDomain
   94.14          xd = xen.xend.XendDomain.instance()
   94.15 -        backdom_name = sxp.child_value(config, 'backend')
   94.16 +        backdom_name = config.get('backend')
   94.17          if backdom_name is None:
   94.18              backdom = xen.xend.XendDomain.DOM0_ID
   94.19          else:
   94.20 @@ -223,7 +224,7 @@ class DevController:
   94.21          configDict = self.getDeviceConfiguration(devid)
   94.22          sxpr = [self.deviceClass]
   94.23          for key, val in configDict.items():
   94.24 -            if type(val) == type(list()):
   94.25 +            if isinstance(val, (types.ListType, types.TupleType)):
   94.26                  for v in val:
   94.27                      sxpr.append([key, v])
   94.28              else:
   94.29 @@ -405,7 +406,7 @@ class DevController:
   94.30          import xen.xend.XendDomain
   94.31          xd = xen.xend.XendDomain.instance()
   94.32  
   94.33 -        backdom_name = sxp.child_value(config, 'backend')
   94.34 +        backdom_name = config.get('backend')
   94.35          if backdom_name:
   94.36              backdom = xd.domain_lookup_nr(backdom_name)
   94.37          else:
    95.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Sat Dec 02 15:19:50 2006 -0700
    95.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Mon Dec 04 08:24:41 2006 -0700
    95.3 @@ -21,6 +21,7 @@ import xen.lowlevel.xc
    95.4  
    95.5  from xen.xend.XendLogging import log
    95.6  from xen.xend import osdep
    95.7 +from xen.util import mkdir
    95.8  
    95.9  import relocate
   95.10  import SrvServer
   95.11 @@ -108,8 +109,7 @@ class Daemon:
   95.12          # so _before_ we close stderr.
   95.13          try:
   95.14              parent = os.path.dirname(XEND_DEBUG_LOG)
   95.15 -            if not os.path.exists(parent):
   95.16 -                os.makedirs(parent, stat.S_IRWXU)
   95.17 +            mkdir.parents(parent, stat.S_IRWXU)
   95.18              fd = os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT|os.O_APPEND)
   95.19          except Exception, exn:
   95.20              print >>sys.stderr, exn
    96.1 --- a/tools/python/xen/xend/server/SrvServer.py	Sat Dec 02 15:19:50 2006 -0700
    96.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Mon Dec 04 08:24:41 2006 -0700
    96.3 @@ -154,7 +154,7 @@ def create():
    96.4      if api_cfg:
    96.5          try:
    96.6              addrs = [(str(x[0]).split(':'),
    96.7 -                      len(x) > 1 and x[1] or XendAPI.AUTH_NONE,
    96.8 +                      len(x) > 1 and x[1] or XendAPI.AUTH_PAM,
    96.9                        len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
   96.10                        or None)
   96.11                       for x in api_cfg]
    97.1 --- a/tools/python/xen/xend/server/blkif.py	Sat Dec 02 15:19:50 2006 -0700
    97.2 +++ b/tools/python/xen/xend/server/blkif.py	Mon Dec 04 08:24:41 2006 -0700
    97.3 @@ -21,7 +21,6 @@ import string
    97.4  
    97.5  from xen.util import blkif
    97.6  from xen.util import security
    97.7 -from xen.xend import sxp
    97.8  from xen.xend.XendError import VmError
    97.9  from xen.xend.server.DevController import DevController
   97.10  
   97.11 @@ -37,9 +36,9 @@ class BlkifController(DevController):
   97.12  
   97.13      def getDeviceDetails(self, config):
   97.14          """@see DevController.getDeviceDetails"""
   97.15 -        uname = sxp.child_value(config, 'uname', '')
   97.16 -        dev = sxp.child_value(config, 'dev', '')
   97.17 -
   97.18 +        uname = config.get('uname', '')
   97.19 +        dev = config.get('dev', '')
   97.20 +        
   97.21          if 'ioemu:' in dev:
   97.22              (_, dev) = string.split(dev, ':', 1)
   97.23          try:
   97.24 @@ -59,17 +58,17 @@ class BlkifController(DevController):
   97.25              except ValueError:
   97.26                  (typ, params) = ("", "")
   97.27  
   97.28 -        mode = sxp.child_value(config, 'mode', 'r')
   97.29 +        mode = config.get('mode', 'r')
   97.30          if mode not in ('r', 'w', 'w!'):
   97.31              raise VmError('Invalid mode')
   97.32  
   97.33 -        back = { 'dev'    : dev,
   97.34 -                 'type'   : typ,
   97.35 -                 'params' : params,
   97.36 -                 'mode'   : mode
   97.37 -               }
   97.38 +        back = {'dev'    : dev,
   97.39 +                'type'   : typ,
   97.40 +                'params' : params,
   97.41 +                'mode'   : mode,
   97.42 +                }
   97.43  
   97.44 -        uuid = sxp.child_value(config, 'uuid')
   97.45 +        uuid = config.get('uuid')
   97.46          if uuid:
   97.47              back['uuid'] = uuid
   97.48  
    98.1 --- a/tools/python/xen/xend/server/iopif.py	Sat Dec 02 15:19:50 2006 -0700
    98.2 +++ b/tools/python/xen/xend/server/iopif.py	Mon Dec 04 08:24:41 2006 -0700
    98.3 @@ -22,7 +22,6 @@ import types
    98.4  
    98.5  import xen.lowlevel.xc
    98.6  
    98.7 -from xen.xend import sxp
    98.8  from xen.xend.XendError import VmError
    98.9  
   98.10  from xen.xend.server.DevController import DevController
   98.11 @@ -49,13 +48,12 @@ class IOPortsController(DevController):
   98.12      def __init__(self, vm):
   98.13          DevController.__init__(self, vm)
   98.14  
   98.15 -
   98.16      def getDeviceDetails(self, config):
   98.17          """@see DevController.getDeviceDetails"""
   98.18  
   98.19          def get_param(field):
   98.20              try:
   98.21 -                val = sxp.child_value(config, field)
   98.22 +                val = config.get(field)
   98.23  
   98.24                  if not val:
   98.25                      raise VmError('ioports: Missing %s config setting' % field)
    99.1 --- a/tools/python/xen/xend/server/irqif.py	Sat Dec 02 15:19:50 2006 -0700
    99.2 +++ b/tools/python/xen/xend/server/irqif.py	Mon Dec 04 08:24:41 2006 -0700
    99.3 @@ -45,7 +45,7 @@ class IRQController(DevController):
    99.4  
    99.5          def get_param(field):
    99.6              try:
    99.7 -                val = sxp.child_value(config, field)
    99.8 +                val = config.get(field)
    99.9  
   99.10                  if not val:
   99.11                      raise VmError('irq: Missing %s config setting' % field)
   100.1 --- a/tools/python/xen/xend/server/netif.py	Sat Dec 02 15:19:50 2006 -0700
   100.2 +++ b/tools/python/xen/xend/server/netif.py	Mon Dec 04 08:24:41 2006 -0700
   100.3 @@ -24,7 +24,6 @@ import os
   100.4  import random
   100.5  import re
   100.6  
   100.7 -from xen.xend import sxp
   100.8  from xen.xend import XendRoot
   100.9  from xen.xend.server.DevController import DevController
  100.10  
  100.11 @@ -139,22 +138,15 @@ class NetifController(DevController):
  100.12      def getDeviceDetails(self, config):
  100.13          """@see DevController.getDeviceDetails"""
  100.14  
  100.15 -        def _get_config_ipaddr(config):
  100.16 -            val = []
  100.17 -            for ipaddr in sxp.children(config, elt='ip'):
  100.18 -                val.append(sxp.child0(ipaddr))
  100.19 -            return val
  100.20 -
  100.21          script = os.path.join(xroot.network_script_dir,
  100.22 -                              sxp.child_value(config, 'script',
  100.23 -                                              xroot.get_vif_script()))
  100.24 -        typ = sxp.child_value(config, 'type')
  100.25 -        bridge  = sxp.child_value(config, 'bridge')
  100.26 -        mac     = sxp.child_value(config, 'mac')
  100.27 -        vifname = sxp.child_value(config, 'vifname')
  100.28 -        rate    = sxp.child_value(config, 'rate')
  100.29 -        uuid    = sxp.child_value(config, 'uuid')
  100.30 -        ipaddr  = _get_config_ipaddr(config)
  100.31 +                              config.get('script', xroot.get_vif_script()))
  100.32 +        typ = config.get('type')
  100.33 +        bridge  = config.get('bridge')
  100.34 +        mac     = config.get('mac')
  100.35 +        vifname = config.get('vifname')
  100.36 +        rate    = config.get('rate')
  100.37 +        uuid    = config.get('uuid')
  100.38 +        ipaddr  = config.get('ip')
  100.39  
  100.40          devid = self.allocateDeviceID()
  100.41  
   101.1 --- a/tools/python/xen/xend/server/pciif.py	Sat Dec 02 15:19:50 2006 -0700
   101.2 +++ b/tools/python/xen/xend/server/pciif.py	Mon Dec 04 08:24:41 2006 -0700
   101.3 @@ -53,60 +53,29 @@ class PciController(DevController):
   101.4  
   101.5      def getDeviceDetails(self, config):
   101.6          """@see DevController.getDeviceDetails"""
   101.7 -        #log.debug('pci config='+sxp.to_string(config))
   101.8 -
   101.9 -        def get_param(config, field, default=None):
  101.10 +        def parse_hex(val):
  101.11              try:
  101.12 -                val = sxp.child_value(config, field)
  101.13 -
  101.14 -                if not val:
  101.15 -                    if default==None:
  101.16 -                        raise VmError('pci: Missing %s config setting' % field)
  101.17 -                    else:
  101.18 -                        return default
  101.19 -
  101.20                  if isinstance(val, types.StringTypes):
  101.21                      return int(val, 16)
  101.22                  else:
  101.23                      return val
  101.24 -            except:
  101.25 -                if default==None:
  101.26 -                    raise VmError('pci: Invalid config setting %s: %s' %
  101.27 -                              (field, val))
  101.28 -                else:
  101.29 -                    return default
  101.30 -        
  101.31 +            except ValueError:
  101.32 +                return None
  101.33 +            
  101.34          back = {}
  101.35 -
  101.36 -        val = sxp.child_value(config, 'dev')
  101.37 -        if isinstance(val, (types.ListType, types.TupleType)):
  101.38 -            pcidevid = 0
  101.39 -            for dev_config in sxp.children(config, 'dev'):
  101.40 -                domain = get_param(dev_config, 'domain', 0)
  101.41 -                bus = get_param(dev_config,'bus')
  101.42 -                slot = get_param(dev_config,'slot')
  101.43 -                func = get_param(dev_config,'func')
  101.44 +        pcidevid = 0
  101.45 +        for pci_config in config.get('devs', []):
  101.46 +            domain = parse_hex(pci_config.get('domain', 0))
  101.47 +            bus = parse_hex(pci_config.get('bus', 0))
  101.48 +            slot = parse_hex(pci_config.get('slot', 0))
  101.49 +            func = parse_hex(pci_config.get('func', 0))            
  101.50 +            self.setupDevice(domain, bus, slot, func)
  101.51 +            back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%02x" % \
  101.52 +                                        (domain, bus, slot, func)
  101.53 +            pcidevid += 1
  101.54  
  101.55 -                self.setupDevice(domain, bus, slot, func)
  101.56 -
  101.57 -                back['dev-%i' % pcidevid]="%04x:%02x:%02x.%02x"% \
  101.58 -                        (domain, bus, slot, func)
  101.59 -                pcidevid+=1
  101.60 -            
  101.61 -            back['num_devs']=str(pcidevid)
  101.62 -
  101.63 -        else:
  101.64 -            # Xen 2.0 configuration compatibility