direct-io.hg

changeset 14612:56caf0e37e6a

merge with xen-unstable.hg
author awilliam@xenbuild2.aw
date Mon Mar 26 10:10:31 2007 -0600 (2007-03-26)
parents 16198b57f535 3afefd64e392
children 2c59917255f7
files tools/misc/xc_shadow.c
line diff
     1.1 --- a/config/StdGNU.mk	Mon Mar 26 09:17:25 2007 -0600
     1.2 +++ b/config/StdGNU.mk	Mon Mar 26 10:10:31 2007 -0600
     1.3 @@ -1,7 +1,7 @@
     1.4  AS         = $(CROSS_COMPILE)as
     1.5  LD         = $(CROSS_COMPILE)ld
     1.6  CC         = $(CROSS_COMPILE)gcc
     1.7 -CPP        = $(CROSS_COMPILE)gcc -E
     1.8 +CPP        = $(CC) -E
     1.9  AR         = $(CROSS_COMPILE)ar
    1.10  RANLIB     = $(CROSS_COMPILE)ranlib
    1.11  NM         = $(CROSS_COMPILE)nm
     2.1 --- a/docs/xen-api/xenapi-datamodel.tex	Mon Mar 26 09:17:25 2007 -0600
     2.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Mon Mar 26 10:10:31 2007 -0600
     2.3 @@ -1062,7 +1062,7 @@ Quals & Field & Type & Description \\
     2.4  $\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
     2.5  $\mathit{RO}_\mathit{run}$ &  {\tt domid} & int & domain ID (if available, -1 otherwise) \\
     2.6  $\mathit{RO}_\mathit{run}$ &  {\tt is\_control\_domain} & bool & true if this is a control domain (domain 0 or a driver domain) \\
     2.7 -$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VM\_metrics ref & metrics associated with this VM. \\
     2.8 +$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VM\_metrics ref & metrics associated with this VM \\
     2.9  $\mathit{RO}_\mathit{run}$ &  {\tt guest\_metrics} & VM\_guest\_metrics ref & metrics associated with the running guest \\
    2.10  \hline
    2.11  \end{longtable}
    2.12 @@ -1379,7 +1379,7 @@ specified VM is in the Running state.
    2.13  \begin{tabular}{|c|c|p{7cm}|}
    2.14   \hline
    2.15  {\bf type} & {\bf name} & {\bf description} \\ \hline
    2.16 -{\tt VM ref } & vm & The VM to hibernate \\ \hline 
    2.17 +{\tt VM ref } & vm & The VM to suspend \\ \hline 
    2.18  
    2.19  \end{tabular}
    2.20  
    2.21 @@ -1414,9 +1414,9 @@ specified VM is in the Suspended state.
    2.22  \begin{tabular}{|c|c|p{7cm}|}
    2.23   \hline
    2.24  {\bf type} & {\bf name} & {\bf description} \\ \hline
    2.25 -{\tt VM ref } & vm & The VM to unhibernate \\ \hline 
    2.26 -
    2.27 -{\tt bool } & start\_paused & Unhibernate VM in paused state if set to true. \\ \hline 
    2.28 +{\tt VM ref } & vm & The VM to resume \\ \hline 
    2.29 +
    2.30 +{\tt bool } & start\_paused & Resume VM in paused state if set to true. \\ \hline 
    2.31  
    2.32  \end{tabular}
    2.33  
    2.34 @@ -1434,6 +1434,41 @@ void
    2.35  \noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE}
    2.36  
    2.37  \vspace{0.6cm}
    2.38 +\subsubsection{RPC name:~set\_VCPUs\_number\_live}
    2.39 +
    2.40 +{\bf Overview:} 
    2.41 +Set this VM's VCPUs/at\_startup value, and set the same value on the VM, if
    2.42 +running.
    2.43 +
    2.44 + \noindent {\bf Signature:} 
    2.45 +\begin{verbatim} void set_VCPUs_number_live (session_id s, VM ref self, int nvcpu)\end{verbatim}
    2.46 +
    2.47 +
    2.48 +\noindent{\bf Arguments:}
    2.49 +
    2.50 + 
    2.51 +\vspace{0.3cm}
    2.52 +\begin{tabular}{|c|c|p{7cm}|}
    2.53 + \hline
    2.54 +{\bf type} & {\bf name} & {\bf description} \\ \hline
    2.55 +{\tt VM ref } & self & The VM \\ \hline 
    2.56 +
    2.57 +{\tt int } & nvcpu & The number of VCPUs \\ \hline 
    2.58 +
    2.59 +\end{tabular}
    2.60 +
    2.61 +\vspace{0.3cm}
    2.62 +
    2.63 + \noindent {\bf Return Type:} 
    2.64 +{\tt 
    2.65 +void
    2.66 +}
    2.67 +
    2.68 +
    2.69 +
    2.70 +\vspace{0.3cm}
    2.71 +\vspace{0.3cm}
    2.72 +\vspace{0.3cm}
    2.73  \subsubsection{RPC name:~get\_all}
    2.74  
    2.75  {\bf Overview:} 
    2.76 @@ -3983,6 +4018,7 @@ Quals & Field & Type & Description \\
    2.77  $\mathit{RO}_\mathit{run}$ &  {\tt memory/actual} & int & Guest's actual memory (bytes) \\
    2.78  $\mathit{RO}_\mathit{run}$ &  {\tt VCPUs/number} & int & Current number of VCPUs \\
    2.79  $\mathit{RO}_\mathit{run}$ &  {\tt VCPUs/utilisation} & (int $\rightarrow$ float) Map & Utilisation for all of guest's current VCPUs \\
    2.80 +$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which this information was last updated \\
    2.81  \hline
    2.82  \end{longtable}
    2.83  \subsection{RPCs associated with class: VM\_metrics}
    2.84 @@ -4135,6 +4171,38 @@ value of the field
    2.85  \vspace{0.3cm}
    2.86  \vspace{0.3cm}
    2.87  \vspace{0.3cm}
    2.88 +\subsubsection{RPC name:~get\_last\_updated}
    2.89 +
    2.90 +{\bf Overview:} 
    2.91 +Get the last\_updated field of the given VM\_metrics.
    2.92 +
    2.93 + \noindent {\bf Signature:} 
    2.94 +\begin{verbatim} datetime get_last_updated (session_id s, VM_metrics ref self)\end{verbatim}
    2.95 +
    2.96 +
    2.97 +\noindent{\bf Arguments:}
    2.98 +
    2.99 + 
   2.100 +\vspace{0.3cm}
   2.101 +\begin{tabular}{|c|c|p{7cm}|}
   2.102 + \hline
   2.103 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   2.104 +{\tt VM\_metrics ref } & self & reference to the object \\ \hline 
   2.105 +
   2.106 +\end{tabular}
   2.107 +
   2.108 +\vspace{0.3cm}
   2.109 +
   2.110 + \noindent {\bf Return Type:} 
   2.111 +{\tt 
   2.112 +datetime
   2.113 +}
   2.114 +
   2.115 +
   2.116 +value of the field
   2.117 +\vspace{0.3cm}
   2.118 +\vspace{0.3cm}
   2.119 +\vspace{0.3cm}
   2.120  \subsubsection{RPC name:~get\_by\_uuid}
   2.121  
   2.122  {\bf Overview:} 
   2.123 @@ -4219,6 +4287,7 @@ Quals & Field & Type & Description \\
   2.124  $\mathit{RO}_\mathit{run}$ &  {\tt disks} & (string $\rightarrow$ string) Map & disk configuration/free space \\
   2.125  $\mathit{RO}_\mathit{run}$ &  {\tt networks} & (string $\rightarrow$ string) Map & network configuration \\
   2.126  $\mathit{RO}_\mathit{run}$ &  {\tt other} & (string $\rightarrow$ string) Map & anything else \\
   2.127 +$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which this information was last updated \\
   2.128  \hline
   2.129  \end{longtable}
   2.130  \subsection{RPCs associated with class: VM\_guest\_metrics}
   2.131 @@ -4467,6 +4536,38 @@ value of the field
   2.132  \vspace{0.3cm}
   2.133  \vspace{0.3cm}
   2.134  \vspace{0.3cm}
   2.135 +\subsubsection{RPC name:~get\_last\_updated}
   2.136 +
   2.137 +{\bf Overview:} 
   2.138 +Get the last\_updated field of the given VM\_guest\_metrics.
   2.139 +
   2.140 + \noindent {\bf Signature:} 
   2.141 +\begin{verbatim} datetime get_last_updated (session_id s, VM_guest_metrics ref self)\end{verbatim}
   2.142 +
   2.143 +
   2.144 +\noindent{\bf Arguments:}
   2.145 +
   2.146 + 
   2.147 +\vspace{0.3cm}
   2.148 +\begin{tabular}{|c|c|p{7cm}|}
   2.149 + \hline
   2.150 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   2.151 +{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline 
   2.152 +
   2.153 +\end{tabular}
   2.154 +
   2.155 +\vspace{0.3cm}
   2.156 +
   2.157 + \noindent {\bf Return Type:} 
   2.158 +{\tt 
   2.159 +datetime
   2.160 +}
   2.161 +
   2.162 +
   2.163 +value of the field
   2.164 +\vspace{0.3cm}
   2.165 +\vspace{0.3cm}
   2.166 +\vspace{0.3cm}
   2.167  \subsubsection{RPC name:~get\_by\_uuid}
   2.168  
   2.169  {\bf Overview:} 
   2.170 @@ -4562,7 +4663,7 @@ Quals & Field & Type & Description \\
   2.171  $\mathit{RW}$ &  {\tt crash\_dump\_sr} & SR ref & The SR in which VDIs for crash dumps are created \\
   2.172  $\mathit{RO}_\mathit{run}$ &  {\tt PBDs} & (PBD ref) Set & physical blockdevices \\
   2.173  $\mathit{RO}_\mathit{run}$ &  {\tt host\_CPUs} & (host\_cpu ref) Set & The physical CPUs on this host \\
   2.174 -$\mathit{RO}_\mathit{ins}$ &  {\tt metrics} & host\_metrics ref & metrics associated with this host. \\
   2.175 +$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & host\_metrics ref & metrics associated with this host \\
   2.176  \hline
   2.177  \end{longtable}
   2.178  \subsection{RPCs associated with class: host}
   2.179 @@ -5816,6 +5917,7 @@ Quals & Field & Type & Description \\
   2.180  $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
   2.181  $\mathit{RO}_\mathit{run}$ &  {\tt memory/total} & int & Host's total memory (bytes) \\
   2.182  $\mathit{RO}_\mathit{run}$ &  {\tt memory/free} & int & Host's free memory (bytes) \\
   2.183 +$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which this information was last updated \\
   2.184  \hline
   2.185  \end{longtable}
   2.186  \subsection{RPCs associated with class: host\_metrics}
   2.187 @@ -5936,6 +6038,38 @@ value of the field
   2.188  \vspace{0.3cm}
   2.189  \vspace{0.3cm}
   2.190  \vspace{0.3cm}
   2.191 +\subsubsection{RPC name:~get\_last\_updated}
   2.192 +
   2.193 +{\bf Overview:} 
   2.194 +Get the last\_updated field of the given host\_metrics.
   2.195 +
   2.196 + \noindent {\bf Signature:} 
   2.197 +\begin{verbatim} datetime get_last_updated (session_id s, host_metrics ref self)\end{verbatim}
   2.198 +
   2.199 +
   2.200 +\noindent{\bf Arguments:}
   2.201 +
   2.202 + 
   2.203 +\vspace{0.3cm}
   2.204 +\begin{tabular}{|c|c|p{7cm}|}
   2.205 + \hline
   2.206 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   2.207 +{\tt host\_metrics ref } & self & reference to the object \\ \hline 
   2.208 +
   2.209 +\end{tabular}
   2.210 +
   2.211 +\vspace{0.3cm}
   2.212 +
   2.213 + \noindent {\bf Return Type:} 
   2.214 +{\tt 
   2.215 +datetime
   2.216 +}
   2.217 +
   2.218 +
   2.219 +value of the field
   2.220 +\vspace{0.3cm}
   2.221 +\vspace{0.3cm}
   2.222 +\vspace{0.3cm}
   2.223  \subsubsection{RPC name:~get\_by\_uuid}
   2.224  
   2.225  {\bf Overview:} 
   2.226 @@ -6852,7 +6986,7 @@ Quals & Field & Type & Description \\
   2.227  $\mathit{RW}$ &  {\tt qos/algorithm\_type} & string & QoS algorithm to use \\
   2.228  $\mathit{RW}$ &  {\tt qos/algorithm\_params} & (string $\rightarrow$ string) Map & parameters for chosen QoS algorithm \\
   2.229  $\mathit{RO}_\mathit{run}$ &  {\tt qos/supported\_algorithms} & string Set & supported QoS algorithms for this VIF \\
   2.230 -$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VIF\_metrics ref & metrics associated with this VIF. \\
   2.231 +$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VIF\_metrics ref & metrics associated with this VIF \\
   2.232  \hline
   2.233  \end{longtable}
   2.234  \subsection{RPCs associated with class: VIF}
   2.235 @@ -7745,6 +7879,7 @@ Quals & Field & Type & Description \\
   2.236  $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
   2.237  $\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\
   2.238  $\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
   2.239 +$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which this information was last updated \\
   2.240  \hline
   2.241  \end{longtable}
   2.242  \subsection{RPCs associated with class: VIF\_metrics}
   2.243 @@ -7865,6 +8000,38 @@ value of the field
   2.244  \vspace{0.3cm}
   2.245  \vspace{0.3cm}
   2.246  \vspace{0.3cm}
   2.247 +\subsubsection{RPC name:~get\_last\_updated}
   2.248 +
   2.249 +{\bf Overview:} 
   2.250 +Get the last\_updated field of the given VIF\_metrics.
   2.251 +
   2.252 + \noindent {\bf Signature:} 
   2.253 +\begin{verbatim} datetime get_last_updated (session_id s, VIF_metrics ref self)\end{verbatim}
   2.254 +
   2.255 +
   2.256 +\noindent{\bf Arguments:}
   2.257 +
   2.258 + 
   2.259 +\vspace{0.3cm}
   2.260 +\begin{tabular}{|c|c|p{7cm}|}
   2.261 + \hline
   2.262 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   2.263 +{\tt VIF\_metrics ref } & self & reference to the object \\ \hline 
   2.264 +
   2.265 +\end{tabular}
   2.266 +
   2.267 +\vspace{0.3cm}
   2.268 +
   2.269 + \noindent {\bf Return Type:} 
   2.270 +{\tt 
   2.271 +datetime
   2.272 +}
   2.273 +
   2.274 +
   2.275 +value of the field
   2.276 +\vspace{0.3cm}
   2.277 +\vspace{0.3cm}
   2.278 +\vspace{0.3cm}
   2.279  \subsubsection{RPC name:~get\_by\_uuid}
   2.280  
   2.281  {\bf Overview:} 
   2.282 @@ -7950,7 +8117,7 @@ Quals & Field & Type & Description \\
   2.283  $\mathit{RW}$ &  {\tt MAC} & string & ethernet MAC address of physical interface \\
   2.284  $\mathit{RW}$ &  {\tt MTU} & int & MTU in octets \\
   2.285  $\mathit{RW}$ &  {\tt VLAN} & int & VLAN tag for all traffic passing through this interface \\
   2.286 -$\mathit{RO}_\mathit{ins}$ &  {\tt metrics} & PIF\_metrics ref & metrics associated with this PIF. \\
   2.287 +$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & PIF\_metrics ref & metrics associated with this PIF \\
   2.288  \hline
   2.289  \end{longtable}
   2.290  \subsection{RPCs associated with class: PIF}
   2.291 @@ -8522,6 +8689,7 @@ Quals & Field & Type & Description \\
   2.292  $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
   2.293  $\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\
   2.294  $\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
   2.295 +$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which this information was last updated \\
   2.296  \hline
   2.297  \end{longtable}
   2.298  \subsection{RPCs associated with class: PIF\_metrics}
   2.299 @@ -8642,6 +8810,38 @@ value of the field
   2.300  \vspace{0.3cm}
   2.301  \vspace{0.3cm}
   2.302  \vspace{0.3cm}
   2.303 +\subsubsection{RPC name:~get\_last\_updated}
   2.304 +
   2.305 +{\bf Overview:} 
   2.306 +Get the last\_updated field of the given PIF\_metrics.
   2.307 +
   2.308 + \noindent {\bf Signature:} 
   2.309 +\begin{verbatim} datetime get_last_updated (session_id s, PIF_metrics ref self)\end{verbatim}
   2.310 +
   2.311 +
   2.312 +\noindent{\bf Arguments:}
   2.313 +
   2.314 + 
   2.315 +\vspace{0.3cm}
   2.316 +\begin{tabular}{|c|c|p{7cm}|}
   2.317 + \hline
   2.318 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   2.319 +{\tt PIF\_metrics ref } & self & reference to the object \\ \hline 
   2.320 +
   2.321 +\end{tabular}
   2.322 +
   2.323 +\vspace{0.3cm}
   2.324 +
   2.325 + \noindent {\bf Return Type:} 
   2.326 +{\tt 
   2.327 +datetime
   2.328 +}
   2.329 +
   2.330 +
   2.331 +value of the field
   2.332 +\vspace{0.3cm}
   2.333 +\vspace{0.3cm}
   2.334 +\vspace{0.3cm}
   2.335  \subsubsection{RPC name:~get\_by\_uuid}
   2.336  
   2.337  {\bf Overview:} 
   2.338 @@ -11293,6 +11493,7 @@ Quals & Field & Type & Description \\
   2.339  $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
   2.340  $\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\
   2.341  $\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
   2.342 +$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which this information was last updated \\
   2.343  \hline
   2.344  \end{longtable}
   2.345  \subsection{RPCs associated with class: VBD\_metrics}
   2.346 @@ -11413,6 +11614,38 @@ value of the field
   2.347  \vspace{0.3cm}
   2.348  \vspace{0.3cm}
   2.349  \vspace{0.3cm}
   2.350 +\subsubsection{RPC name:~get\_last\_updated}
   2.351 +
   2.352 +{\bf Overview:} 
   2.353 +Get the last\_updated field of the given VBD\_metrics.
   2.354 +
   2.355 + \noindent {\bf Signature:} 
   2.356 +\begin{verbatim} datetime get_last_updated (session_id s, VBD_metrics ref self)\end{verbatim}
   2.357 +
   2.358 +
   2.359 +\noindent{\bf Arguments:}
   2.360 +
   2.361 + 
   2.362 +\vspace{0.3cm}
   2.363 +\begin{tabular}{|c|c|p{7cm}|}
   2.364 + \hline
   2.365 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   2.366 +{\tt VBD\_metrics ref } & self & reference to the object \\ \hline 
   2.367 +
   2.368 +\end{tabular}
   2.369 +
   2.370 +\vspace{0.3cm}
   2.371 +
   2.372 + \noindent {\bf Return Type:} 
   2.373 +{\tt 
   2.374 +datetime
   2.375 +}
   2.376 +
   2.377 +
   2.378 +value of the field
   2.379 +\vspace{0.3cm}
   2.380 +\vspace{0.3cm}
   2.381 +\vspace{0.3cm}
   2.382  \subsubsection{RPC name:~get\_by\_uuid}
   2.383  
   2.384  {\bf Overview:} 
   2.385 @@ -13384,14 +13617,3 @@ HVM is required for this operation
   2.386  {\bf Signature:}
   2.387  \begin{verbatim}VM_HVM_REQUIRED(vm)\end{verbatim}
   2.388  \begin{center}\rule{10em}{0.1pt}\end{center}
   2.389 -
   2.390 -
   2.391 -
   2.392 -\newpage
   2.393 -\section{DTD}
   2.394 -General notes:
   2.395 -\begin{itemize}
   2.396 -\item Values of primitive types (int, bool, etc) and higher-order types (Sets, Maps) are encoded as simple strings, rather than being expanded into XML fragments. For example ``5'', ``true'', ``1, 2, 3, 4'', ``(1, 2), (2, 3), (3, 4)''
   2.397 -\item Values of enumeration types are represented as strings (e.g. ``PAE'', ``3DNow!'')
   2.398 -\item Object References are represented as UUIDs, written in string form
   2.399 -\end{itemize}
     3.1 --- a/tools/ioemu/hw/piix4acpi.c	Mon Mar 26 09:17:25 2007 -0600
     3.2 +++ b/tools/ioemu/hw/piix4acpi.c	Mon Mar 26 10:10:31 2007 -0600
     3.3 @@ -52,126 +52,16 @@
     3.4  typedef struct AcpiDeviceState AcpiDeviceState;
     3.5  AcpiDeviceState *acpi_device_table;
     3.6  
     3.7 -typedef struct PM1Event_BLK {
     3.8 -    uint16_t pm1_status; /* pm1a_EVT_BLK */
     3.9 -    uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
    3.10 -}PM1Event_BLK;
    3.11 -
    3.12  typedef struct PCIAcpiState {
    3.13      PCIDevice dev;
    3.14 -    uint16_t irq;
    3.15 -    uint16_t pm1_status; /* pm1a_EVT_BLK */
    3.16 -    uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
    3.17      uint16_t pm1_control; /* pm1a_ECNT_BLK */
    3.18 -    uint32_t pm1_timer; /* pmtmr_BLK */
    3.19 -    uint64_t old_vmck_ticks; /* using vm_clock counter */
    3.20  } PCIAcpiState;
    3.21  
    3.22 -static PCIAcpiState *acpi_state;
    3.23 -
    3.24 -static void acpi_reset(PCIAcpiState *s)
    3.25 -{
    3.26 -    uint8_t *pci_conf;
    3.27 -    pci_conf = s->dev.config;
    3.28 -
    3.29 -    pci_conf[0x42] = 0x00;
    3.30 -    pci_conf[0x43] = 0x00;
    3.31 -    s->irq = 9;
    3.32 -    s->pm1_status = 0;
    3.33 -    s->pm1_enable = 0x00;    /* TMROF_EN should cleared */
    3.34 -    s->pm1_control = SCI_EN; /* SCI_EN */
    3.35 -    s->pm1_timer = 0;
    3.36 -    s->old_vmck_ticks = qemu_get_clock(vm_clock);
    3.37 -}
    3.38 -
    3.39 -/*byte access  */
    3.40 -static void acpiPm1Status_writeb(void *opaque, uint32_t addr, uint32_t val)
    3.41 -{
    3.42 -    PCIAcpiState *s = opaque;
    3.43 -
    3.44 -    if ((val&TMROF_STS)==TMROF_STS)
    3.45 -        s->pm1_status = s->pm1_status&!TMROF_STS;
    3.46 -
    3.47 -    if ((val&GBL_STS)==GBL_STS)
    3.48 -        s->pm1_status = s->pm1_status&!GBL_STS;
    3.49 -
    3.50 -/*     printf("acpiPm1Status_writeb \n addr %x val:%x pm1_status:%x \n", addr, val,s->pm1_status); */
    3.51 -}
    3.52 -
    3.53 -static uint32_t acpiPm1Status_readb(void *opaque, uint32_t addr)
    3.54 -{
    3.55 -    PCIAcpiState *s = opaque;
    3.56 -    uint32_t val;
    3.57 -
    3.58 -    val = s->pm1_status;
    3.59 -/*         printf("acpiPm1Status_readb \n addr %x val:%x\n", addr, val); */
    3.60 -
    3.61 -   return val;
    3.62 -}
    3.63 -
    3.64 -static void acpiPm1StatusP1_writeb(void *opaque, uint32_t addr, uint32_t val)
    3.65 -{
    3.66 -    PCIAcpiState *s = opaque;
    3.67 -
    3.68 -    s->pm1_status = (val<<8)||(s->pm1_status);
    3.69 -/*     printf("acpiPm1StatusP1_writeb \n addr %x val:%x\n", addr, val); */
    3.70 -}
    3.71 -
    3.72 -static uint32_t acpiPm1StatusP1_readb(void *opaque, uint32_t addr)
    3.73 -{
    3.74 -    PCIAcpiState *s = opaque;
    3.75 -    uint32_t val;
    3.76 -
    3.77 -    val = (s->pm1_status)>>8;
    3.78 -    printf("acpiPm1StatusP1_readb \n addr %x val:%x\n", addr, val);
    3.79 -
    3.80 -    return val;
    3.81 -}
    3.82 -
    3.83 -static void acpiPm1Enable_writeb(void *opaque, uint32_t addr, uint32_t val)
    3.84 -{
    3.85 -    PCIAcpiState *s = opaque;
    3.86 -
    3.87 -    s->pm1_enable = val;
    3.88 -/*   printf("acpiPm1Enable_writeb \n addr %x val:%x\n", addr, val); */
    3.89 -}
    3.90 -
    3.91 -static uint32_t acpiPm1Enable_readb(void *opaque, uint32_t addr)
    3.92 -{
    3.93 -    PCIAcpiState *s = opaque;
    3.94 -    uint32_t val;
    3.95 -
    3.96 -    val = (s->pm1_enable)||0x1;
    3.97 -/*  printf("acpiPm1Enable_readb \n addr %x val:%x\n", addr, val); */
    3.98 -
    3.99 -    return val;
   3.100 -}
   3.101 -
   3.102 -static void acpiPm1EnableP1_writeb(void *opaque, uint32_t addr, uint32_t val)
   3.103 -{
   3.104 -    PCIAcpiState *s = opaque;
   3.105 -
   3.106 -    s->pm1_enable = (val<<8)||(s->pm1_enable);
   3.107 -/*    printf("acpiPm1EnableP1_writeb \n addr %x val:%x\n", addr, val); */
   3.108 -
   3.109 -}
   3.110 -
   3.111 -static uint32_t acpiPm1EnableP1_readb(void *opaque, uint32_t addr)
   3.112 -{
   3.113 -    PCIAcpiState *s = opaque;
   3.114 -    uint32_t val;
   3.115 -
   3.116 -    val = (s->pm1_enable)>>8;
   3.117 -/*  printf("acpiPm1EnableP1_readb \n addr %x val:%x\n", addr, val); */
   3.118 -
   3.119 -    return val;
   3.120 -}
   3.121 -
   3.122  static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
   3.123  {
   3.124      PCIAcpiState *s = opaque;
   3.125  
   3.126 -    s->pm1_control = val;
   3.127 +    s->pm1_control = (s->pm1_control & 0xff00) | (val & 0xff);
   3.128  /*  printf("acpiPm1Control_writeb \n addr %x val:%x\n", addr, val); */
   3.129  
   3.130  }
   3.131 @@ -181,7 +71,8 @@ static uint32_t acpiPm1Control_readb(voi
   3.132      PCIAcpiState *s = opaque;
   3.133      uint32_t val;
   3.134  
   3.135 -    val = s->pm1_control;
   3.136 +    /* Mask out the write-only bits */
   3.137 +    val = s->pm1_control & ~(GBL_RLS|SLP_EN) & 0xff;
   3.138  /*    printf("acpiPm1Control_readb \n addr %x val:%x\n", addr, val); */
   3.139  
   3.140      return val;
   3.141 @@ -191,14 +82,13 @@ static void acpiPm1ControlP1_writeb(void
   3.142  {
   3.143      PCIAcpiState *s = opaque;
   3.144  
   3.145 -    s->pm1_control = (val<<8)||(s->pm1_control);
   3.146 +    s->pm1_control = (s->pm1_control & 0xff) | (val << 8);
   3.147  /*    printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */
   3.148  
   3.149      // Check for power off request
   3.150 -
   3.151 +    val <<= 8;
   3.152      if (((val & SLP_EN) != 0) &&
   3.153          ((val & SLP_TYP_MASK) == SLP_VAL)) {
   3.154 -        s->pm1_timer=0x0; //clear ACPI timer
   3.155          qemu_system_shutdown_request();
   3.156      }
   3.157  }
   3.158 @@ -208,7 +98,8 @@ static uint32_t acpiPm1ControlP1_readb(v
   3.159      PCIAcpiState *s = opaque;
   3.160      uint32_t val;
   3.161  
   3.162 -    val = (s->pm1_control)>>8;
   3.163 +    /* Mask out the write-only bits */
   3.164 +    val = (s->pm1_control & ~(GBL_RLS|SLP_EN)) >> 8;
   3.165  /*    printf("acpiPm1ControlP1_readb \n addr %x val:%x\n", addr, val); */
   3.166  
   3.167      return val;
   3.168 @@ -217,50 +108,6 @@ static uint32_t acpiPm1ControlP1_readb(v
   3.169  
   3.170  /* word access   */
   3.171  
   3.172 -static void acpiPm1Status_writew(void *opaque, uint32_t addr, uint32_t val)
   3.173 -{
   3.174 -    PCIAcpiState *s = opaque;
   3.175 -
   3.176 -    if ((val&TMROF_STS)==TMROF_STS)
   3.177 -        s->pm1_status = s->pm1_status&!TMROF_STS;
   3.178 -
   3.179 -    if ((val&GBL_STS)==GBL_STS)
   3.180 -        s->pm1_status = s->pm1_status&!GBL_STS;
   3.181 -
   3.182 -/*    printf("acpiPm1Status_writew \n addr %x val:%x pm1_status:%x \n", addr, val,s->pm1_status); */
   3.183 -}
   3.184 -
   3.185 -static uint32_t acpiPm1Status_readw(void *opaque, uint32_t addr)
   3.186 -{
   3.187 -    PCIAcpiState *s = opaque;
   3.188 -    uint32_t val;
   3.189 -
   3.190 -    val = s->pm1_status;
   3.191 -/*    printf("acpiPm1Status_readw \n addr %x val:%x\n", addr, val); */
   3.192 -
   3.193 -    return val;
   3.194 -}
   3.195 -
   3.196 -static void acpiPm1Enable_writew(void *opaque, uint32_t addr, uint32_t val)
   3.197 -{
   3.198 -    PCIAcpiState *s = opaque;
   3.199 -
   3.200 -    s->pm1_enable = val;
   3.201 -/*    printf("acpiPm1Enable_writew \n addr %x val:%x\n", addr, val); */
   3.202 -
   3.203 -}
   3.204 -
   3.205 -static uint32_t acpiPm1Enable_readw(void *opaque, uint32_t addr)
   3.206 -{
   3.207 -    PCIAcpiState *s = opaque;
   3.208 -    uint32_t val;
   3.209 -
   3.210 -    val = s->pm1_enable;
   3.211 -/*    printf("acpiPm1Enable_readw \n addr %x val:%x\n", addr, val); */
   3.212 -
   3.213 -   return val;
   3.214 -}
   3.215 -
   3.216  static void acpiPm1Control_writew(void *opaque, uint32_t addr, uint32_t val)
   3.217  {
   3.218      PCIAcpiState *s = opaque;
   3.219 @@ -282,56 +129,13 @@ static uint32_t acpiPm1Control_readw(voi
   3.220      PCIAcpiState *s = opaque;
   3.221      uint32_t val;
   3.222  
   3.223 -    val = s->pm1_control;
   3.224 +    /* Mask out the write-only bits */
   3.225 +    val = s->pm1_control & ~(GBL_RLS|SLP_EN);
   3.226  /*    printf("acpiPm1Control_readw \n addr %x val:%x\n", addr, val);  */
   3.227  
   3.228      return val;
   3.229  }
   3.230  
   3.231 -/* dword access */
   3.232 -
   3.233 -static void acpiPm1Event_writel(void *opaque, uint32_t addr, uint32_t val)
   3.234 -{
   3.235 -    PCIAcpiState *s = opaque;
   3.236 -
   3.237 -    s->pm1_status = val;
   3.238 -    s->pm1_enable = val>>16;
   3.239 -/*     printf("acpiPm1Event_writel \n addr %x val:%x \n", addr, val); */
   3.240 -
   3.241 -}
   3.242 -
   3.243 -static uint32_t acpiPm1Event_readl(void *opaque, uint32_t addr)
   3.244 -{
   3.245 -    PCIAcpiState *s = opaque;
   3.246 -    uint32_t val;
   3.247 -
   3.248 -    val = s->pm1_status|(s->pm1_enable<<16);
   3.249 -/*    printf("acpiPm1Event_readl \n addr %x val:%x\n", addr, val);    */
   3.250 -
   3.251 -    return val;
   3.252 -}
   3.253 -
   3.254 -static void acpiPm1Timer_writel(void *opaque, uint32_t addr, uint32_t val)
   3.255 -{
   3.256 -    PCIAcpiState *s = opaque;
   3.257 -
   3.258 -    s->pm1_timer = val;
   3.259 -    s->old_vmck_ticks = qemu_get_clock(vm_clock) +
   3.260 -        muldiv64(val, FREQUENCE_PMTIMER, ticks_per_sec);
   3.261 -}
   3.262 -
   3.263 -static uint32_t acpiPm1Timer_readl(void *opaque, uint32_t addr)
   3.264 -{
   3.265 -    PCIAcpiState *s = opaque;
   3.266 -    int64_t current_vmck_ticks = qemu_get_clock(vm_clock);
   3.267 -    int64_t vmck_ticks_delta = current_vmck_ticks - s->old_vmck_ticks;
   3.268 -
   3.269 -    if (s->old_vmck_ticks)
   3.270 -        s->pm1_timer += muldiv64(vmck_ticks_delta, FREQUENCE_PMTIMER,
   3.271 -                                 ticks_per_sec);
   3.272 -    s->old_vmck_ticks = current_vmck_ticks;
   3.273 -    return s->pm1_timer;
   3.274 -}
   3.275  
   3.276  static void acpi_map(PCIDevice *pci_dev, int region_num,
   3.277                      uint32_t addr, uint32_t size, int type)
   3.278 @@ -341,37 +145,14 @@ static void acpi_map(PCIDevice *pci_dev,
   3.279      printf("register acpi io\n");
   3.280  
   3.281      /* Byte access */
   3.282 -    register_ioport_write(addr, 1, 1, acpiPm1Status_writeb, d);
   3.283 -    register_ioport_read(addr, 1, 1, acpiPm1Status_readb, d);
   3.284 -    register_ioport_write(addr+1, 1, 1, acpiPm1StatusP1_writeb, d);
   3.285 -    register_ioport_read(addr+1, 1, 1, acpiPm1StatusP1_readb, d);
   3.286 -
   3.287 -    register_ioport_write(addr + 2, 1, 1, acpiPm1Enable_writeb, d);
   3.288 -    register_ioport_read(addr + 2, 1, 1, acpiPm1Enable_readb, d);
   3.289 -    register_ioport_write(addr + 2 +1, 1, 1, acpiPm1EnableP1_writeb, d);
   3.290 -    register_ioport_read(addr + 2 +1, 1, 1, acpiPm1EnableP1_readb, d);
   3.291 -
   3.292      register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d);
   3.293      register_ioport_read(addr + 4, 1, 1, acpiPm1Control_readb, d);
   3.294      register_ioport_write(addr + 4 + 1, 1, 1, acpiPm1ControlP1_writeb, d);
   3.295      register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);
   3.296  
   3.297      /* Word access */
   3.298 -    register_ioport_write(addr, 2, 2, acpiPm1Status_writew, d);
   3.299 -    register_ioport_read(addr, 2, 2, acpiPm1Status_readw, d);
   3.300 -
   3.301 -    register_ioport_write(addr + 2, 2, 2, acpiPm1Enable_writew, d);
   3.302 -    register_ioport_read(addr + 2, 2, 2, acpiPm1Enable_readw, d);
   3.303 -
   3.304      register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d);
   3.305      register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
   3.306 -
   3.307 -    /* DWord access */
   3.308 -    register_ioport_write(addr, 4, 4, acpiPm1Event_writel, d);
   3.309 -    register_ioport_read(addr, 4, 4, acpiPm1Event_readl, d);
   3.310 -
   3.311 -    register_ioport_write(addr + 8, 4, 4, acpiPm1Timer_writel, d);
   3.312 -    register_ioport_read(addr + 8, 4, 4, acpiPm1Timer_readl, d);
   3.313  }
   3.314  
   3.315  /* PIIX4 acpi pci configuration space, func 2 */
   3.316 @@ -385,7 +166,6 @@ void pci_piix4_acpi_init(PCIBus *bus, in
   3.317          bus, "PIIX4 ACPI", sizeof(PCIAcpiState),
   3.318          devfn, NULL, NULL);
   3.319  
   3.320 -    acpi_state = d;
   3.321      pci_conf = d->dev.config;
   3.322      pci_conf[0x00] = 0x86;  /* Intel */
   3.323      pci_conf[0x01] = 0x80;
   3.324 @@ -408,6 +188,9 @@ void pci_piix4_acpi_init(PCIBus *bus, in
   3.325       */
   3.326      pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
   3.327      pci_conf[0x41] = 0x1f;
   3.328 +    pci_conf[0x42] = 0x00;
   3.329 +    pci_conf[0x43] = 0x00;
   3.330 +    d->pm1_control = SCI_EN;
   3.331 +
   3.332      acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
   3.333 -    acpi_reset(d);
   3.334  }
     4.1 --- a/tools/libxen/include/xen_common.h	Mon Mar 26 09:17:25 2007 -0600
     4.2 +++ b/tools/libxen/include/xen_common.h	Mon Mar 26 10:10:31 2007 -0600
     4.3 @@ -51,6 +51,30 @@ typedef struct
     4.4  } xen_session;
     4.5  
     4.6  
     4.7 +typedef struct xen_session_record
     4.8 +{
     4.9 +    char *uuid;
    4.10 +    struct xen_host_record_opt *this_host;
    4.11 +    char *this_user;
    4.12 +    time_t last_active;
    4.13 +} xen_session_record;
    4.14 +
    4.15 +
    4.16 +/**
    4.17 + * Allocate a xen_session_record.
    4.18 + */
    4.19 +extern xen_session_record *
    4.20 +xen_session_record_alloc(void);
    4.21 +
    4.22 +
    4.23 +/**
    4.24 + * Free the given xen_session_record, and all referenced values.  The
    4.25 + * given record must have been allocated by this library.
    4.26 + */
    4.27 +extern void
    4.28 +xen_session_record_free(xen_session_record *record);
    4.29 +
    4.30 +
    4.31  struct xen_task_;
    4.32  typedef struct xen_task_ * xen_task_id;
    4.33  
    4.34 @@ -136,10 +160,45 @@ xen_session_logout(xen_session *session)
    4.35  
    4.36  
    4.37  /**
    4.38 - * Set *result to be a handle to the host to which this session is connected.
    4.39 + * Get the UUID of the second given session.  Set *result to point at a
    4.40 + * string, yours to free.
    4.41 + */
    4.42 +extern bool
    4.43 +xen_session_get_uuid(xen_session *session, char **result,
    4.44 +                     xen_session *self_session);
    4.45 +
    4.46 +
    4.47 +/**
    4.48 + * Get the this_host field of the second given session.  Set *result to be a
    4.49 + * handle to that host.
    4.50   */
    4.51 -extern int
    4.52 -xen_session_get_this_host(xen_session *session, xen_host *result);
    4.53 +extern bool
    4.54 +xen_session_get_this_host(xen_session *session, xen_host *result,
    4.55 +                          xen_session *self_session);
    4.56 +
    4.57 +
    4.58 +/**
    4.59 + * Get the this_user field of the second given session.  Set *result to point
    4.60 + * at a string, yours to free.
    4.61 + */
    4.62 +extern bool
    4.63 +xen_session_get_this_user(xen_session *session, char **result,
    4.64 +                          xen_session *self_session);
    4.65 +
    4.66 +
    4.67 +/**
    4.68 + * Get the last_active field of the given session, and place it in *result.
    4.69 + */
    4.70 +extern bool
    4.71 +xen_session_get_last_active(xen_session *session, time_t *result,
    4.72 +                            xen_session *self_session);
    4.73 +
    4.74 +/**
    4.75 + * Get a record containing the current state of the second given session.
    4.76 + */
    4.77 +extern bool
    4.78 +xen_session_get_record(xen_session *session, xen_session_record **result,
    4.79 +                       xen_session *self_session);
    4.80  
    4.81  
    4.82  #endif
     5.1 --- a/tools/libxen/include/xen_host_metrics.h	Mon Mar 26 09:17:25 2007 -0600
     5.2 +++ b/tools/libxen/include/xen_host_metrics.h	Mon Mar 26 10:10:31 2007 -0600
     5.3 @@ -64,6 +64,7 @@ typedef struct xen_host_metrics_record
     5.4      char *uuid;
     5.5      int64_t memory_total;
     5.6      int64_t memory_free;
     5.7 +    time_t last_updated;
     5.8  } xen_host_metrics_record;
     5.9  
    5.10  /**
    5.11 @@ -182,6 +183,13 @@ xen_host_metrics_get_memory_free(xen_ses
    5.12  
    5.13  
    5.14  /**
    5.15 + * Get the last_updated field of the given host_metrics.
    5.16 + */
    5.17 +extern bool
    5.18 +xen_host_metrics_get_last_updated(xen_session *session, time_t *result, xen_host_metrics host_metrics);
    5.19 +
    5.20 +
    5.21 +/**
    5.22   * Return a list of all the host_metrics instances known to the system.
    5.23   */
    5.24  extern bool
     6.1 --- a/tools/libxen/include/xen_pif_metrics.h	Mon Mar 26 09:17:25 2007 -0600
     6.2 +++ b/tools/libxen/include/xen_pif_metrics.h	Mon Mar 26 10:10:31 2007 -0600
     6.3 @@ -64,6 +64,7 @@ typedef struct xen_pif_metrics_record
     6.4      char *uuid;
     6.5      double io_read_kbs;
     6.6      double io_write_kbs;
     6.7 +    time_t last_updated;
     6.8  } xen_pif_metrics_record;
     6.9  
    6.10  /**
    6.11 @@ -181,6 +182,13 @@ xen_pif_metrics_get_io_write_kbs(xen_ses
    6.12  
    6.13  
    6.14  /**
    6.15 + * Get the last_updated field of the given PIF_metrics.
    6.16 + */
    6.17 +extern bool
    6.18 +xen_pif_metrics_get_last_updated(xen_session *session, time_t *result, xen_pif_metrics pif_metrics);
    6.19 +
    6.20 +
    6.21 +/**
    6.22   * Return a list of all the PIF_metrics instances known to the system.
    6.23   */
    6.24  extern bool
     7.1 --- a/tools/libxen/include/xen_user.h	Mon Mar 26 09:17:25 2007 -0600
     7.2 +++ b/tools/libxen/include/xen_user.h	Mon Mar 26 10:10:31 2007 -0600
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 2006, XenSource Inc.
     7.6 + * Copyright (c) 2006-2007, XenSource Inc.
     7.7   *
     7.8   * This library is free software; you can redistribute it and/or
     7.9   * modify it under the terms of the GNU Lesser General Public
    7.10 @@ -24,8 +24,8 @@
    7.11  
    7.12  
    7.13  /*
    7.14 - * The user class. 
    7.15 - *  
    7.16 + * The user class.
    7.17 + * 
    7.18   * A user of the system.
    7.19   */
    7.20  
     8.1 --- a/tools/libxen/include/xen_vbd_metrics.h	Mon Mar 26 09:17:25 2007 -0600
     8.2 +++ b/tools/libxen/include/xen_vbd_metrics.h	Mon Mar 26 10:10:31 2007 -0600
     8.3 @@ -64,6 +64,7 @@ typedef struct xen_vbd_metrics_record
     8.4      char *uuid;
     8.5      double io_read_kbs;
     8.6      double io_write_kbs;
     8.7 +    time_t last_updated;
     8.8  } xen_vbd_metrics_record;
     8.9  
    8.10  /**
    8.11 @@ -181,6 +182,13 @@ xen_vbd_metrics_get_io_write_kbs(xen_ses
    8.12  
    8.13  
    8.14  /**
    8.15 + * Get the last_updated field of the given VBD_metrics.
    8.16 + */
    8.17 +extern bool
    8.18 +xen_vbd_metrics_get_last_updated(xen_session *session, time_t *result, xen_vbd_metrics vbd_metrics);
    8.19 +
    8.20 +
    8.21 +/**
    8.22   * Return a list of all the VBD_metrics instances known to the system.
    8.23   */
    8.24  extern bool
     9.1 --- a/tools/libxen/include/xen_vif_metrics.h	Mon Mar 26 09:17:25 2007 -0600
     9.2 +++ b/tools/libxen/include/xen_vif_metrics.h	Mon Mar 26 10:10:31 2007 -0600
     9.3 @@ -64,6 +64,7 @@ typedef struct xen_vif_metrics_record
     9.4      char *uuid;
     9.5      double io_read_kbs;
     9.6      double io_write_kbs;
     9.7 +    time_t last_updated;
     9.8  } xen_vif_metrics_record;
     9.9  
    9.10  /**
    9.11 @@ -181,6 +182,13 @@ xen_vif_metrics_get_io_write_kbs(xen_ses
    9.12  
    9.13  
    9.14  /**
    9.15 + * Get the last_updated field of the given VIF_metrics.
    9.16 + */
    9.17 +extern bool
    9.18 +xen_vif_metrics_get_last_updated(xen_session *session, time_t *result, xen_vif_metrics vif_metrics);
    9.19 +
    9.20 +
    9.21 +/**
    9.22   * Return a list of all the VIF_metrics instances known to the system.
    9.23   */
    9.24  extern bool
    10.1 --- a/tools/libxen/include/xen_vm.h	Mon Mar 26 09:17:25 2007 -0600
    10.2 +++ b/tools/libxen/include/xen_vm.h	Mon Mar 26 10:10:31 2007 -0600
    10.3 @@ -830,6 +830,14 @@ xen_vm_resume(xen_session *session, xen_
    10.4  
    10.5  
    10.6  /**
    10.7 + * Set this VM's VCPUs/at_startup value, and set the same value on the
    10.8 + * VM, if running
    10.9 + */
   10.10 +extern bool
   10.11 +xen_vm_set_vcpus_number_live(xen_session *session, xen_vm self, int64_t nvcpu);
   10.12 +
   10.13 +
   10.14 +/**
   10.15   * Return a list of all the VMs known to the system.
   10.16   */
   10.17  extern bool
    11.1 --- a/tools/libxen/include/xen_vm_guest_metrics.h	Mon Mar 26 09:17:25 2007 -0600
    11.2 +++ b/tools/libxen/include/xen_vm_guest_metrics.h	Mon Mar 26 10:10:31 2007 -0600
    11.3 @@ -69,6 +69,7 @@ typedef struct xen_vm_guest_metrics_reco
    11.4      xen_string_string_map *disks;
    11.5      xen_string_string_map *networks;
    11.6      xen_string_string_map *other;
    11.7 +    time_t last_updated;
    11.8  } xen_vm_guest_metrics_record;
    11.9  
   11.10  /**
   11.11 @@ -216,6 +217,13 @@ xen_vm_guest_metrics_get_other(xen_sessi
   11.12  
   11.13  
   11.14  /**
   11.15 + * Get the last_updated field of the given VM_guest_metrics.
   11.16 + */
   11.17 +extern bool
   11.18 +xen_vm_guest_metrics_get_last_updated(xen_session *session, time_t *result, xen_vm_guest_metrics vm_guest_metrics);
   11.19 +
   11.20 +
   11.21 +/**
   11.22   * Return a list of all the VM_guest_metrics instances known to the
   11.23   * system.
   11.24   */
    12.1 --- a/tools/libxen/include/xen_vm_metrics.h	Mon Mar 26 09:17:25 2007 -0600
    12.2 +++ b/tools/libxen/include/xen_vm_metrics.h	Mon Mar 26 10:10:31 2007 -0600
    12.3 @@ -66,6 +66,7 @@ typedef struct xen_vm_metrics_record
    12.4      int64_t memory_actual;
    12.5      int64_t vcpus_number;
    12.6      xen_int_float_map *vcpus_utilisation;
    12.7 +    time_t last_updated;
    12.8  } xen_vm_metrics_record;
    12.9  
   12.10  /**
   12.11 @@ -190,6 +191,13 @@ xen_vm_metrics_get_vcpus_utilisation(xen
   12.12  
   12.13  
   12.14  /**
   12.15 + * Get the last_updated field of the given VM_metrics.
   12.16 + */
   12.17 +extern bool
   12.18 +xen_vm_metrics_get_last_updated(xen_session *session, time_t *result, xen_vm_metrics vm_metrics);
   12.19 +
   12.20 +
   12.21 +/**
   12.22   * Return a list of all the VM_metrics instances known to the system.
   12.23   */
   12.24  extern bool
    13.1 --- a/tools/libxen/src/xen_common.c	Mon Mar 26 09:17:25 2007 -0600
    13.2 +++ b/tools/libxen/src/xen_common.c	Mon Mar 26 10:10:31 2007 -0600
    13.3 @@ -16,12 +16,14 @@
    13.4   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
    13.5   */
    13.6  
    13.7 +#define _XOPEN_SOURCE
    13.8  #include <assert.h>
    13.9  #include <stdarg.h>
   13.10  #include <stddef.h>
   13.11  #include <stdio.h>
   13.12  #include <stdlib.h>
   13.13  #include <string.h>
   13.14 +#include <time.h>
   13.15  
   13.16  #include <libxml/parser.h>
   13.17  #include <libxml/tree.h>
   13.18 @@ -30,6 +32,7 @@
   13.19  #include <libxml/xpath.h>
   13.20  
   13.21  #include "xen_common.h"
   13.22 +#include "xen_host.h"
   13.23  #include "xen_internal.h"
   13.24  #include "xen_int_float_map.h"
   13.25  #include "xen_string_string_map.h"
   13.26 @@ -136,6 +139,20 @@ xen_fini(void)
   13.27  }
   13.28  
   13.29  
   13.30 +void
   13.31 +xen_session_record_free(xen_session_record *record)
   13.32 +{
   13.33 +    if (record == NULL)
   13.34 +    {
   13.35 +        return;
   13.36 +    }
   13.37 +    free(record->uuid);
   13.38 +    xen_host_record_opt_free(record->this_host);
   13.39 +    free(record->this_user);
   13.40 +    free(record);
   13.41 +}
   13.42 +
   13.43 +
   13.44  xen_session *
   13.45  xen_session_login_with_password(xen_call_func call_func, void *handle,
   13.46                                  const char *uname, const char *pwd)
   13.47 @@ -185,15 +202,111 @@ xen_session_logout(xen_session *session)
   13.48  }
   13.49  
   13.50  
   13.51 -int
   13.52 -xen_session_get_this_host(xen_session *session, xen_host *result)
   13.53 +bool
   13.54 +xen_session_get_uuid(xen_session *session, char **result,
   13.55 +                     xen_session *self_session)
   13.56 +{
   13.57 +    abstract_value params[] =
   13.58 +        {
   13.59 +            { .type = &abstract_type_string,
   13.60 +              .u.string_val = self_session->session_id }
   13.61 +        };
   13.62 +
   13.63 +    xen_call_(session, "session.get_uuid", params, 1,
   13.64 +              &abstract_type_string, result);
   13.65 +    return session->ok;
   13.66 +}
   13.67 +
   13.68 +
   13.69 +bool
   13.70 +xen_session_get_this_host(xen_session *session, xen_host *result,
   13.71 +                          xen_session *self_session)
   13.72 +{
   13.73 +    abstract_value params[] =
   13.74 +        {
   13.75 +            { .type = &abstract_type_string,
   13.76 +              .u.string_val = self_session->session_id }
   13.77 +        };
   13.78 +
   13.79 +    xen_call_(session, "session.get_this_host", params, 1,
   13.80 +              &abstract_type_string, result);
   13.81 +    return session->ok;
   13.82 +}
   13.83 +
   13.84 +
   13.85 +bool
   13.86 +xen_session_get_this_user(xen_session *session, char **result,
   13.87 +                          xen_session *self_session)
   13.88  {
   13.89      abstract_value params[] =
   13.90          {
   13.91 +            { .type = &abstract_type_string,
   13.92 +              .u.string_val = self_session->session_id }
   13.93 +        };
   13.94 +
   13.95 +    xen_call_(session, "session.get_this_user", params, 1,
   13.96 +              &abstract_type_string, result);
   13.97 +    return session->ok;
   13.98 +}
   13.99 +
  13.100 +
  13.101 +bool
  13.102 +xen_session_get_last_active(xen_session *session, time_t *result,
  13.103 +                            xen_session *self_session)
  13.104 +{
  13.105 +    abstract_value params[] =
  13.106 +        {
  13.107 +            { .type = &abstract_type_string,
  13.108 +              .u.string_val = self_session->session_id }
  13.109          };
  13.110  
  13.111 -    xen_call_(session, "session.get_this_host", params, 0,
  13.112 -              &abstract_type_string, result);
  13.113 +    xen_call_(session, "session.get_last_active", params, 1,
  13.114 +              &abstract_type_datetime, result);
  13.115 +    return session->ok;
  13.116 +}
  13.117 +
  13.118 +
  13.119 +static const struct_member xen_session_record_struct_members[] =
  13.120 +    {
  13.121 +        { .key = "uuid",
  13.122 +          .type = &abstract_type_string,
  13.123 +          .offset = offsetof(xen_session_record, uuid) },
  13.124 +        { .key = "this_host",
  13.125 +          .type = &abstract_type_ref,
  13.126 +          .offset = offsetof(xen_session_record, this_host) },
  13.127 +        { .key = "this_user",
  13.128 +          .type = &abstract_type_string,
  13.129 +          .offset = offsetof(xen_session_record, this_user) },
  13.130 +        { .key = "last_active",
  13.131 +          .type = &abstract_type_datetime,
  13.132 +          .offset = offsetof(xen_session_record, last_active) },
  13.133 +    };
  13.134 +
  13.135 +const abstract_type xen_session_record_abstract_type_ =
  13.136 +    {
  13.137 +       .typename = STRUCT,
  13.138 +       .struct_size = sizeof(xen_session_record),
  13.139 +       .member_count =
  13.140 +           sizeof(xen_session_record_struct_members) / sizeof(struct_member),
  13.141 +       .members = xen_session_record_struct_members
  13.142 +    };
  13.143 +
  13.144 +
  13.145 +bool
  13.146 +xen_session_get_record(xen_session *session, xen_session_record **result,
  13.147 +                       xen_session *self_session)
  13.148 +{
  13.149 +    abstract_value param_values[] =
  13.150 +        {
  13.151 +            { .type = &abstract_type_string,
  13.152 +              .u.string_val = self_session->session_id }
  13.153 +        };
  13.154 +
  13.155 +    abstract_type result_type = xen_session_record_abstract_type_;
  13.156 +
  13.157 +    *result = NULL;
  13.158 +    XEN_CALL_("session.get_record");
  13.159 +
  13.160      return session->ok;
  13.161  }
  13.162  
  13.163 @@ -493,16 +606,18 @@ static void destring(xen_session *s, xml
  13.164  
  13.165  
  13.166  /**
  13.167 - * result_type : STRING => value : char **, the char * is yours.
  13.168 - * result_type : ENUM   => value : int *
  13.169 - * result_type : INT    => value : int64_t *
  13.170 - * result_type : FLOAT  => value : double *
  13.171 - * result_type : BOOL   => value : bool *
  13.172 - * result_type : SET    => value : arbitrary_set **, the set is yours.
  13.173 - * result_type : MAP    => value : arbitrary_map **, the map is yours.
  13.174 - * result_type : OPT    => value : arbitrary_record_opt **,
  13.175 - *                                 the record is yours, the handle is filled.
  13.176 - * result_type : STRUCT => value : void **, the void * is yours.
  13.177 + * result_type : STRING   => value : char **, the char * is yours.
  13.178 + * result_type : ENUM     => value : int *
  13.179 + * result_type : INT      => value : int64_t *
  13.180 + * result_type : FLOAT    => value : double *
  13.181 + * result_type : BOOL     => value : bool *
  13.182 + * result_type : DATETIME => value : time_t *
  13.183 + * result_type : SET      => value : arbitrary_set **, the set is yours.
  13.184 + * result_type : MAP      => value : arbitrary_map **, the map is yours.
  13.185 + * result_type : OPT      => value : arbitrary_record_opt **,
  13.186 + *                                   the record is yours, the handle is
  13.187 + *                                   filled.
  13.188 + * result_type : STRUCT   => value : void **, the void * is yours.
  13.189   */
  13.190  static void parse_into(xen_session *s, xmlNode *value_node,
  13.191                         const abstract_type *result_type, void *value,
  13.192 @@ -625,6 +740,25 @@ static void parse_into(xen_session *s, x
  13.193      }
  13.194      break;
  13.195  
  13.196 +    case DATETIME:
  13.197 +    {
  13.198 +        xmlChar *string = string_from_value(value_node, "dateTime.iso8601");
  13.199 +        if (string == NULL)
  13.200 +        {
  13.201 +            server_error(
  13.202 +                s, "Expected an DateTime from the server but didn't get one");
  13.203 +        }
  13.204 +        else
  13.205 +        {
  13.206 +            struct tm tm;
  13.207 +            memset(&tm, 0, sizeof(tm));
  13.208 +            strptime((char *)string, "%Y%m%dT%H:%M:%S", &tm);
  13.209 +            ((time_t *)value)[slot] = (time_t)mktime(&tm);
  13.210 +            free(string);
  13.211 +        }
  13.212 +    }
  13.213 +    break;
  13.214 +
  13.215      case SET:
  13.216      {
  13.217          if (!is_container_node(value_node, "value") ||
    14.1 --- a/tools/libxen/src/xen_console.c	Mon Mar 26 09:17:25 2007 -0600
    14.2 +++ b/tools/libxen/src/xen_console.c	Mon Mar 26 10:10:31 2007 -0600
    14.3 @@ -284,6 +284,15 @@ xen_console_get_all(xen_session *session
    14.4  bool
    14.5  xen_console_get_uuid(xen_session *session, char **result, xen_console console)
    14.6  {
    14.7 -    *result = session->ok ? xen_strdup_((char *)console) : NULL;
    14.8 +    abstract_value param_values[] =
    14.9 +        {
   14.10 +            { .type = &abstract_type_string,
   14.11 +              .u.string_val = console }
   14.12 +        };
   14.13 +
   14.14 +    abstract_type result_type = abstract_type_string;
   14.15 +
   14.16 +    *result = NULL;
   14.17 +    XEN_CALL_("console.get_uuid");
   14.18      return session->ok;
   14.19  }
    15.1 --- a/tools/libxen/src/xen_crashdump.c	Mon Mar 26 09:17:25 2007 -0600
    15.2 +++ b/tools/libxen/src/xen_crashdump.c	Mon Mar 26 10:10:31 2007 -0600
    15.3 @@ -177,6 +177,15 @@ xen_crashdump_get_all(xen_session *sessi
    15.4  bool
    15.5  xen_crashdump_get_uuid(xen_session *session, char **result, xen_crashdump crashdump)
    15.6  {
    15.7 -    *result = session->ok ? xen_strdup_((char *)crashdump) : NULL;
    15.8 +    abstract_value param_values[] =
    15.9 +        {
   15.10 +            { .type = &abstract_type_string,
   15.11 +              .u.string_val = crashdump }
   15.12 +        };
   15.13 +
   15.14 +    abstract_type result_type = abstract_type_string;
   15.15 +
   15.16 +    *result = NULL;
   15.17 +    XEN_CALL_("crashdump.get_uuid");
   15.18      return session->ok;
   15.19  }
    16.1 --- a/tools/libxen/src/xen_host.c	Mon Mar 26 09:17:25 2007 -0600
    16.2 +++ b/tools/libxen/src/xen_host.c	Mon Mar 26 10:10:31 2007 -0600
    16.3 @@ -754,6 +754,15 @@ xen_host_get_all(xen_session *session, s
    16.4  bool
    16.5  xen_host_get_uuid(xen_session *session, char **result, xen_host host)
    16.6  {
    16.7 -    *result = session->ok ? xen_strdup_((char *)host) : NULL;
    16.8 +    abstract_value param_values[] =
    16.9 +        {
   16.10 +            { .type = &abstract_type_string,
   16.11 +              .u.string_val = host }
   16.12 +        };
   16.13 +
   16.14 +    abstract_type result_type = abstract_type_string;
   16.15 +
   16.16 +    *result = NULL;
   16.17 +    XEN_CALL_("host.get_uuid");
   16.18      return session->ok;
   16.19  }
    17.1 --- a/tools/libxen/src/xen_host_cpu.c	Mon Mar 26 09:17:25 2007 -0600
    17.2 +++ b/tools/libxen/src/xen_host_cpu.c	Mon Mar 26 10:10:31 2007 -0600
    17.3 @@ -282,6 +282,15 @@ xen_host_cpu_get_all(xen_session *sessio
    17.4  bool
    17.5  xen_host_cpu_get_uuid(xen_session *session, char **result, xen_host_cpu host_cpu)
    17.6  {
    17.7 -    *result = session->ok ? xen_strdup_((char *)host_cpu) : NULL;
    17.8 +    abstract_value param_values[] =
    17.9 +        {
   17.10 +            { .type = &abstract_type_string,
   17.11 +              .u.string_val = host_cpu }
   17.12 +        };
   17.13 +
   17.14 +    abstract_type result_type = abstract_type_string;
   17.15 +
   17.16 +    *result = NULL;
   17.17 +    XEN_CALL_("host_cpu.get_uuid");
   17.18      return session->ok;
   17.19  }
    18.1 --- a/tools/libxen/src/xen_host_metrics.c	Mon Mar 26 09:17:25 2007 -0600
    18.2 +++ b/tools/libxen/src/xen_host_metrics.c	Mon Mar 26 10:10:31 2007 -0600
    18.3 @@ -44,7 +44,10 @@ static const struct_member xen_host_metr
    18.4            .offset = offsetof(xen_host_metrics_record, memory_total) },
    18.5          { .key = "memory_free",
    18.6            .type = &abstract_type_int,
    18.7 -          .offset = offsetof(xen_host_metrics_record, memory_free) }
    18.8 +          .offset = offsetof(xen_host_metrics_record, memory_free) },
    18.9 +        { .key = "last_updated",
   18.10 +          .type = &abstract_type_datetime,
   18.11 +          .offset = offsetof(xen_host_metrics_record, last_updated) }
   18.12      };
   18.13  
   18.14  const abstract_type xen_host_metrics_record_abstract_type_ =
   18.15 @@ -143,6 +146,22 @@ xen_host_metrics_get_memory_free(xen_ses
   18.16  
   18.17  
   18.18  bool
   18.19 +xen_host_metrics_get_last_updated(xen_session *session, time_t *result, xen_host_metrics host_metrics)
   18.20 +{
   18.21 +    abstract_value param_values[] =
   18.22 +        {
   18.23 +            { .type = &abstract_type_string,
   18.24 +              .u.string_val = host_metrics }
   18.25 +        };
   18.26 +
   18.27 +    abstract_type result_type = abstract_type_datetime;
   18.28 +
   18.29 +    XEN_CALL_("host_metrics.get_last_updated");
   18.30 +    return session->ok;
   18.31 +}
   18.32 +
   18.33 +
   18.34 +bool
   18.35  xen_host_metrics_get_all(xen_session *session, struct xen_host_metrics_set **result)
   18.36  {
   18.37  
   18.38 @@ -157,6 +176,15 @@ xen_host_metrics_get_all(xen_session *se
   18.39  bool
   18.40  xen_host_metrics_get_uuid(xen_session *session, char **result, xen_host_metrics host_metrics)
   18.41  {
   18.42 -    *result = session->ok ? xen_strdup_((char *)host_metrics) : NULL;
   18.43 +    abstract_value param_values[] =
   18.44 +        {
   18.45 +            { .type = &abstract_type_string,
   18.46 +              .u.string_val = host_metrics }
   18.47 +        };
   18.48 +
   18.49 +    abstract_type result_type = abstract_type_string;
   18.50 +
   18.51 +    *result = NULL;
   18.52 +    XEN_CALL_("host_metrics.get_uuid");
   18.53      return session->ok;
   18.54  }
    19.1 --- a/tools/libxen/src/xen_network.c	Mon Mar 26 09:17:25 2007 -0600
    19.2 +++ b/tools/libxen/src/xen_network.c	Mon Mar 26 10:10:31 2007 -0600
    19.3 @@ -285,6 +285,15 @@ xen_network_get_all(xen_session *session
    19.4  bool
    19.5  xen_network_get_uuid(xen_session *session, char **result, xen_network network)
    19.6  {
    19.7 -    *result = session->ok ? xen_strdup_((char *)network) : NULL;
    19.8 +    abstract_value param_values[] =
    19.9 +        {
   19.10 +            { .type = &abstract_type_string,
   19.11 +              .u.string_val = network }
   19.12 +        };
   19.13 +
   19.14 +    abstract_type result_type = abstract_type_string;
   19.15 +
   19.16 +    *result = NULL;
   19.17 +    XEN_CALL_("network.get_uuid");
   19.18      return session->ok;
   19.19  }
    20.1 --- a/tools/libxen/src/xen_pbd.c	Mon Mar 26 09:17:25 2007 -0600
    20.2 +++ b/tools/libxen/src/xen_pbd.c	Mon Mar 26 10:10:31 2007 -0600
    20.3 @@ -235,6 +235,15 @@ xen_pbd_get_all(xen_session *session, st
    20.4  bool
    20.5  xen_pbd_get_uuid(xen_session *session, char **result, xen_pbd pbd)
    20.6  {
    20.7 -    *result = session->ok ? xen_strdup_((char *)pbd) : NULL;
    20.8 +    abstract_value param_values[] =
    20.9 +        {
   20.10 +            { .type = &abstract_type_string,
   20.11 +              .u.string_val = pbd }
   20.12 +        };
   20.13 +
   20.14 +    abstract_type result_type = abstract_type_string;
   20.15 +
   20.16 +    *result = NULL;
   20.17 +    XEN_CALL_("PBD.get_uuid");
   20.18      return session->ok;
   20.19  }
    21.1 --- a/tools/libxen/src/xen_pif.c	Mon Mar 26 09:17:25 2007 -0600
    21.2 +++ b/tools/libxen/src/xen_pif.c	Mon Mar 26 10:10:31 2007 -0600
    21.3 @@ -366,6 +366,15 @@ xen_pif_get_all(xen_session *session, st
    21.4  bool
    21.5  xen_pif_get_uuid(xen_session *session, char **result, xen_pif pif)
    21.6  {
    21.7 -    *result = session->ok ? xen_strdup_((char *)pif) : NULL;
    21.8 +    abstract_value param_values[] =
    21.9 +        {
   21.10 +            { .type = &abstract_type_string,
   21.11 +              .u.string_val = pif }
   21.12 +        };
   21.13 +
   21.14 +    abstract_type result_type = abstract_type_string;
   21.15 +
   21.16 +    *result = NULL;
   21.17 +    XEN_CALL_("PIF.get_uuid");
   21.18      return session->ok;
   21.19  }
    22.1 --- a/tools/libxen/src/xen_pif_metrics.c	Mon Mar 26 09:17:25 2007 -0600
    22.2 +++ b/tools/libxen/src/xen_pif_metrics.c	Mon Mar 26 10:10:31 2007 -0600
    22.3 @@ -44,7 +44,10 @@ static const struct_member xen_pif_metri
    22.4            .offset = offsetof(xen_pif_metrics_record, io_read_kbs) },
    22.5          { .key = "io_write_kbs",
    22.6            .type = &abstract_type_float,
    22.7 -          .offset = offsetof(xen_pif_metrics_record, io_write_kbs) }
    22.8 +          .offset = offsetof(xen_pif_metrics_record, io_write_kbs) },
    22.9 +        { .key = "last_updated",
   22.10 +          .type = &abstract_type_datetime,
   22.11 +          .offset = offsetof(xen_pif_metrics_record, last_updated) }
   22.12      };
   22.13  
   22.14  const abstract_type xen_pif_metrics_record_abstract_type_ =
   22.15 @@ -143,6 +146,22 @@ xen_pif_metrics_get_io_write_kbs(xen_ses
   22.16  
   22.17  
   22.18  bool
   22.19 +xen_pif_metrics_get_last_updated(xen_session *session, time_t *result, xen_pif_metrics pif_metrics)
   22.20 +{
   22.21 +    abstract_value param_values[] =
   22.22 +        {
   22.23 +            { .type = &abstract_type_string,
   22.24 +              .u.string_val = pif_metrics }
   22.25 +        };
   22.26 +
   22.27 +    abstract_type result_type = abstract_type_datetime;
   22.28 +
   22.29 +    XEN_CALL_("PIF_metrics.get_last_updated");
   22.30 +    return session->ok;
   22.31 +}
   22.32 +
   22.33 +
   22.34 +bool
   22.35  xen_pif_metrics_get_all(xen_session *session, struct xen_pif_metrics_set **result)
   22.36  {
   22.37  
   22.38 @@ -157,6 +176,15 @@ xen_pif_metrics_get_all(xen_session *ses
   22.39  bool
   22.40  xen_pif_metrics_get_uuid(xen_session *session, char **result, xen_pif_metrics pif_metrics)
   22.41  {
   22.42 -    *result = session->ok ? xen_strdup_((char *)pif_metrics) : NULL;
   22.43 +    abstract_value param_values[] =
   22.44 +        {
   22.45 +            { .type = &abstract_type_string,
   22.46 +              .u.string_val = pif_metrics }
   22.47 +        };
   22.48 +
   22.49 +    abstract_type result_type = abstract_type_string;
   22.50 +
   22.51 +    *result = NULL;
   22.52 +    XEN_CALL_("PIF_metrics.get_uuid");
   22.53      return session->ok;
   22.54  }
    23.1 --- a/tools/libxen/src/xen_sr.c	Mon Mar 26 09:17:25 2007 -0600
    23.2 +++ b/tools/libxen/src/xen_sr.c	Mon Mar 26 10:10:31 2007 -0600
    23.3 @@ -388,6 +388,15 @@ xen_sr_get_all(xen_session *session, str
    23.4  bool
    23.5  xen_sr_get_uuid(xen_session *session, char **result, xen_sr sr)
    23.6  {
    23.7 -    *result = session->ok ? xen_strdup_((char *)sr) : NULL;
    23.8 +    abstract_value param_values[] =
    23.9 +        {
   23.10 +            { .type = &abstract_type_string,
   23.11 +              .u.string_val = sr }
   23.12 +        };
   23.13 +
   23.14 +    abstract_type result_type = abstract_type_string;
   23.15 +
   23.16 +    *result = NULL;
   23.17 +    XEN_CALL_("SR.get_uuid");
   23.18      return session->ok;
   23.19  }
    24.1 --- a/tools/libxen/src/xen_user.c	Mon Mar 26 09:17:25 2007 -0600
    24.2 +++ b/tools/libxen/src/xen_user.c	Mon Mar 26 10:10:31 2007 -0600
    24.3 @@ -1,5 +1,5 @@
    24.4  /*
    24.5 - * Copyright (c) 2006, XenSource Inc.
    24.6 + * Copyright (c) 2006-2007, XenSource Inc.
    24.7   *
    24.8   * This library is free software; you can redistribute it and/or
    24.9   * modify it under the terms of the GNU Lesser General Public
   24.10 @@ -196,6 +196,15 @@ xen_user_set_fullname(xen_session *sessi
   24.11  bool
   24.12  xen_user_get_uuid(xen_session *session, char **result, xen_user user)
   24.13  {
   24.14 -    *result = session->ok ? xen_strdup_((char *)user) : NULL;
   24.15 +    abstract_value param_values[] =
   24.16 +        {
   24.17 +            { .type = &abstract_type_string,
   24.18 +              .u.string_val = user }
   24.19 +        };
   24.20 +
   24.21 +    abstract_type result_type = abstract_type_string;
   24.22 +
   24.23 +    *result = NULL;
   24.24 +    XEN_CALL_("user.get_uuid");
   24.25      return session->ok;
   24.26  }
    25.1 --- a/tools/libxen/src/xen_vbd.c	Mon Mar 26 09:17:25 2007 -0600
    25.2 +++ b/tools/libxen/src/xen_vbd.c	Mon Mar 26 10:10:31 2007 -0600
    25.3 @@ -591,6 +591,15 @@ xen_vbd_get_all(xen_session *session, st
    25.4  bool
    25.5  xen_vbd_get_uuid(xen_session *session, char **result, xen_vbd vbd)
    25.6  {
    25.7 -    *result = session->ok ? xen_strdup_((char *)vbd) : NULL;
    25.8 +    abstract_value param_values[] =
    25.9 +        {
   25.10 +            { .type = &abstract_type_string,
   25.11 +              .u.string_val = vbd }
   25.12 +        };
   25.13 +
   25.14 +    abstract_type result_type = abstract_type_string;
   25.15 +
   25.16 +    *result = NULL;
   25.17 +    XEN_CALL_("VBD.get_uuid");
   25.18      return session->ok;
   25.19  }
    26.1 --- a/tools/libxen/src/xen_vbd_metrics.c	Mon Mar 26 09:17:25 2007 -0600
    26.2 +++ b/tools/libxen/src/xen_vbd_metrics.c	Mon Mar 26 10:10:31 2007 -0600
    26.3 @@ -44,7 +44,10 @@ static const struct_member xen_vbd_metri
    26.4            .offset = offsetof(xen_vbd_metrics_record, io_read_kbs) },
    26.5          { .key = "io_write_kbs",
    26.6            .type = &abstract_type_float,
    26.7 -          .offset = offsetof(xen_vbd_metrics_record, io_write_kbs) }
    26.8 +          .offset = offsetof(xen_vbd_metrics_record, io_write_kbs) },
    26.9 +        { .key = "last_updated",
   26.10 +          .type = &abstract_type_datetime,
   26.11 +          .offset = offsetof(xen_vbd_metrics_record, last_updated) }
   26.12      };
   26.13  
   26.14  const abstract_type xen_vbd_metrics_record_abstract_type_ =
   26.15 @@ -143,6 +146,22 @@ xen_vbd_metrics_get_io_write_kbs(xen_ses
   26.16  
   26.17  
   26.18  bool
   26.19 +xen_vbd_metrics_get_last_updated(xen_session *session, time_t *result, xen_vbd_metrics vbd_metrics)
   26.20 +{
   26.21 +    abstract_value param_values[] =
   26.22 +        {
   26.23 +            { .type = &abstract_type_string,
   26.24 +              .u.string_val = vbd_metrics }
   26.25 +        };
   26.26 +
   26.27 +    abstract_type result_type = abstract_type_datetime;
   26.28 +
   26.29 +    XEN_CALL_("VBD_metrics.get_last_updated");
   26.30 +    return session->ok;
   26.31 +}
   26.32 +
   26.33 +
   26.34 +bool
   26.35  xen_vbd_metrics_get_all(xen_session *session, struct xen_vbd_metrics_set **result)
   26.36  {
   26.37  
   26.38 @@ -157,6 +176,15 @@ xen_vbd_metrics_get_all(xen_session *ses
   26.39  bool
   26.40  xen_vbd_metrics_get_uuid(xen_session *session, char **result, xen_vbd_metrics vbd_metrics)
   26.41  {
   26.42 -    *result = session->ok ? xen_strdup_((char *)vbd_metrics) : NULL;
   26.43 +    abstract_value param_values[] =
   26.44 +        {
   26.45 +            { .type = &abstract_type_string,
   26.46 +              .u.string_val = vbd_metrics }
   26.47 +        };
   26.48 +
   26.49 +    abstract_type result_type = abstract_type_string;
   26.50 +
   26.51 +    *result = NULL;
   26.52 +    XEN_CALL_("VBD_metrics.get_uuid");
   26.53      return session->ok;
   26.54  }
    27.1 --- a/tools/libxen/src/xen_vdi.c	Mon Mar 26 09:17:25 2007 -0600
    27.2 +++ b/tools/libxen/src/xen_vdi.c	Mon Mar 26 10:10:31 2007 -0600
    27.3 @@ -555,6 +555,15 @@ xen_vdi_get_all(xen_session *session, st
    27.4  bool
    27.5  xen_vdi_get_uuid(xen_session *session, char **result, xen_vdi vdi)
    27.6  {
    27.7 -    *result = session->ok ? xen_strdup_((char *)vdi) : NULL;
    27.8 +    abstract_value param_values[] =
    27.9 +        {
   27.10 +            { .type = &abstract_type_string,
   27.11 +              .u.string_val = vdi }
   27.12 +        };
   27.13 +
   27.14 +    abstract_type result_type = abstract_type_string;
   27.15 +
   27.16 +    *result = NULL;
   27.17 +    XEN_CALL_("VDI.get_uuid");
   27.18      return session->ok;
   27.19  }
    28.1 --- a/tools/libxen/src/xen_vif.c	Mon Mar 26 09:17:25 2007 -0600
    28.2 +++ b/tools/libxen/src/xen_vif.c	Mon Mar 26 10:10:31 2007 -0600
    28.3 @@ -542,6 +542,15 @@ xen_vif_get_all(xen_session *session, st
    28.4  bool
    28.5  xen_vif_get_uuid(xen_session *session, char **result, xen_vif vif)
    28.6  {
    28.7 -    *result = session->ok ? xen_strdup_((char *)vif) : NULL;
    28.8 +    abstract_value param_values[] =
    28.9 +        {
   28.10 +            { .type = &abstract_type_string,
   28.11 +              .u.string_val = vif }
   28.12 +        };
   28.13 +
   28.14 +    abstract_type result_type = abstract_type_string;
   28.15 +
   28.16 +    *result = NULL;
   28.17 +    XEN_CALL_("VIF.get_uuid");
   28.18      return session->ok;
   28.19  }
    29.1 --- a/tools/libxen/src/xen_vif_metrics.c	Mon Mar 26 09:17:25 2007 -0600
    29.2 +++ b/tools/libxen/src/xen_vif_metrics.c	Mon Mar 26 10:10:31 2007 -0600
    29.3 @@ -44,7 +44,10 @@ static const struct_member xen_vif_metri
    29.4            .offset = offsetof(xen_vif_metrics_record, io_read_kbs) },
    29.5          { .key = "io_write_kbs",
    29.6            .type = &abstract_type_float,
    29.7 -          .offset = offsetof(xen_vif_metrics_record, io_write_kbs) }
    29.8 +          .offset = offsetof(xen_vif_metrics_record, io_write_kbs) },
    29.9 +        { .key = "last_updated",
   29.10 +          .type = &abstract_type_datetime,
   29.11 +          .offset = offsetof(xen_vif_metrics_record, last_updated) }
   29.12      };
   29.13  
   29.14  const abstract_type xen_vif_metrics_record_abstract_type_ =
   29.15 @@ -143,6 +146,22 @@ xen_vif_metrics_get_io_write_kbs(xen_ses
   29.16  
   29.17  
   29.18  bool
   29.19 +xen_vif_metrics_get_last_updated(xen_session *session, time_t *result, xen_vif_metrics vif_metrics)
   29.20 +{
   29.21 +    abstract_value param_values[] =
   29.22 +        {
   29.23 +            { .type = &abstract_type_string,
   29.24 +              .u.string_val = vif_metrics }
   29.25 +        };
   29.26 +
   29.27 +    abstract_type result_type = abstract_type_datetime;
   29.28 +
   29.29 +    XEN_CALL_("VIF_metrics.get_last_updated");
   29.30 +    return session->ok;
   29.31 +}
   29.32 +
   29.33 +
   29.34 +bool
   29.35  xen_vif_metrics_get_all(xen_session *session, struct xen_vif_metrics_set **result)
   29.36  {
   29.37  
   29.38 @@ -157,6 +176,15 @@ xen_vif_metrics_get_all(xen_session *ses
   29.39  bool
   29.40  xen_vif_metrics_get_uuid(xen_session *session, char **result, xen_vif_metrics vif_metrics)
   29.41  {
   29.42 -    *result = session->ok ? xen_strdup_((char *)vif_metrics) : NULL;
   29.43 +    abstract_value param_values[] =
   29.44 +        {
   29.45 +            { .type = &abstract_type_string,
   29.46 +              .u.string_val = vif_metrics }
   29.47 +        };
   29.48 +
   29.49 +    abstract_type result_type = abstract_type_string;
   29.50 +
   29.51 +    *result = NULL;
   29.52 +    XEN_CALL_("VIF_metrics.get_uuid");
   29.53      return session->ok;
   29.54  }
    30.1 --- a/tools/libxen/src/xen_vm.c	Mon Mar 26 09:17:25 2007 -0600
    30.2 +++ b/tools/libxen/src/xen_vm.c	Mon Mar 26 10:10:31 2007 -0600
    30.3 @@ -1594,6 +1594,22 @@ xen_vm_resume(xen_session *session, xen_
    30.4  
    30.5  
    30.6  bool
    30.7 +xen_vm_set_vcpus_number_live(xen_session *session, xen_vm self, int64_t nvcpu)
    30.8 +{
    30.9 +    abstract_value param_values[] =
   30.10 +        {
   30.11 +            { .type = &abstract_type_string,
   30.12 +              .u.string_val = self },
   30.13 +            { .type = &abstract_type_int,
   30.14 +              .u.int_val = nvcpu }
   30.15 +        };
   30.16 +
   30.17 +    xen_call_(session, "VM.set_VCPUs_number_live", param_values, 2, NULL, NULL);
   30.18 +    return session->ok;
   30.19 +}
   30.20 +
   30.21 +
   30.22 +bool
   30.23  xen_vm_get_all(xen_session *session, struct xen_vm_set **result)
   30.24  {
   30.25  
   30.26 @@ -1608,6 +1624,15 @@ xen_vm_get_all(xen_session *session, str
   30.27  bool
   30.28  xen_vm_get_uuid(xen_session *session, char **result, xen_vm vm)
   30.29  {
   30.30 -    *result = session->ok ? xen_strdup_((char *)vm) : NULL;
   30.31 +    abstract_value param_values[] =
   30.32 +        {
   30.33 +            { .type = &abstract_type_string,
   30.34 +              .u.string_val = vm }
   30.35 +        };
   30.36 +
   30.37 +    abstract_type result_type = abstract_type_string;
   30.38 +
   30.39 +    *result = NULL;
   30.40 +    XEN_CALL_("VM.get_uuid");
   30.41      return session->ok;
   30.42  }
    31.1 --- a/tools/libxen/src/xen_vm_guest_metrics.c	Mon Mar 26 09:17:25 2007 -0600
    31.2 +++ b/tools/libxen/src/xen_vm_guest_metrics.c	Mon Mar 26 10:10:31 2007 -0600
    31.3 @@ -57,7 +57,10 @@ static const struct_member xen_vm_guest_
    31.4            .offset = offsetof(xen_vm_guest_metrics_record, networks) },
    31.5          { .key = "other",
    31.6            .type = &abstract_type_string_string_map,
    31.7 -          .offset = offsetof(xen_vm_guest_metrics_record, other) }
    31.8 +          .offset = offsetof(xen_vm_guest_metrics_record, other) },
    31.9 +        { .key = "last_updated",
   31.10 +          .type = &abstract_type_datetime,
   31.11 +          .offset = offsetof(xen_vm_guest_metrics_record, last_updated) }
   31.12      };
   31.13  
   31.14  const abstract_type xen_vm_guest_metrics_record_abstract_type_ =
   31.15 @@ -232,6 +235,22 @@ xen_vm_guest_metrics_get_other(xen_sessi
   31.16  
   31.17  
   31.18  bool
   31.19 +xen_vm_guest_metrics_get_last_updated(xen_session *session, time_t *result, xen_vm_guest_metrics vm_guest_metrics)
   31.20 +{
   31.21 +    abstract_value param_values[] =
   31.22 +        {
   31.23 +            { .type = &abstract_type_string,
   31.24 +              .u.string_val = vm_guest_metrics }
   31.25 +        };
   31.26 +
   31.27 +    abstract_type result_type = abstract_type_datetime;
   31.28 +
   31.29 +    XEN_CALL_("VM_guest_metrics.get_last_updated");
   31.30 +    return session->ok;
   31.31 +}
   31.32 +
   31.33 +
   31.34 +bool
   31.35  xen_vm_guest_metrics_get_all(xen_session *session, struct xen_vm_guest_metrics_set **result)
   31.36  {
   31.37  
   31.38 @@ -246,6 +265,15 @@ xen_vm_guest_metrics_get_all(xen_session
   31.39  bool
   31.40  xen_vm_guest_metrics_get_uuid(xen_session *session, char **result, xen_vm_guest_metrics vm_guest_metrics)
   31.41  {
   31.42 -    *result = session->ok ? xen_strdup_((char *)vm_guest_metrics) : NULL;
   31.43 +    abstract_value param_values[] =
   31.44 +        {
   31.45 +            { .type = &abstract_type_string,
   31.46 +              .u.string_val = vm_guest_metrics }
   31.47 +        };
   31.48 +
   31.49 +    abstract_type result_type = abstract_type_string;
   31.50 +
   31.51 +    *result = NULL;
   31.52 +    XEN_CALL_("VM_guest_metrics.get_uuid");
   31.53      return session->ok;
   31.54  }
    32.1 --- a/tools/libxen/src/xen_vm_metrics.c	Mon Mar 26 09:17:25 2007 -0600
    32.2 +++ b/tools/libxen/src/xen_vm_metrics.c	Mon Mar 26 10:10:31 2007 -0600
    32.3 @@ -48,7 +48,10 @@ static const struct_member xen_vm_metric
    32.4            .offset = offsetof(xen_vm_metrics_record, vcpus_number) },
    32.5          { .key = "VCPUs_utilisation",
    32.6            .type = &abstract_type_int_float_map,
    32.7 -          .offset = offsetof(xen_vm_metrics_record, vcpus_utilisation) }
    32.8 +          .offset = offsetof(xen_vm_metrics_record, vcpus_utilisation) },
    32.9 +        { .key = "last_updated",
   32.10 +          .type = &abstract_type_datetime,
   32.11 +          .offset = offsetof(xen_vm_metrics_record, last_updated) }
   32.12      };
   32.13  
   32.14  const abstract_type xen_vm_metrics_record_abstract_type_ =
   32.15 @@ -165,6 +168,22 @@ xen_vm_metrics_get_vcpus_utilisation(xen
   32.16  
   32.17  
   32.18  bool
   32.19 +xen_vm_metrics_get_last_updated(xen_session *session, time_t *result, xen_vm_metrics vm_metrics)
   32.20 +{
   32.21 +    abstract_value param_values[] =
   32.22 +        {
   32.23 +            { .type = &abstract_type_string,
   32.24 +              .u.string_val = vm_metrics }
   32.25 +        };
   32.26 +
   32.27 +    abstract_type result_type = abstract_type_datetime;
   32.28 +
   32.29 +    XEN_CALL_("VM_metrics.get_last_updated");
   32.30 +    return session->ok;
   32.31 +}
   32.32 +
   32.33 +
   32.34 +bool
   32.35  xen_vm_metrics_get_all(xen_session *session, struct xen_vm_metrics_set **result)
   32.36  {
   32.37  
   32.38 @@ -179,6 +198,15 @@ xen_vm_metrics_get_all(xen_session *sess
   32.39  bool
   32.40  xen_vm_metrics_get_uuid(xen_session *session, char **result, xen_vm_metrics vm_metrics)
   32.41  {
   32.42 -    *result = session->ok ? xen_strdup_((char *)vm_metrics) : NULL;
   32.43 +    abstract_value param_values[] =
   32.44 +        {
   32.45 +            { .type = &abstract_type_string,
   32.46 +              .u.string_val = vm_metrics }
   32.47 +        };
   32.48 +
   32.49 +    abstract_type result_type = abstract_type_string;
   32.50 +
   32.51 +    *result = NULL;
   32.52 +    XEN_CALL_("VM_metrics.get_uuid");
   32.53      return session->ok;
   32.54  }
    33.1 --- a/tools/libxen/src/xen_vtpm.c	Mon Mar 26 09:17:25 2007 -0600
    33.2 +++ b/tools/libxen/src/xen_vtpm.c	Mon Mar 26 10:10:31 2007 -0600
    33.3 @@ -182,6 +182,15 @@ xen_vtpm_get_backend(xen_session *sessio
    33.4  bool
    33.5  xen_vtpm_get_uuid(xen_session *session, char **result, xen_vtpm vtpm)
    33.6  {
    33.7 -    *result = session->ok ? xen_strdup_((char *)vtpm) : NULL;
    33.8 +    abstract_value param_values[] =
    33.9 +        {
   33.10 +            { .type = &abstract_type_string,
   33.11 +              .u.string_val = vtpm }
   33.12 +        };
   33.13 +
   33.14 +    abstract_type result_type = abstract_type_string;
   33.15 +
   33.16 +    *result = NULL;
   33.17 +    XEN_CALL_("VTPM.get_uuid");
   33.18      return session->ok;
   33.19  }
    34.1 --- a/tools/libxen/test/test_bindings.c	Mon Mar 26 09:17:25 2007 -0600
    34.2 +++ b/tools/libxen/test/test_bindings.c	Mon Mar 26 10:10:31 2007 -0600
    34.3 @@ -17,6 +17,7 @@
    34.4   */
    34.5  
    34.6  #define _GNU_SOURCE
    34.7 +#include <assert.h>
    34.8  #include <inttypes.h>
    34.9  #include <stdlib.h>
   34.10  #include <stdio.h>
   34.11 @@ -33,6 +34,7 @@
   34.12  #include "xen_vm.h"
   34.13  #include "xen_vm_metrics.h"
   34.14  
   34.15 +//#define PRINT_XML
   34.16  
   34.17  static void usage()
   34.18  {
   34.19 @@ -61,6 +63,7 @@ typedef struct
   34.20  
   34.21  
   34.22  static xen_vm create_new_vm(xen_session *session, bool hvm);
   34.23 +static void print_session_info(xen_session *session);
   34.24  static void print_vm_power_state(xen_session *session, xen_vm vm);
   34.25  static void print_vm_metrics(xen_session *session, xen_vm vm);
   34.26  
   34.27 @@ -69,6 +72,11 @@ static size_t
   34.28  write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
   34.29  {
   34.30      size_t n = size * nmemb;
   34.31 +#ifdef PRINT_XML
   34.32 +    printf("\n\n---Result from server -----------------------\n");
   34.33 +    printf("%s\n",((char*) ptr));
   34.34 +    fflush(stdout);
   34.35 +#endif
   34.36      return comms->func(ptr, n, comms->handle) ? n : 0;
   34.37  }
   34.38  
   34.39 @@ -79,6 +87,12 @@ call_func(const void *data, size_t len, 
   34.40  {
   34.41      (void)user_handle;
   34.42  
   34.43 +#ifdef PRINT_XML
   34.44 +    printf("\n\n---Data to server: -----------------------\n");
   34.45 +    printf("%s\n",((char*) data));
   34.46 +    fflush(stdout);
   34.47 +#endif
   34.48 +
   34.49      CURL *curl = curl_easy_init();
   34.50      if (!curl) {
   34.51          return -1;
   34.52 @@ -144,6 +158,14 @@ int main(int argc, char **argv)
   34.53      xen_session *session =
   34.54          xen_session_login_with_password(call_func, NULL, username, password);
   34.55  
   34.56 +    print_session_info(session);
   34.57 +    if (!session->ok)
   34.58 +    {
   34.59 +        /* Error has been logged, just clean up. */
   34.60 +        CLEANUP;
   34.61 +        return 1;
   34.62 +    }
   34.63 +
   34.64      xen_vm vm;
   34.65      if (!xen_vm_get_by_uuid(session, &vm,
   34.66                              "00000000-0000-0000-0000-000000000000"))
   34.67 @@ -184,7 +206,7 @@ int main(int argc, char **argv)
   34.68      }
   34.69  
   34.70      xen_host host;
   34.71 -    if (!xen_session_get_this_host(session, &host))
   34.72 +    if (!xen_session_get_this_host(session, &host, session))
   34.73      {
   34.74          print_error(session);
   34.75          xen_vm_record_free(vm_record);
   34.76 @@ -256,12 +278,12 @@ int main(int argc, char **argv)
   34.77  
   34.78      printf("%s.\n", vm_uuid);
   34.79  
   34.80 -    fprintf(stderr, "In bytes, the VM UUID is ");
   34.81 +    printf("In bytes, the VM UUID is ");
   34.82      for (int i = 0; i < 15; i++)
   34.83      {
   34.84 -        fprintf(stderr, "%x, ", (unsigned int)vm_uuid_bytes[i]);
   34.85 +        printf("%x, ", (unsigned int)vm_uuid_bytes[i]);
   34.86      }
   34.87 -    fprintf(stderr, "%x.\n", (unsigned int)vm_uuid_bytes[15]);
   34.88 +    printf("%x.\n", (unsigned int)vm_uuid_bytes[15]);
   34.89  
   34.90      printf("%zd.\n", versions->size);
   34.91  
   34.92 @@ -369,16 +391,16 @@ static xen_vm create_new_vm(xen_session 
   34.93              .name_description = hvm ? "New HVM VM" : "New PV VM",
   34.94              .user_version = 1,
   34.95              .is_a_template = false,
   34.96 -            .memory_static_max = 256,
   34.97 -            .memory_dynamic_max = 256,
   34.98 -            .memory_dynamic_min = 128,
   34.99 -            .memory_static_min = 128,
  34.100 +            .memory_static_max = 256 * 1024 * 1024,
  34.101 +            .memory_dynamic_max = 256 * 1024 * 1024,
  34.102 +            .memory_dynamic_min = 128 * 1024 * 1024,
  34.103 +            .memory_static_min = 128 * 1024 * 1024,
  34.104              .vcpus_params = vcpus_params,
  34.105              .vcpus_max = 4,
  34.106              .vcpus_at_startup = 2,
  34.107              .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
  34.108              .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
  34.109 -            .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
  34.110 +            .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_RESTART,
  34.111              .hvm_boot_policy = hvm ? "BIOS order" : NULL,
  34.112              .hvm_boot_params = hvm ? hvm_boot_params : NULL,
  34.113              .pv_bootloader   = hvm ? NULL : "pygrub",
  34.114 @@ -403,7 +425,7 @@ static xen_vm create_new_vm(xen_session 
  34.115       * Create a new disk for the new VM.
  34.116       */
  34.117      xen_sr_set *srs;
  34.118 -    if (!xen_sr_get_by_name_label(session, &srs, "Local") ||
  34.119 +    if (!xen_sr_get_by_name_label(session, &srs, "QCoW") ||
  34.120          srs->size < 1)
  34.121      {
  34.122          fprintf(stderr, "SR lookup failed.\n");
  34.123 @@ -519,16 +541,14 @@ static xen_vm create_new_vm(xen_session 
  34.124      }
  34.125  
  34.126      if (hvm) {
  34.127 -        fprintf(stderr,
  34.128 -                "Created a new HVM VM, with UUID %s, VDI UUID %s, VBD "
  34.129 -                "UUID %s, and VNC console UUID %s.\n",
  34.130 -                vm_uuid, vdi0_uuid, vbd0_uuid, vnc_uuid);
  34.131 +        printf("Created a new HVM VM, with UUID %s, VDI UUID %s, VBD "
  34.132 +               "UUID %s, and VNC console UUID %s.\n",
  34.133 +               vm_uuid, vdi0_uuid, vbd0_uuid, vnc_uuid);
  34.134      }
  34.135      else {
  34.136 -        fprintf(stderr,
  34.137 -                "Created a new PV VM, with UUID %s, VDI UUID %s, and VBD "
  34.138 -                "UUID %s.\n",
  34.139 -                vm_uuid, vdi0_uuid, vbd0_uuid);
  34.140 +        printf("Created a new PV VM, with UUID %s, VDI UUID %s, and VBD "
  34.141 +               "UUID %s.\n",
  34.142 +               vm_uuid, vdi0_uuid, vbd0_uuid);
  34.143      }
  34.144  
  34.145      xen_uuid_free(vm_uuid);
  34.146 @@ -569,6 +589,58 @@ static void print_vm_power_state(xen_ses
  34.147             xen_vm_power_state_to_string(power_state));
  34.148  
  34.149      xen_uuid_free(vm_uuid);
  34.150 +
  34.151 +    fflush(stdout);
  34.152 +}
  34.153 +
  34.154 +
  34.155 +/**
  34.156 + * Workaround for whinging GCCs, as suggested by strftime(3).
  34.157 + */
  34.158 +static size_t my_strftime(char *s, size_t max, const char *fmt,
  34.159 +                          const struct tm *tm)
  34.160 +{
  34.161 +    return strftime(s, max, fmt, tm);
  34.162 +}
  34.163 +
  34.164 +
  34.165 +/**
  34.166 + * Print some session details.
  34.167 + */
  34.168 +static void print_session_info(xen_session *session)
  34.169 +{
  34.170 +    xen_session_record *record;
  34.171 +    if (!xen_session_get_record(session, &record, session))
  34.172 +    {
  34.173 +        print_error(session);
  34.174 +        return;
  34.175 +    }
  34.176 +
  34.177 +    printf("Session UUID: %s.\n", record->uuid);
  34.178 +    printf("Session user: %s.\n", record->this_user);
  34.179 +    char time[256];
  34.180 +    struct tm *tm = localtime(&record->last_active);
  34.181 +    my_strftime(time, 256, "Session last active: %c, local time.\n", tm);
  34.182 +    printf(time);
  34.183 +
  34.184 +    char *uuid = NULL;
  34.185 +    char *this_user = NULL;
  34.186 +    xen_session_get_uuid(session, &uuid, session);
  34.187 +    xen_session_get_this_user(session, &this_user, session);
  34.188 +
  34.189 +    if (!session->ok)
  34.190 +    {
  34.191 +        xen_session_record_free(record);
  34.192 +        print_error(session);
  34.193 +        return;
  34.194 +    }
  34.195 +
  34.196 +    assert(!strcmp(record->uuid, uuid));
  34.197 +    assert(!strcmp(record->this_user, this_user));
  34.198 +
  34.199 +    xen_session_record_free(record);
  34.200 +
  34.201 +    fflush(stdout);
  34.202  }
  34.203  
  34.204  
  34.205 @@ -592,6 +664,11 @@ static void print_vm_metrics(xen_session
  34.206          return;
  34.207      }
  34.208  
  34.209 +    char time[256];
  34.210 +    struct tm *tm = localtime(&vm_metrics_record->last_updated);
  34.211 +    my_strftime(time, 256, "Metrics updated at %c, local time.\n", tm);
  34.212 +    printf(time);
  34.213 +
  34.214      for (size_t i = 0; i < vm_metrics_record->vcpus_utilisation->size; i++)
  34.215      {
  34.216          printf("%"PRId64" -> %lf.\n",
  34.217 @@ -601,4 +678,6 @@ static void print_vm_metrics(xen_session
  34.218  
  34.219      xen_vm_metrics_record_free(vm_metrics_record);
  34.220      xen_vm_metrics_free(vm_metrics);
  34.221 +
  34.222 +    fflush(stdout);
  34.223  }
    35.1 --- a/tools/misc/Makefile	Mon Mar 26 09:17:25 2007 -0600
    35.2 +++ b/tools/misc/Makefile	Mon Mar 26 10:10:31 2007 -0600
    35.3 @@ -9,7 +9,7 @@ CFLAGS   += $(INCLUDES)
    35.4  
    35.5  HDRS     = $(wildcard *.h)
    35.6  
    35.7 -TARGETS-y := xenperf xc_shadow
    35.8 +TARGETS-y := xenperf
    35.9  TARGETS-$(CONFIG_X86) += xen-detect
   35.10  TARGETS := $(TARGETS-y)
   35.11  
   35.12 @@ -43,5 +43,5 @@ clean:
   35.13  %.o: %.c $(HDRS) Makefile
   35.14  	$(CC) -c $(CFLAGS) -o $@ $<
   35.15  
   35.16 -xenperf xc_shadow: %: %.o Makefile
   35.17 +xenperf: %: %.o Makefile
   35.18  	$(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl
    36.1 --- a/tools/misc/xc_shadow.c	Mon Mar 26 09:17:25 2007 -0600
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,72 +0,0 @@
    36.4 -/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
    36.5 - ****************************************************************************
    36.6 - * (C) 2005 - Rolf Neugebauer - Intel Research Cambridge
    36.7 - ****************************************************************************
    36.8 - *
    36.9 - *        File: xc_shadow.c
   36.10 - *      Author: Rolf Neugebauer (rolf.neugebauer@intel.com)
   36.11 - *        Date: Mar 2005
   36.12 - * 
   36.13 - * Description: 
   36.14 - */
   36.15 -
   36.16 -
   36.17 -#include <xenctrl.h>
   36.18 -#include <stdio.h>
   36.19 -#include <stdlib.h>
   36.20 -#include <sys/mman.h>
   36.21 -#include <errno.h>
   36.22 -#include <string.h>
   36.23 -
   36.24 -void usage(void)
   36.25 -{
   36.26 -    printf("xc_shadow: -[0|1|2]\n");
   36.27 -    printf("    set shadow mode\n");
   36.28 -    exit(0);
   36.29 -}
   36.30 -
   36.31 -int main(int argc, char *argv[])
   36.32 -{
   36.33 -    int xc_handle;
   36.34 -    int mode = 0;
   36.35 -
   36.36 -    if ( argc > 1 )
   36.37 -    {
   36.38 -        char *p = argv[1];
   36.39 -        if (*p++ == '-') {
   36.40 -            if (*p == '1')
   36.41 -                mode = 1;
   36.42 -            else if (*p == '2')
   36.43 -                mode = 2;
   36.44 -            else if (*p == '0')
   36.45 -                mode = 0;
   36.46 -            else
   36.47 -                usage();
   36.48 -        } else
   36.49 -            usage();
   36.50 -    } 
   36.51 -    else
   36.52 -        usage();
   36.53 -
   36.54 -    if ( (xc_handle = xc_interface_open()) == -1 )
   36.55 -    {
   36.56 -        fprintf(stderr, "Error opening xc interface: %d (%s)\n",
   36.57 -                errno, strerror(errno));
   36.58 -        return 1;
   36.59 -    }
   36.60 -
   36.61 -    if ( xc_shadow_control(xc_handle,
   36.62 -                           0,
   36.63 -                           mode, 
   36.64 -                           NULL,
   36.65 -                           0,
   36.66 -                           NULL,
   36.67 -                           0,
   36.68 -                           NULL) < 0 )
   36.69 -    {    
   36.70 -        fprintf(stderr, "Error reseting performance counters: %d (%s)\n",
   36.71 -                errno, strerror(errno));
   36.72 -        return 1;
   36.73 -    }
   36.74 -    return 0;
   36.75 -}
    37.1 --- a/tools/python/xen/util/xmlrpclib2.py	Mon Mar 26 09:17:25 2007 -0600
    37.2 +++ b/tools/python/xen/util/xmlrpclib2.py	Mon Mar 26 10:10:31 2007 -0600
    37.3 @@ -54,9 +54,10 @@ def stringify(value):
    37.4         (isinstance(value, int) and not isinstance(value, bool)):
    37.5          return str(value)
    37.6      elif isinstance(value, dict):
    37.7 +        new_value = {}
    37.8          for k, v in value.items():
    37.9 -            value[k] = stringify(v)
   37.10 -        return value
   37.11 +            new_value[stringify(k)] = stringify(v)
   37.12 +        return new_value
   37.13      elif isinstance(value, (tuple, list)):
   37.14          return [stringify(v) for v in value]
   37.15      else:
    38.1 --- a/tools/python/xen/xend/XendAPI.py	Mon Mar 26 09:17:25 2007 -0600
    38.2 +++ b/tools/python/xen/xend/XendAPI.py	Mon Mar 26 10:10:31 2007 -0600
    38.3 @@ -21,6 +21,8 @@ import string
    38.4  import sys
    38.5  import traceback
    38.6  import threading
    38.7 +import time
    38.8 +import xmlrpclib
    38.9  
   38.10  from xen.xend import XendDomain, XendDomainInfo, XendNode, XendDmesg
   38.11  from xen.xend import XendLogging, XendTaskManager
   38.12 @@ -77,6 +79,11 @@ def xen_api_todo():
   38.13      """Temporary method to make sure we track down all the TODOs"""
   38.14      return {"Status": "Error", "ErrorDescription": XEND_ERROR_TODO}
   38.15  
   38.16 +
   38.17 +def now():
   38.18 +    return xmlrpclib.DateTime(time.strftime("%Y%m%dT%H:%M:%S", time.gmtime()))
   38.19 +
   38.20 +
   38.21  # ---------------------------------------------------
   38.22  # Python Method Decorators for input value validation
   38.23  # ---------------------------------------------------
   38.24 @@ -516,9 +523,12 @@ class XendAPI(object):
   38.25      # ----------------------------------------------------------------
   38.26      # NOTE: Left unwrapped by __init__
   38.27  
   38.28 -    session_attr_ro = ['this_host', 'this_user']
   38.29 +    session_attr_ro = ['this_host', 'this_user', 'last_active']
   38.30      session_methods = [('logout', None)]
   38.31  
   38.32 +    def session_get_all(self, session):
   38.33 +        return xen_api_success([session])
   38.34 +
   38.35      def session_login_with_password(self, *args):
   38.36          if len(args) != 2:
   38.37              return xen_api_error(
   38.38 @@ -527,8 +537,8 @@ class XendAPI(object):
   38.39          username = args[0]
   38.40          password = args[1]
   38.41          try:
   38.42 -            session = (self.auth == AUTH_NONE and
   38.43 -                       auth_manager().login_unconditionally(username) or
   38.44 +            session = ((self.auth == AUTH_NONE and
   38.45 +                        auth_manager().login_unconditionally(username)) or
   38.46                         auth_manager().login_with_password(username, password))
   38.47              return xen_api_success(session)
   38.48          except XendError, e:
   38.49 @@ -539,27 +549,41 @@ class XendAPI(object):
   38.50      def session_logout(self, session):
   38.51          auth_manager().logout(session)
   38.52          return xen_api_success_void()
   38.53 -    def session_get_record(self, session):
   38.54 -        record = {'uuid'     : session,
   38.55 -                  'this_host': XendNode.instance().uuid,
   38.56 -                  'this_user': auth_manager().get_user(session)}
   38.57 +
   38.58 +    def session_get_record(self, session, self_session):
   38.59 +        if self_session != session:
   38.60 +            return xen_api_error(['PERMISSION_DENIED'])
   38.61 +        record = {'uuid'       : session,
   38.62 +                  'this_host'  : XendNode.instance().uuid,
   38.63 +                  'this_user'  : auth_manager().get_user(session),
   38.64 +                  'last_active': now()}
   38.65          return xen_api_success(record)
   38.66  
   38.67 -    def session_get_uuid(self, session):
   38.68 -        return xen_api_success(session)
   38.69 +    def session_get_uuid(self, session, self_session):
   38.70 +        return xen_api_success(self_session)
   38.71  
   38.72 -    def session_get_by_uuid(self, session):
   38.73 -        return xen_api_success(session)
   38.74 +    def session_get_by_uuid(self, session, self_session):
   38.75 +        return xen_api_success(self_session)
   38.76  
   38.77      # attributes (ro)
   38.78 -    def session_get_this_host(self, session):
   38.79 +    def session_get_this_host(self, session, self_session):
   38.80 +        if self_session != session:
   38.81 +            return xen_api_error(['PERMISSION_DENIED'])
   38.82          return xen_api_success(XendNode.instance().uuid)
   38.83 -    def session_get_this_user(self, session):
   38.84 +
   38.85 +    def session_get_this_user(self, session, self_session):
   38.86 +        if self_session != session:
   38.87 +            return xen_api_error(['PERMISSION_DENIED'])
   38.88          user = auth_manager().get_user(session)
   38.89 -        if user:
   38.90 +        if user is not None:
   38.91              return xen_api_success(user)
   38.92          return xen_api_error(['SESSION_INVALID', session])
   38.93  
   38.94 +    def session_get_last_active(self, session, self_session):
   38.95 +        if self_session != session:
   38.96 +            return xen_api_error(['PERMISSION_DENIED'])
   38.97 +        return xen_api_success(now())
   38.98 +
   38.99  
  38.100      # Xen API: Class User
  38.101      # ----------------------------------------------------------------
  38.102 @@ -643,6 +667,7 @@ class XendAPI(object):
  38.103  
  38.104      host_attr_ro = ['software_version',
  38.105                      'resident_VMs',
  38.106 +                    'PIFs',
  38.107                      'host_CPUs',
  38.108                      'cpu_configuration',
  38.109                      'metrics',
  38.110 @@ -712,6 +737,8 @@ class XendAPI(object):
  38.111          return xen_api_success(XendNode.instance().xen_version())
  38.112      def host_get_resident_VMs(self, session, host_ref):
  38.113          return xen_api_success(XendDomain.instance().get_domain_refs())
  38.114 +    def host_get_PIFs(self, session, ref):
  38.115 +        return xen_api_success(XendNode.instance().get_PIF_refs())
  38.116      def host_get_host_CPUs(self, session, host_ref):
  38.117          return xen_api_success(XendNode.instance().get_host_cpu_refs())
  38.118      def host_get_metrics(self, _, ref):
  38.119 @@ -847,7 +874,8 @@ class XendAPI(object):
  38.120      # ----------------------------------------------------------------
  38.121  
  38.122      host_metrics_attr_ro = ['memory_total',
  38.123 -                            'memory_free']
  38.124 +                            'memory_free',
  38.125 +                            'last_updated']
  38.126      host_metrics_attr_rw = []
  38.127      host_metrics_methods = []
  38.128  
  38.129 @@ -862,14 +890,18 @@ class XendAPI(object):
  38.130              'uuid'         : ref,
  38.131              'memory_total' : self._host_metrics_get_memory_total(),
  38.132              'memory_free'  : self._host_metrics_get_memory_free(),
  38.133 +            'last_updated' : now(),
  38.134              })
  38.135  
  38.136 -    def host_metrics_get_memory_total(self, _, ref):
  38.137 +    def host_metrics_get_memory_total(self, _1, _2):
  38.138          return xen_api_success(self._host_metrics_get_memory_total())
  38.139  
  38.140 -    def host_metrics_get_memory_free(self, _, ref):
  38.141 +    def host_metrics_get_memory_free(self, _1, _2):
  38.142          return xen_api_success(self._host_metrics_get_memory_free())
  38.143  
  38.144 +    def host_metrics_get_last_updated(self, _1, _2):
  38.145 +        return xen_api_success(now())
  38.146 +
  38.147      def _host_metrics_get_memory_total(self):
  38.148          node = XendNode.instance()
  38.149          return node.xc.physinfo()['total_memory'] * 1024
  38.150 @@ -1009,7 +1041,8 @@ class XendAPI(object):
  38.151      # ----------------------------------------------------------------
  38.152  
  38.153      PIF_metrics_attr_ro = ['io_read_kbs',
  38.154 -                           'io_write_kbs']
  38.155 +                           'io_write_kbs',
  38.156 +                           'last_updated']
  38.157      PIF_metrics_attr_rw = []
  38.158      PIF_methods = []
  38.159  
  38.160 @@ -1028,15 +1061,15 @@ class XendAPI(object):
  38.161      def PIF_metrics_get_io_write_kbs(self, _, ref):
  38.162          return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
  38.163  
  38.164 +    def PIF_metrics_get_last_updated(self, _1, _2):
  38.165 +        return xen_api_success(now())
  38.166 +
  38.167  
  38.168      # Xen API: Class VM
  38.169      # ----------------------------------------------------------------        
  38.170  
  38.171      VM_attr_ro = ['power_state',
  38.172                    'resident_on',
  38.173 -                  'memory_static_max',                  
  38.174 -                  'memory_static_min',
  38.175 -                  'VCPUs_number',
  38.176                    'consoles',
  38.177                    'VIFs',
  38.178                    'VBDs',
  38.179 @@ -1054,6 +1087,10 @@ class XendAPI(object):
  38.180                    'auto_power_on',
  38.181                    'memory_dynamic_max',
  38.182                    'memory_dynamic_min',
  38.183 +                  'memory_static_max',
  38.184 +                  'memory_static_min',
  38.185 +                  'VCPUs_max',
  38.186 +                  'VCPUs_at_startup',
  38.187                    'VCPUs_params',
  38.188                    'actions_after_shutdown',
  38.189                    'actions_after_reboot',
  38.190 @@ -1081,17 +1118,23 @@ class XendAPI(object):
  38.191                    ('suspend', None),
  38.192                    ('resume', None),
  38.193                    ('send_sysrq', None),
  38.194 +                  ('set_VCPUs_number_live', None),
  38.195                    ('add_to_HVM_boot_params', None),
  38.196                    ('remove_from_HVM_boot_params', None),
  38.197                    ('add_to_VCPUs_params', None),
  38.198 +                  ('add_to_VCPUs_params_live', None),
  38.199                    ('remove_from_VCPUs_params', None),
  38.200                    ('add_to_platform', None),
  38.201                    ('remove_from_platform', None),
  38.202                    ('add_to_other_config', None),
  38.203                    ('remove_from_other_config', None),
  38.204 +                  ('save', None),
  38.205 +                  ('set_memory_dynamic_max_live', None),
  38.206 +                  ('set_memory_dynamic_min_live', None),
  38.207                    ('send_trigger', None)]
  38.208      
  38.209      VM_funcs  = [('create', 'VM'),
  38.210 +                 ('restore', None),
  38.211                   ('get_by_name_label', 'Set(VM)')]
  38.212  
  38.213      # parameters required for _create()
  38.214 @@ -1104,6 +1147,8 @@ class XendAPI(object):
  38.215          'memory_dynamic_max',
  38.216          'memory_dynamic_min',
  38.217          'memory_static_min',
  38.218 +        'VCPUs_max',
  38.219 +        'VCPUs_at_startup',
  38.220          'VCPUs_params',
  38.221          'actions_after_shutdown',
  38.222          'actions_after_reboot',
  38.223 @@ -1150,10 +1195,6 @@ class XendAPI(object):
  38.224          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.225          return xen_api_success(dom.get_memory_static_min())
  38.226      
  38.227 -    def VM_get_VCPUs_number(self, session, vm_ref):
  38.228 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.229 -        return xen_api_success(dom.getVCpuCount())
  38.230 -    
  38.231      def VM_get_VIFs(self, session, vm_ref):
  38.232          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.233          return xen_api_success(dom.get_vifs())
  38.234 @@ -1178,6 +1219,14 @@ class XendAPI(object):
  38.235          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.236          return xen_api_success(dom.get_metrics())
  38.237  
  38.238 +    def VM_get_VCPUs_max(self, _, vm_ref):
  38.239 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.240 +        return xen_api_todo()
  38.241 +
  38.242 +    def VM_get_VCPUs_at_startup(self, _, vm_ref):
  38.243 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.244 +        return xen_api_todo()
  38.245 +
  38.246      # attributes (rw)
  38.247      def VM_get_name_label(self, session, vm_ref):
  38.248          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.249 @@ -1191,9 +1240,8 @@ class XendAPI(object):
  38.250          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.251          return xen_api_todo()
  38.252      
  38.253 -    def VM_get_is_a_template(self, session, vm_ref):
  38.254 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.255 -        return xen_api_todo()
  38.256 +    def VM_get_is_a_template(self, session, ref):
  38.257 +        return self.VM_get('is_a_template', session, ref)
  38.258      
  38.259      def VM_get_memory_dynamic_max(self, session, vm_ref):
  38.260          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.261 @@ -1286,12 +1334,38 @@ class XendAPI(object):
  38.262      
  38.263      def VM_set_memory_dynamic_max(self, session, vm_ref, mem):
  38.264          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.265 -        return xen_api_todo()
  38.266 -    
  38.267 +        dom.set_memory_dynamic_max(int(mem))
  38.268 +        return xen_api_success_void()
  38.269 +
  38.270      def VM_set_memory_dynamic_min(self, session, vm_ref, mem):
  38.271          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.272 -        return xen_api_todo()
  38.273 +        dom.set_memory_dynamic_min(int(mem))
  38.274 +        return xen_api_success_void()
  38.275 +
  38.276 +    def VM_set_memory_static_max(self, session, vm_ref, mem):
  38.277 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.278 +        dom.set_memory_static_max(int(mem))
  38.279 +        return xen_api_success_void()
  38.280      
  38.281 +    def VM_set_memory_static_min(self, session, vm_ref, mem):
  38.282 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.283 +        dom.set_memory_static_min(int(mem))
  38.284 +        return xen_api_success_void()
  38.285 +
  38.286 +    def VM_set_memory_dynamic_max_live(self, session, vm_ref, mem):
  38.287 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.288 +        dom.set_memory_dynamic_max(int(mem))
  38.289 +        # need to pass target as MiB
  38.290 +        dom.setMemoryTarget(int(mem)/1024/1024)
  38.291 +        return xen_api_success_void()
  38.292 +
  38.293 +    def VM_set_memory_dynamic_min_live(self, session, vm_ref, mem):
  38.294 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.295 +        dom.set_memory_dynamic_min(int(mem))
  38.296 +        # need to pass target as MiB
  38.297 +        dom.setMemoryTarget(int(mem)/1024/1024)
  38.298 +        return xen_api_success_void()
  38.299 +
  38.300      def VM_set_VCPUs_params(self, session, vm_ref, value):
  38.301          return self.VM_set('vcpus_params', session, vm_ref, value)
  38.302  
  38.303 @@ -1302,6 +1376,36 @@ class XendAPI(object):
  38.304          dom.info['vcpus_params'][key] = value
  38.305          return self._VM_save(dom)
  38.306  
  38.307 +    def VM_add_to_VCPUs_params_live(self, session, vm_ref, key, value):
  38.308 +        self.VM_add_to_VCPUs_params(session, vm_ref, key, value)
  38.309 +        self._VM_VCPUs_params_refresh(vm_ref)
  38.310 +        return xen_api_success_void()
  38.311 +
  38.312 +    def _VM_VCPUs_params_refresh(self, vm_ref):
  38.313 +        xendom  = XendDomain.instance()
  38.314 +        xeninfo = xendom.get_vm_by_uuid(vm_ref)
  38.315 +
  38.316 +        #update the cpumaps
  38.317 +        for key, value in xeninfo.info['vcpus_params'].items():
  38.318 +            if key.startswith("cpumap"):
  38.319 +                vcpu = int(key[6:])
  38.320 +                try:
  38.321 +                    xendom.domain_pincpu(xeninfo.getDomid(), vcpu, value)
  38.322 +                except Exception, ex:
  38.323 +                    log.exception(ex)
  38.324 +
  38.325 +        #need to update sched params aswell
  38.326 +        if 'weight' in xeninfo.info['vcpus_params'] \
  38.327 +           and 'cap' in xeninfo.info['vcpus_params']:
  38.328 +            weight = xeninfo.info['vcpus_params']['weight']
  38.329 +            cap = xeninfo.info['vcpus_params']['cap']
  38.330 +            xendom.domain_sched_credit_set(xeninfo.getDomid(), weight, cap)
  38.331 +
  38.332 +    def VM_set_VCPUs_number_live(self, _, vm_ref, num):
  38.333 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.334 +        dom.setVCpuCount(int(num))
  38.335 +        return xen_api_success_void()
  38.336 +     
  38.337      def VM_remove_from_VCPUs_params(self, session, vm_ref, key):
  38.338          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
  38.339          if 'vcpus_params' in dom.info \
  38.340 @@ -1442,7 +1546,7 @@ class XendAPI(object):
  38.341              'name_label': xeninfo.getName(),
  38.342              'name_description': xeninfo.getName(),
  38.343              'user_version': 1,
  38.344 -            'is_a_template': False,
  38.345 +            'is_a_template': xeninfo.info['is_a_template'],
  38.346              'auto_power_on': False,
  38.347              'resident_on': XendNode.instance().uuid,
  38.348              'memory_static_min': xeninfo.get_memory_static_min(),
  38.349 @@ -1450,7 +1554,8 @@ class XendAPI(object):
  38.350              'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
  38.351              'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
  38.352              'VCPUs_params': xeninfo.get_vcpus_params(),
  38.353 -            'VCPUs_number': xeninfo.getVCpuCount(),
  38.354 +            'VCPUs_at_startup': xeninfo.getVCpuCount(),
  38.355 +            'VCPUs_max': xeninfo.getVCpuCount(),
  38.356              'actions_after_shutdown': xeninfo.get_on_shutdown(),
  38.357              'actions_after_reboot': xeninfo.get_on_reboot(),
  38.358              'actions_after_suspend': xeninfo.get_on_suspend(),
  38.359 @@ -1471,7 +1576,8 @@ class XendAPI(object):
  38.360              'tools_version': xeninfo.get_tools_version(),
  38.361              'other_config': xeninfo.info.get('other_config', {}),
  38.362              'domid': domid is None and -1 or domid,
  38.363 -            'is_control_domain': xeninfo == xendom.privilegedDomain(),
  38.364 +            'is_control_domain': xeninfo.info['is_control_domain'],
  38.365 +            'metrics': xeninfo.get_metrics()
  38.366          }
  38.367          return xen_api_success(record)
  38.368  
  38.369 @@ -1541,14 +1647,31 @@ class XendAPI(object):
  38.370          xeninfo = xendom.get_vm_by_uuid(vm_ref)
  38.371          xendom.domain_send_trigger(xeninfo.getDomid(), trigger, vcpu)
  38.372          return xen_api_success_void()
  38.373 -        
  38.374 +
  38.375 +    def VM_save(self, _, vm_ref, dest, checkpoint):
  38.376 +        xendom = XendDomain.instance()
  38.377 +        xeninfo = xendom.get_vm_by_uuid(vm_ref)
  38.378 +        xendom.domain_save(xeninfo.getDomid(), dest, checkpoint)
  38.379 +        return xen_api_success_void()
  38.380 +
  38.381 +    def VM_restore(self, _, src, paused):
  38.382 +        xendom = XendDomain.instance()
  38.383 +        xendom.domain_restore(src, bool(paused))
  38.384 +        return xen_api_success_void()
  38.385 +
  38.386  
  38.387      # Xen API: Class VM_metrics
  38.388      # ----------------------------------------------------------------
  38.389  
  38.390      VM_metrics_attr_ro = ['memory_actual',
  38.391 -                           'vcpus_number',
  38.392 -                           'vcpus_utilisation']
  38.393 +                          'VCPUs_number',
  38.394 +                          'VCPUs_utilisation',
  38.395 +                          'VCPUs_CPU',
  38.396 +                          'VCPUs_flags',
  38.397 +                          'VCPUs_params',
  38.398 +                          'state',
  38.399 +                          'start_time',
  38.400 +                          'last_updated']
  38.401      VM_metrics_attr_rw = []
  38.402      VM_metrics_methods = []
  38.403  
  38.404 @@ -1564,11 +1687,30 @@ class XendAPI(object):
  38.405      def VM_metrics_get_memory_actual(self, _, ref):
  38.406          return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
  38.407  
  38.408 -    def VM_metrics_get_vcpus_number(self, _, ref):
  38.409 -        return xen_api_success(self._VM_metrics_get(ref).get_vcpus_number())
  38.410 +    def VM_metrics_get_VCPUs_number(self, _, ref):
  38.411 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_number())
  38.412 +
  38.413 +    def VM_metrics_get_VCPUs_utilisation(self, _, ref):
  38.414 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_utilisation())
  38.415 +
  38.416 +    def VM_metrics_get_VCPUs_CPU(self, _, ref):
  38.417 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_CPU())
  38.418 +    
  38.419 +    def VM_metrics_get_VCPUs_flags(self, _, ref):
  38.420 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_flags())
  38.421  
  38.422 -    def VM_metrics_get_vcpus_utilisation(self, _, ref):
  38.423 -        return xen_api_success(self._VM_metrics_get(ref).get_vcpus_utilisation())
  38.424 +    def VM_metrics_get_VCPUs_params(self, _, ref):
  38.425 +        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_params())
  38.426 +
  38.427 +    def VM_metrics_get_start_time(self, _, ref):
  38.428 +        return xen_api_success(self._VM_metrics_get(ref).get_start_time())
  38.429 +
  38.430 +    def VM_metrics_get_state(self, _, ref):
  38.431 +        return xen_api_success(self._VM_metrics_get(ref).get_state())
  38.432 +
  38.433 +    def VM_metrics_get_last_updated(self, _1, _2):
  38.434 +        return xen_api_success(now())
  38.435 +
  38.436  
  38.437      # Xen API: Class VBD
  38.438      # ----------------------------------------------------------------
  38.439 @@ -1723,7 +1865,8 @@ class XendAPI(object):
  38.440      # ----------------------------------------------------------------
  38.441  
  38.442      VBD_metrics_attr_ro = ['io_read_kbs',
  38.443 -                           'io_write_kbs']
  38.444 +                           'io_write_kbs',
  38.445 +                           'last_updated']
  38.446      VBD_metrics_attr_rw = []
  38.447      VBD_methods = []
  38.448  
  38.449 @@ -1733,7 +1876,9 @@ class XendAPI(object):
  38.450              return xen_api_error(['HANDLE_INVALID', 'VBD_metrics', ref])
  38.451          return xen_api_success(
  38.452              { 'io_read_kbs'  : vm.get_dev_property('vbd', ref, 'io_read_kbs'),
  38.453 -              'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs') })
  38.454 +              'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs'),
  38.455 +              'last_updated' : now()
  38.456 +            })
  38.457  
  38.458      def VBD_metrics_get_io_read_kbs(self, _, ref):
  38.459          return self._VBD_get(ref, 'io_read_kbs')
  38.460 @@ -1741,6 +1886,9 @@ class XendAPI(object):
  38.461      def VBD_metrics_get_io_write_kbs(self, session, ref):
  38.462          return self._VBD_get(ref, 'io_write_kbs')
  38.463  
  38.464 +    def VBD_metrics_get_last_updated(self, _1, _2):
  38.465 +        return xen_api_success(now())
  38.466 +
  38.467  
  38.468      # Xen API: Class VIF
  38.469      # ----------------------------------------------------------------
  38.470 @@ -1857,7 +2005,8 @@ class XendAPI(object):
  38.471      # ----------------------------------------------------------------
  38.472  
  38.473      VIF_metrics_attr_ro = ['io_read_kbs',
  38.474 -                           'io_write_kbs']
  38.475 +                           'io_write_kbs',
  38.476 +                           'last_updated']
  38.477      VIF_metrics_attr_rw = []
  38.478      VIF_methods = []
  38.479  
  38.480 @@ -1867,7 +2016,9 @@ class XendAPI(object):
  38.481              return xen_api_error(['HANDLE_INVALID', 'VIF_metrics', ref])
  38.482          return xen_api_success(
  38.483              { 'io_read_kbs'  : vm.get_dev_property('vif', ref, 'io_read_kbs'),
  38.484 -              'io_write_kbs' : vm.get_dev_property('vif', ref, 'io_write_kbs') })
  38.485 +              'io_write_kbs' : vm.get_dev_property('vif', ref, 'io_write_kbs'),
  38.486 +              'last_updated' : now()
  38.487 +            })
  38.488  
  38.489      def VIF_metrics_get_io_read_kbs(self, _, ref):
  38.490          return self._VIF_get(ref, 'io_read_kbs')
  38.491 @@ -1875,6 +2026,9 @@ class XendAPI(object):
  38.492      def VIF_metrics_get_io_write_kbs(self, session, ref):
  38.493          return self._VIF_get(ref, 'io_write_kbs')
  38.494  
  38.495 +    def VIF_metrics_get_last_updated(self, _1, _2):
  38.496 +        return xen_api_success(now())
  38.497 +
  38.498  
  38.499      # Xen API: Class VDI
  38.500      # ----------------------------------------------------------------
  38.501 @@ -2347,39 +2501,3 @@ class XendAPIAsyncProxy:
  38.502                                                  synchronous_method_name,
  38.503                                                  session)
  38.504          return xen_api_success(task_uuid)
  38.505 -
  38.506 -#   
  38.507 -# Auto generate some stubs based on XendAPI introspection
  38.508 -#
  38.509 -if __name__ == "__main__":
  38.510 -    def output(line):
  38.511 -        print '    ' + line
  38.512 -    
  38.513 -    classes = ['VDI', 'SR']
  38.514 -    for cls in classes:
  38.515 -        ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
  38.516 -        rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
  38.517 -        methods  = getattr(XendAPI, '%s_methods' % cls, [])
  38.518 -        funcs    = getattr(XendAPI, '%s_funcs' % cls, [])
  38.519 -
  38.520 -        ref = '%s_ref' % cls
  38.521 -
  38.522 -        for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
  38.523 -            getter_name = '%s_get_%s' % (cls, attr_name)
  38.524 -            output('def %s(self, session, %s):' % (getter_name, ref))
  38.525 -            output('    return xen_api_todo()')
  38.526 -
  38.527 -        for attr_name in rw_attrs + XendAPI.Base_attr_rw:
  38.528 -            setter_name = '%s_set_%s' % (cls, attr_name)
  38.529 -            output('def %s(self, session, %s, value):' % (setter_name, ref))
  38.530 -            output('    return xen_api_todo()')
  38.531 -
  38.532 -        for method_name in methods + XendAPI.Base_methods:
  38.533 -            method_full_name = '%s_%s' % (cls,method_name)
  38.534 -            output('def %s(self, session, %s):' % (method_full_name, ref))
  38.535 -            output('    return xen_api_todo()')
  38.536 -
  38.537 -        for func_name in funcs + XendAPI.Base_funcs:
  38.538 -            func_full_name = '%s_%s' % (cls, func_name)
  38.539 -            output('def %s(self, session):' % func_full_name)
  38.540 -            output('    return xen_api_todo()')
    39.1 --- a/tools/python/xen/xend/XendConfig.py	Mon Mar 26 09:17:25 2007 -0600
    39.2 +++ b/tools/python/xen/xend/XendConfig.py	Mon Mar 26 10:10:31 2007 -0600
    39.3 @@ -44,7 +44,7 @@ def reverse_dict(adict):
    39.4      return dict([(v, k) for k, v in adict.items()])
    39.5  
    39.6  def bool0(v):
    39.7 -    return v != '0' and bool(v)
    39.8 +    return v != '0' and v != 'False' and bool(v)
    39.9  
   39.10  # Recursively copy a data struct, scrubbing out VNC passwords.
   39.11  # Will scrub any dict entry with a key of 'vncpasswd' or any
   39.12 @@ -81,18 +81,18 @@ def scrub_password(data):
   39.13  #
   39.14  # CPU fields:
   39.15  #
   39.16 -# vcpus_number -- the maximum number of vcpus that this domain may ever have.
   39.17 +# VCPUs_max    -- the maximum number of vcpus that this domain may ever have.
   39.18  #                 aka XendDomainInfo.getVCpuCount().
   39.19  # vcpus        -- the legacy configuration name for above.
   39.20  # max_vcpu_id  -- vcpus_number - 1.  This is given to us by Xen.
   39.21  #
   39.22  # cpus         -- the list of pCPUs available to each vCPU.
   39.23  #
   39.24 -#   vcpu_avail:  a bitmap telling the guest domain whether it may use each of
   39.25 -#                its VCPUs.  This is translated to
   39.26 -#                <dompath>/cpu/<id>/availability = {online,offline} for use
   39.27 -#                by the guest domain.
   39.28 -# online_vpcus -- the number of VCPUs currently up, as reported by Xen.  This
   39.29 +# vcpu_avail   -- a bitmap telling the guest domain whether it may use each of
   39.30 +#                 its VCPUs.  This is translated to
   39.31 +#                 <dompath>/cpu/<id>/availability = {online,offline} for use
   39.32 +#                 by the guest domain.
   39.33 +# VCPUs_live   -- the number of VCPUs currently up, as reported by Xen.  This
   39.34  #                 is changed by changing vcpu_avail, and waiting for the
   39.35  #                 domain to respond.
   39.36  #
   39.37 @@ -103,7 +103,7 @@ def scrub_password(data):
   39.38  
   39.39  XENAPI_CFG_TO_LEGACY_CFG = {
   39.40      'uuid': 'uuid',
   39.41 -    'vcpus_number': 'vcpus',
   39.42 +    'VCPUs_max': 'vcpus',
   39.43      'cpus': 'cpus',
   39.44      'name_label': 'name',
   39.45      'actions_after_shutdown': 'on_poweroff',
   39.46 @@ -128,7 +128,6 @@ XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 
   39.47  
   39.48  XENAPI_CFG_TYPES = {
   39.49      'uuid': str,
   39.50 -    'power_state': str,
   39.51      'name_label': str,
   39.52      'name_description': str,
   39.53      'user_version': str,
   39.54 @@ -139,9 +138,10 @@ XENAPI_CFG_TYPES = {
   39.55      'memory_dynamic_min': int,
   39.56      'memory_dynamic_max': int,
   39.57      'cpus': list,
   39.58 -    'vcpus_policy': str,
   39.59      'vcpus_params': dict,
   39.60 -    'vcpus_number': int,
   39.61 +    'VCPUs_max': int,
   39.62 +    'VCPUs_at_startup': int,
   39.63 +    'VCPUs_live': int,
   39.64      'actions_after_shutdown': str,
   39.65      'actions_after_reboot': str,
   39.66      'actions_after_crash': str,
   39.67 @@ -269,7 +269,7 @@ class XendConfig(dict):
   39.68              self.update_with_xenapi_config(xapi)
   39.69          elif dominfo:
   39.70              # output from xc.domain_getinfo
   39.71 -            self._dominfo_to_xapi(dominfo)
   39.72 +            self._dominfo_to_xapi(dominfo, update_mem = True)
   39.73  
   39.74          log.debug('XendConfig.init: %s' % scrub_password(self))
   39.75  
   39.76 @@ -298,6 +298,8 @@ class XendConfig(dict):
   39.77              'actions_after_reboot': 'restart',
   39.78              'actions_after_crash': 'restart',
   39.79              'actions_after_suspend': '',
   39.80 +            'is_template': False,
   39.81 +            'is_control_domain': False,
   39.82              'features': '',
   39.83              'PV_bootloader': '',
   39.84              'PV_kernel': '',
   39.85 @@ -318,7 +320,9 @@ class XendConfig(dict):
   39.86              'cpus': [],
   39.87              'cpu_weight': 256,
   39.88              'cpu_cap': 0,
   39.89 -            'vcpus_number': 1,
   39.90 +            'VCPUs_max': 1,
   39.91 +            'VCPUs_live': 1,
   39.92 +            'VCPUs_at_startup': 1,
   39.93              'vcpus_params': {},
   39.94              'console_refs': [],
   39.95              'vif_refs': [],
   39.96 @@ -371,8 +375,8 @@ class XendConfig(dict):
   39.97                                        event)
   39.98  
   39.99      def _vcpus_sanity_check(self):
  39.100 -        if 'vcpus_number' in self and 'vcpu_avail' not in self:
  39.101 -            self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
  39.102 +        if 'VCPUs_max' in self and 'vcpu_avail' not in self:
  39.103 +            self['vcpu_avail'] = (1 << self['VCPUs_max']) - 1
  39.104  
  39.105      def _uuid_sanity_check(self):
  39.106          """Make sure UUID is in proper string format with hyphens."""
  39.107 @@ -403,15 +407,17 @@ class XendConfig(dict):
  39.108          self._vcpus_sanity_check()
  39.109          self._platform_sanity_check()
  39.110  
  39.111 -    def _dominfo_to_xapi(self, dominfo):
  39.112 +    def _dominfo_to_xapi(self, dominfo, update_mem = False):
  39.113          self['domid'] = dominfo['domid']
  39.114          self['online_vcpus'] = dominfo['online_vcpus']
  39.115 -        self['vcpus_number'] = dominfo['max_vcpu_id'] + 1
  39.116 +        self['VCPUs_max'] = dominfo['max_vcpu_id'] + 1
  39.117  
  39.118 -        self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024
  39.119 -        self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024
  39.120 -        self['memory_static_min'] = 0
  39.121 -        self['memory_static_max'] = dominfo['maxmem_kb'] * 1024
  39.122 +        if update_mem:
  39.123 +            self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024
  39.124 +            self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024
  39.125 +            self['memory_static_min'] = 0
  39.126 +            self['memory_static_max'] = dominfo['maxmem_kb'] * 1024
  39.127 +            self._memory_sanity_check()
  39.128  
  39.129          self['cpu_time'] = dominfo['cpu_time']/1e9
  39.130          # TODO: i don't know what the security stuff expects here
  39.131 @@ -562,12 +568,12 @@ class XendConfig(dict):
  39.132              image_vcpus = sxp.child_value(image_sxp, 'vcpus')
  39.133              if image_vcpus != None:
  39.134                  try:
  39.135 -                    if 'vcpus_number' not in cfg:
  39.136 -                        cfg['vcpus_number'] = int(image_vcpus)
  39.137 -                    elif cfg['vcpus_number'] != int(image_vcpus):
  39.138 -                        cfg['vcpus_number'] = int(image_vcpus)
  39.139 +                    if 'VCPUs_max' not in cfg:
  39.140 +                        cfg['VCPUs_max'] = int(image_vcpus)
  39.141 +                    elif cfg['VCPUs_max'] != int(image_vcpus):
  39.142 +                        cfg['VCPUs_max'] = int(image_vcpus)
  39.143                          log.warn('Overriding vcpus from %d to %d using image'
  39.144 -                                 'vcpus value.', cfg['vcpus_number'])
  39.145 +                                 'vcpus value.', cfg['VCPUs_max'])
  39.146                  except ValueError, e:
  39.147                      raise XendConfigError('integer expeceted: %s: %s' %
  39.148                                            image_sxp, e)
  39.149 @@ -851,16 +857,6 @@ class XendConfig(dict):
  39.150          sxpr.append(["maxmem", int(self["memory_static_max"])/MiB])
  39.151          sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
  39.152  
  39.153 -        if not legacy_only:
  39.154 -            sxpr.append(['memory_dynamic_min',
  39.155 -                     int(self.get('memory_dynamic_min'))])
  39.156 -            sxpr.append(['memory_dynamic_max',
  39.157 -                     int(self.get('memory_dynamic_max'))])
  39.158 -            sxpr.append(['memory_static_max',
  39.159 -                     int(self.get('memory_static_max'))])
  39.160 -            sxpr.append(['memory_static_min',
  39.161 -                     int(self.get('memory_static_min'))])
  39.162 -
  39.163          for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
  39.164              if legacy in ('domid', 'uuid'): # skip these
  39.165                  continue
    40.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Mar 26 09:17:25 2007 -0600
    40.2 +++ b/tools/python/xen/xend/XendDomain.py	Mon Mar 26 10:10:31 2007 -0600
    40.3 @@ -34,7 +34,7 @@ import xen.lowlevel.xc
    40.4  
    40.5  from xen.xend import XendOptions, XendCheckpoint, XendDomainInfo
    40.6  from xen.xend.PrettyPrint import prettyprint
    40.7 -from xen.xend.XendConfig import XendConfig
    40.8 +from xen.xend import XendConfig
    40.9  from xen.xend.XendError import XendError, XendInvalidDomain, VmError
   40.10  from xen.xend.XendError import VMBadState
   40.11  from xen.xend.XendLogging import log
   40.12 @@ -191,6 +191,10 @@ class XendDomain:
   40.13                          self._managed_domain_register(new_dom)
   40.14                      else:
   40.15                          self._managed_domain_register(running_dom)
   40.16 +                        for key in XendConfig.XENAPI_CFG_TYPES.keys():
   40.17 +                            if key not in XendConfig.LEGACY_XENSTORE_VM_PARAMS and \
   40.18 +                                   key in dom:
   40.19 +                                running_dom.info[key] = dom[key]
   40.20                  except Exception:
   40.21                      log.exception("Failed to create reference to managed "
   40.22                                    "domain: %s" % dom_name)
   40.23 @@ -316,7 +320,7 @@ class XendDomain:
   40.24          for dom_uuid in dom_uuids:
   40.25              try:
   40.26                  cfg_file = self._managed_config_path(dom_uuid)
   40.27 -                cfg = XendConfig(filename = cfg_file)
   40.28 +                cfg = XendConfig.XendConfig(filename = cfg_file)
   40.29                  if cfg.get('uuid') != dom_uuid:
   40.30                      # something is wrong with the SXP
   40.31                      log.error("UUID mismatch in stored configuration: %s" %
   40.32 @@ -414,7 +418,7 @@ class XendDomain:
   40.33          running_domids = [d['domid'] for d in running if d['dying'] != 1]
   40.34          for domid, dom in self.domains.items():
   40.35              if domid not in running_domids and domid != DOM0_ID:
   40.36 -                self.remove_domain(dom, domid)
   40.37 +                self._remove_domain(dom, domid)
   40.38  
   40.39  
   40.40      def add_domain(self, info):
   40.41 @@ -433,6 +437,16 @@ class XendDomain:
   40.42              self._managed_domain_register(info)
   40.43  
   40.44      def remove_domain(self, info, domid = None):
   40.45 +        """Remove the domain from the list of running domains, taking the
   40.46 +        domains_lock first.
   40.47 +        """
   40.48 +        self.domains_lock.acquire()
   40.49 +        try:
   40.50 +            self._remove_domain(info, domid)
   40.51 +        finally:
   40.52 +            self.domains_lock.release()
   40.53 +
   40.54 +    def _remove_domain(self, info, domid = None):
   40.55          """Remove the domain from the list of running domains
   40.56          
   40.57          @requires: Expects to be protected by the domains_lock.
   40.58 @@ -639,14 +653,16 @@ class XendDomain:
   40.59      def get_dev_property_by_uuid(self, klass, dev_uuid, field):
   40.60          value = None
   40.61          self.domains_lock.acquire()
   40.62 +
   40.63          try:
   40.64 -            dom = self.get_vm_with_dev_uuid(klass, dev_uuid)
   40.65 -            if dom:
   40.66 -                value = dom.get_dev_property(klass, dev_uuid, field)
   40.67 -        except ValueError, e:
   40.68 -            pass
   40.69 -
   40.70 -        self.domains_lock.release()
   40.71 +            try:
   40.72 +                dom = self.get_vm_with_dev_uuid(klass, dev_uuid)
   40.73 +                if dom:
   40.74 +                    value = dom.get_dev_property(klass, dev_uuid, field)
   40.75 +            except ValueError, e:
   40.76 +                pass
   40.77 +        finally:
   40.78 +            self.domains_lock.release()
   40.79          
   40.80          return value
   40.81  
   40.82 @@ -683,7 +699,7 @@ class XendDomain:
   40.83          self.domains_lock.acquire()
   40.84          try:
   40.85              try:
   40.86 -                xeninfo = XendConfig(xapi = xenapi_vm)
   40.87 +                xeninfo = XendConfig.XendConfig(xapi = xenapi_vm)
   40.88                  dominfo = XendDomainInfo.createDormant(xeninfo)
   40.89                  log.debug("Creating new managed domain: %s: %s" %
   40.90                            (dominfo.getName(), dominfo.get_uuid()))
   40.91 @@ -906,7 +922,7 @@ class XendDomain:
   40.92          self.domains_lock.acquire()
   40.93          try:
   40.94              try:
   40.95 -                domconfig = XendConfig(sxp_obj = config)
   40.96 +                domconfig = XendConfig.XendConfig(sxp_obj = config)
   40.97                  dominfo = XendDomainInfo.createDormant(domconfig)
   40.98                  log.debug("Creating new managed domain: %s" %
   40.99                            dominfo.getName())
  40.100 @@ -971,18 +987,34 @@ class XendDomain:
  40.101                      raise VMBadState("Domain is still running",
  40.102                                       POWER_STATE_NAMES[DOM_STATE_HALTED],
  40.103                                       POWER_STATE_NAMES[dominfo.state])
  40.104 -
  40.105 -                log.info("Domain %s (%s) deleted." %
  40.106 -                         (dominfo.getName(), dominfo.info.get('uuid')))
  40.107 -
  40.108 -                self._managed_domain_unregister(dominfo)
  40.109 -                self.remove_domain(dominfo)
  40.110 -                XendDevices.destroy_device_state(dominfo)
  40.111 +                
  40.112 +                self._domain_delete_by_info(dominfo)
  40.113              except Exception, ex:
  40.114                  raise XendError(str(ex))
  40.115          finally:
  40.116              self.domains_lock.release()
  40.117 -        
  40.118 +
  40.119 +
  40.120 +    def domain_delete_by_dominfo(self, dominfo):
  40.121 +        """Only for use by XendDomainInfo.
  40.122 +        """
  40.123 +        self.domains_lock.acquire()
  40.124 +        try:
  40.125 +            self._domain_delete_by_info(dominfo)
  40.126 +        finally:
  40.127 +            self.domains_lock.release()
  40.128 +
  40.129 +
  40.130 +    def _domain_delete_by_info(self, dominfo):
  40.131 +        """Expects to be protected by domains_lock.
  40.132 +        """
  40.133 +        log.info("Domain %s (%s) deleted." %
  40.134 +                 (dominfo.getName(), dominfo.info.get('uuid')))
  40.135 +                
  40.136 +        self._managed_domain_unregister(dominfo)
  40.137 +        self._remove_domain(dominfo)
  40.138 +        XendDevices.destroy_device_state(dominfo)
  40.139 +
  40.140  
  40.141      def domain_configure(self, config):
  40.142          """Configure an existing domain.
  40.143 @@ -1230,7 +1262,9 @@ class XendDomain:
  40.144              try:
  40.145                  rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap)
  40.146              except Exception, ex:
  40.147 -                raise XendError(str(ex))
  40.148 +                log.exception(ex)
  40.149 +                raise XendError("Cannot pin vcpu: %s to cpu: %s - %s" % \
  40.150 +                                (v, cpumap, str(ex)))
  40.151          return rc
  40.152  
  40.153      def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
    41.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Mar 26 09:17:25 2007 -0600
    41.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Mar 26 10:10:31 2007 -0600
    41.3 @@ -127,6 +127,8 @@ def recreate(info, priv):
    41.4      assert not info['dying']
    41.5  
    41.6      xeninfo = XendConfig.XendConfig(dominfo = info)
    41.7 +    xeninfo['is_control_domain'] = priv
    41.8 +    xeninfo['is_a_template'] = False
    41.9      domid = xeninfo['domid']
   41.10      uuid1 = uuid.fromString(xeninfo['uuid'])
   41.11      needs_reinitialising = False
   41.12 @@ -614,9 +616,9 @@ class XendDomainInfo:
   41.13              sxpr = ['domain',
   41.14                      ['domid',      self.domid],
   41.15                      ['name',       self.info['name_label']],
   41.16 -                    ['vcpu_count', self.info['vcpus_number']]]
   41.17 -
   41.18 -            for i in range(0, self.info['vcpus_number']):
   41.19 +                    ['vcpu_count', self.info['VCPUs_max']]]
   41.20 +
   41.21 +            for i in range(0, self.info['VCPUs_max']):
   41.22                  info = xc.vcpu_getinfo(self.domid, i)
   41.23  
   41.24                  sxpr.append(['vcpu',
   41.25 @@ -660,7 +662,6 @@ class XendDomainInfo:
   41.26          vm_config = dict(zip(augment_entries, vm_config))
   41.27          
   41.28          for arg in augment_entries:
   41.29 -            xapicfg = arg
   41.30              val = vm_config[arg]
   41.31              if val != None:
   41.32                  if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
   41.33 @@ -678,7 +679,7 @@ class XendDomainInfo:
   41.34          # settings to take precedence over any entries in the store.
   41.35          if priv:
   41.36              xeninfo = dom_get(self.domid)
   41.37 -            self.info['vcpus_number'] = xeninfo['online_vcpus']
   41.38 +            self.info['VCPUs_max'] = xeninfo['online_vcpus']
   41.39              self.info['vcpu_avail'] = (1 << xeninfo['online_vcpus']) - 1
   41.40  
   41.41          # read image value
   41.42 @@ -831,7 +832,7 @@ class XendDomainInfo:
   41.43                  return 'offline'
   41.44  
   41.45          result = {}
   41.46 -        for v in range(0, self.info['vcpus_number']):
   41.47 +        for v in range(0, self.info['VCPUs_max']):
   41.48              result["cpu/%d/availability" % v] = availability(v)
   41.49          return result
   41.50  
   41.51 @@ -952,7 +953,7 @@ class XendDomainInfo:
   41.52          return self.info['features']
   41.53  
   41.54      def getVCpuCount(self):
   41.55 -        return self.info['vcpus_number']
   41.56 +        return self.info['VCPUs_max']
   41.57  
   41.58      def setVCpuCount(self, vcpus):
   41.59          if vcpus <= 0:
   41.60 @@ -964,16 +965,16 @@ class XendDomainInfo:
   41.61              # update dom differently depending on whether we are adjusting
   41.62              # vcpu number up or down, otherwise _vcpuDomDetails does not
   41.63              # disable the vcpus
   41.64 -            if self.info['vcpus_number'] > vcpus:
   41.65 +            if self.info['VCPUs_max'] > vcpus:
   41.66                  # decreasing
   41.67                  self._writeDom(self._vcpuDomDetails())
   41.68 -                self.info['vcpus_number'] = vcpus
   41.69 +                self.info['VCPUs_live'] = vcpus
   41.70              else:
   41.71                  # same or increasing
   41.72 -                self.info['vcpus_number'] = vcpus
   41.73 +                self.info['VCPUs_live'] = vcpus
   41.74                  self._writeDom(self._vcpuDomDetails())
   41.75          else:
   41.76 -            self.info['vcpus_number'] = vcpus
   41.77 +            self.info['VCPUs_live'] = vcpus
   41.78              xen.xend.XendDomain.instance().managed_config_save(self)
   41.79          log.info("Set VCPU count on domain %s to %d", self.info['name_label'],
   41.80                   vcpus)
   41.81 @@ -1427,7 +1428,7 @@ class XendDomainInfo:
   41.82          self._recreateDom()
   41.83  
   41.84          # Set maximum number of vcpus in domain
   41.85 -        xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number']))
   41.86 +        xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
   41.87  
   41.88          # register the domain in the list 
   41.89          from xen.xend import XendDomain
   41.90 @@ -1464,7 +1465,7 @@ class XendDomainInfo:
   41.91              # this is done prior to memory allocation to aide in memory
   41.92              # distribution for NUMA systems.
   41.93              if self.info['cpus'] is not None and len(self.info['cpus']) > 0:
   41.94 -                for v in range(0, self.info['vcpus_number']):
   41.95 +                for v in range(0, self.info['VCPUs_max']):
   41.96                      xc.vcpu_setaffinity(self.domid, v, self.info['cpus'])
   41.97  
   41.98              # Use architecture- and image-specific calculations to determine
   41.99 @@ -1651,6 +1652,12 @@ class XendDomainInfo:
  41.100  
  41.101          self._cleanup_phantom_devs(paths)
  41.102  
  41.103 +        if "transient" in self.info["other_config"] \
  41.104 +           and bool(self.info["other_config"]["transient"]):
  41.105 +            from xen.xend import XendDomain
  41.106 +            XendDomain.instance().domain_delete_by_dominfo(self)
  41.107 +
  41.108 +
  41.109      def destroyDomain(self):
  41.110          log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
  41.111  
  41.112 @@ -1662,26 +1669,17 @@ class XendDomainInfo:
  41.113                  self.domid = None
  41.114                  for state in DOM_STATES_OLD:
  41.115                      self.info[state] = 0
  41.116 +                self._stateSet(DOM_STATE_HALTED)
  41.117          except:
  41.118              log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
  41.119  
  41.120          from xen.xend import XendDomain
  41.121 -
  41.122 -        if "transient" in self.info["other_config"]\
  41.123 -           and bool(self.info["other_config"]["transient"]):
  41.124 -            xendDomainInstance = XendDomain.instance()
  41.125 -            
  41.126 -            xendDomainInstance.domains_lock.acquire()
  41.127 -            xendDomainInstance._refresh(refresh_shutdown = False)
  41.128 -            xendDomainInstance.domains_lock.release()
  41.129 -            
  41.130 -            xendDomainInstance.domain_delete(self.info["name_label"])
  41.131 -        else:
  41.132 -            XendDomain.instance().remove_domain(self)
  41.133 +        XendDomain.instance().remove_domain(self)
  41.134  
  41.135          self.cleanupDomain()
  41.136          self._cleanup_phantom_devs(paths)
  41.137  
  41.138 +
  41.139      def resumeDomain(self):
  41.140          log.debug("XendDomainInfo.resumeDomain(%s)", str(self.domid))
  41.141  
  41.142 @@ -1860,7 +1858,7 @@ class XendDomainInfo:
  41.143          if arch.type == "x86":
  41.144              # 1MB per vcpu plus 4Kib/Mib of RAM.  This is higher than 
  41.145              # the minimum that Xen would allocate if no value were given.
  41.146 -            overhead_kb = self.info['vcpus_number'] * 1024 + \
  41.147 +            overhead_kb = self.info['VCPUs_max'] * 1024 + \
  41.148                            (self.info['memory_static_max'] / 1024 / 1024) * 4
  41.149              overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
  41.150              # The domain might already have some shadow memory
  41.151 @@ -2082,6 +2080,16 @@ class XendDomainInfo:
  41.152          return self.info.get('memory_dynamic_max', 0)
  41.153      def get_memory_dynamic_min(self):
  41.154          return self.info.get('memory_dynamic_min', 0)
  41.155 +
  41.156 +    def set_memory_static_max(self, val):
  41.157 +        self.info['memory_static_max'] = val
  41.158 +    def set_memory_static_min(self, val):
  41.159 +        self.info['memory_static_min'] = val
  41.160 +    def set_memory_dynamic_max(self, val):
  41.161 +        self.info['memory_dynamic_max'] = val
  41.162 +    def set_memory_dynamic_min(self, val):
  41.163 +        self.info['memory_dynamic_min'] = val
  41.164 +    
  41.165      def get_vcpus_params(self):
  41.166          if self.getDomid() is None:
  41.167              return self.info['vcpus_params']
  41.168 @@ -2258,8 +2266,8 @@ class XendDomainInfo:
  41.169      def get_vcpus_util(self):
  41.170          vcpu_util = {}
  41.171          xennode = XendNode.instance()
  41.172 -        if 'vcpus_number' in self.info and self.domid != None:
  41.173 -            for i in range(0, self.info['vcpus_number']):
  41.174 +        if 'VCPUs_max' in self.info and self.domid != None:
  41.175 +            for i in range(0, self.info['VCPUs_max']):
  41.176                  util = xennode.get_vcpu_util(self.domid, i)
  41.177                  vcpu_util[str(i)] = util
  41.178                  
    42.1 --- a/tools/python/xen/xend/XendNode.py	Mon Mar 26 09:17:25 2007 -0600
    42.2 +++ b/tools/python/xen/xend/XendNode.py	Mon Mar 26 10:10:31 2007 -0600
    42.3 @@ -215,6 +215,10 @@ class XendNode:
    42.4          self.save_networks()
    42.5  
    42.6  
    42.7 +    def get_PIF_refs(self):
    42.8 +        return self.pifs.keys()
    42.9 +
   42.10 +
   42.11      def _PIF_create(self, name, mtu, vlan, mac, network, persist = True,
   42.12                      pif_uuid = None, metrics_uuid = None):
   42.13          for pif in self.pifs.values():
    43.1 --- a/tools/python/xen/xend/XendPIFMetrics.py	Mon Mar 26 09:17:25 2007 -0600
    43.2 +++ b/tools/python/xen/xend/XendPIFMetrics.py	Mon Mar 26 10:10:31 2007 -0600
    43.3 @@ -40,8 +40,10 @@ class XendPIFMetrics:
    43.4          return 0.0
    43.5  
    43.6      def get_record(self):
    43.7 +        import xen.xend.XendAPI as XendAPI
    43.8          return {'uuid'         : self.uuid,
    43.9                  'PIF'          : self.pif.uuid,
   43.10                  'io_read_kbs'  : self.get_io_read_kbs(),
   43.11 -                'io_write_kbs' : self.get_io_write_kbs()
   43.12 +                'io_write_kbs' : self.get_io_write_kbs(),
   43.13 +                'last_updated' : XendAPI.now(),
   43.14                  }
    44.1 --- a/tools/python/xen/xend/XendQCoWStorageRepo.py	Mon Mar 26 09:17:25 2007 -0600
    44.2 +++ b/tools/python/xen/xend/XendQCoWStorageRepo.py	Mon Mar 26 10:10:31 2007 -0600
    44.3 @@ -208,7 +208,8 @@ class XendQCoWStorageRepo(XendStorageRep
    44.4          self.lock.acquire()
    44.5          try:
    44.6              if not self._has_space_available_for(desired_size_bytes):
    44.7 -                raise XendError("Not enough space")
    44.8 +                raise XendError("Not enough space (need %d)" %
    44.9 +                                desired_size_bytes)
   44.10  
   44.11              image_uuid = uuid.createString()
   44.12              qcow_path = os.path.join(self.location,
   44.13 @@ -251,6 +252,7 @@ class XendQCoWStorageRepo(XendStorageRep
   44.14                  except OSError:
   44.15                      log.exception("Failed to destroy image")
   44.16                  del self.images[image_uuid]
   44.17 +                self._refresh()
   44.18                  return True
   44.19          finally:
   44.20              self.lock.release()
   44.21 @@ -317,15 +319,12 @@ class XendQCoWStorageRepo(XendStorageRep
   44.22      def create_vdi(self, vdi_struct):
   44.23          image_uuid = None
   44.24          try:
   44.25 -            sector_count = int(vdi_struct.get('virtual_size', 0))
   44.26 -            sector_size = int(vdi_struct.get('sector_size', 1024))
   44.27 -            size_bytes = (sector_count * sector_size)
   44.28 +            size_bytes = int(vdi_struct.get('virtual_size', 0))
   44.29  
   44.30              image_uuid = self._create_image_files(size_bytes)
   44.31              
   44.32              image = self.images[image_uuid]
   44.33              image_cfg = {
   44.34 -                'sector_size': sector_size,
   44.35                  'virtual_size': size_bytes,
   44.36                  'type': vdi_struct.get('type', 'system'),
   44.37                  'name_label': vdi_struct.get('name_label', ''),
   44.38 @@ -350,17 +349,3 @@ class XendQCoWStorageRepo(XendStorageRep
   44.39              raise
   44.40  
   44.41          return image_uuid
   44.42 -
   44.43 -
   44.44 -# remove everything below this line!! for testing only
   44.45 -if __name__ == "__main__":
   44.46 -    xsr = XendStorageRepository()
   44.47 -    print 'Free Space: %d MB' % (xsr.free_space_bytes()/MB)
   44.48 -    print "Create Image:",
   44.49 -    print xsr._create_image_files(10 * MB)
   44.50 -    print 'Delete all images:'
   44.51 -    for image_uuid in xsr.list_images():
   44.52 -        print image_uuid,
   44.53 -        xsr._destroy_image_files(image_uuid)
   44.54 -
   44.55 -    print
    45.1 --- a/tools/python/xen/xend/XendVMMetrics.py	Mon Mar 26 09:17:25 2007 -0600
    45.2 +++ b/tools/python/xen/xend/XendVMMetrics.py	Mon Mar 26 10:10:31 2007 -0600
    45.3 @@ -13,9 +13,13 @@
    45.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    45.5  #============================================================================
    45.6  # Copyright (c) 2006-2007 Xensource Inc.
    45.7 +# Copyright (c) 2007 Tom Wilkie
    45.8  #============================================================================
    45.9  
   45.10  from xen.xend.XendLogging import log
   45.11 +import xen.lowlevel.xc
   45.12 +
   45.13 +xc = xen.lowlevel.xc.xc()
   45.14  
   45.15  instances = {}
   45.16  
   45.17 @@ -46,25 +50,106 @@ class XendVMMetrics:
   45.18          return self.uuid
   45.19  
   45.20      def get_memory_actual(self):
   45.21 -        return self.get_record()["memory_actual"]
   45.22 +        domInfo = self.xend_domain_instance.getDomInfo()
   45.23 +        if domInfo:
   45.24 +            return domInfo["mem_kb"] * 1024
   45.25 +        else:
   45.26 +            return 0
   45.27  
   45.28 -    def get_vcpus_number(self):
   45.29 -        return self.get_record()["vcpus_number"]
   45.30 -    
   45.31 -    def get_vcpus_utilisation(self):
   45.32 -        return self.xend_domain_instance.get_vcpus_util()
   45.33 -
   45.34 -    def get_record(self):
   45.35 +    def get_VCPUs_number(self):
   45.36          domInfo = self.xend_domain_instance.getDomInfo()
   45.37          if domInfo:
   45.38 -            return { 'uuid'              : self.uuid,
   45.39 -                     'memory_actual'     : domInfo["mem_kb"] * 1024,
   45.40 -                     'vcpus_number'      : domInfo["online_vcpus"],
   45.41 -                     'vcpus_utilisation' : self.get_vcpus_utilisation()
   45.42 -                   }
   45.43 +            return domInfo["online_vcpus"]
   45.44 +        else:
   45.45 +            return 0
   45.46 +    
   45.47 +    def get_VCPUs_utilisation(self):
   45.48 +        return self.xend_domain_instance.get_vcpus_util()
   45.49 +
   45.50 +    def get_VCPUs_CPU(self):
   45.51 +        domid = self.xend_domain_instance.getDomid()
   45.52 +        if domid is not None:
   45.53 +            vcpus_cpu = {}
   45.54 +            vcpus_max = self.xend_domain_instance.info['VCPUs_max']
   45.55 +            for i in range(0, vcpus_max):
   45.56 +                info = xc.vcpu_getinfo(domid, i)
   45.57 +                vcpus_cpu[i] = info['cpu']
   45.58 +            return vcpus_cpu
   45.59 +        else:
   45.60 +            return {}
   45.61 +
   45.62 +    def get_VCPUs_flags(self):
   45.63 +        domid = self.xend_domain_instance.getDomid()
   45.64 +        if domid is not None:
   45.65 +            vcpus_flags = {}
   45.66 +            vcpus_max = self.xend_domain_instance.info['VCPUs_max']
   45.67 +            for i in range(0, vcpus_max):
   45.68 +                info = xc.vcpu_getinfo(domid, i)
   45.69 +                flags = []
   45.70 +                def set_flag(flag):
   45.71 +                    if info[flag] == 1:
   45.72 +                        flags.append(flag)
   45.73 +                set_flag('blocked')
   45.74 +                set_flag('online')
   45.75 +                set_flag('running')
   45.76 +                vcpus_flags[i] = ",".join(flags)
   45.77 +            return vcpus_flags
   45.78          else:
   45.79 -            return { 'uuid'              : self.uuid,
   45.80 -                     'memory_actual'     : 0,
   45.81 -                     'vcpus_number'      : 0,
   45.82 -                     'vcpus_utilisation' : {}
   45.83 -                   }
   45.84 +            return {}
   45.85 +
   45.86 +    def get_state(self):
   45.87 +        try:
   45.88 +            domid = self.xend_domain_instance.getDomid()
   45.89 +            domlist = xc.domain_getinfo(domid, 1)
   45.90 +            if domlist and domid == domlist[0]['domid']:
   45.91 +                dominfo = domlist[0]
   45.92 +
   45.93 +                states = []
   45.94 +                def addState(key):
   45.95 +                    if dominfo[key] == 1:
   45.96 +                        states.append(key)
   45.97 +
   45.98 +                addState("running")
   45.99 +                addState("blocked")
  45.100 +                addState("paused")
  45.101 +                addState("dying")
  45.102 +                addState("crashed")
  45.103 +                addState("shutdown")
  45.104 +                return ",".join(states)
  45.105 +        except Exception, err:
  45.106 +            # ignore missing domain
  45.107 +            log.trace("domain_getinfo(%d) failed, ignoring: %s", domid, str(err))
  45.108 +        return ""
  45.109 +
  45.110 +    def get_VCPUs_params(self):
  45.111 +        domid = self.xend_domain_instance.getDomid()
  45.112 +        if domid is not None:
  45.113 +            params_live = {}
  45.114 +            vcpus_max = self.xend_domain_instance.info['VCPUs_max']
  45.115 +            for i in range(0, vcpus_max):
  45.116 +                info = xc.vcpu_getinfo(domid, i)
  45.117 +                params_live['cpumap%i' % i] = \
  45.118 +                    ",".join(map(str, info['cpumap']))
  45.119 +
  45.120 +            params_live.update(xc.sched_credit_domain_get(domid))
  45.121 +            
  45.122 +            return params_live
  45.123 +        else:
  45.124 +            return {}
  45.125 +
  45.126 +    def get_start_time(self):
  45.127 +        return self.xend_domain_instance.info.get("start_time", -1)
  45.128 +    
  45.129 +    def get_record(self):
  45.130 +        import xen.xend.XendAPI as XendAPI
  45.131 +        return { 'uuid'              : self.uuid,
  45.132 +                 'memory_actual'     : self.get_memory_actual(),
  45.133 +                 'VCPUs_number'      : self.get_VCPUs_number(),
  45.134 +                 'VCPUs_utilisation' : self.get_VCPUs_utilisation(),
  45.135 +                 'VCPUs_CPU'         : self.get_VCPUs_CPU(),
  45.136 +                 'VCPUs_flags'       : self.get_VCPUs_flags(),
  45.137 +                 'VCPUs_params'      : self.get_VCPUs_params(),
  45.138 +                 'start_time'        : self.get_start_time(),
  45.139 +                 'state'             : self.get_state(),
  45.140 +                 'last_updated'      : XendAPI.now(),
  45.141 +               }
    46.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Mon Mar 26 09:17:25 2007 -0600
    46.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Mon Mar 26 10:10:31 2007 -0600
    46.3 @@ -101,10 +101,10 @@ class SrvDomain(SrvDir):
    46.4  
    46.5      def do_dump(self, _, req):
    46.6          fn = FormFn(self.xd.domain_dump,
    46.7 -	            [['dom',         'int'],
    46.8 -		     ['file',        'str'],
    46.9 -		     ['live',        'int'],
   46.10 -		     ['crash',       'int']])
   46.11 +                    [['dom',         'int'],
   46.12 +                     ['file',        'str'],
   46.13 +                     ['live',        'int'],
   46.14 +                     ['crash',       'int']])
   46.15          return fn(req.args, {'dom': self.dom.domid})
   46.16  
   46.17      def op_migrate(self, op, req):
   46.18 @@ -139,9 +139,9 @@ class SrvDomain(SrvDir):
   46.19                      [['dom', 'int'],
   46.20                       ['period', 'int'],
   46.21                       ['slice', 'int'],
   46.22 -		     ['latency', 'int'],
   46.23 -		     ['extratime', 'int'],
   46.24 -		     ['weight', 'int']])
   46.25 +                     ['latency', 'int'],
   46.26 +                     ['extratime', 'int'],
   46.27 +                     ['weight', 'int']])
   46.28          val = fn(req.args, {'dom': self.dom.domid})
   46.29          return val
   46.30      
    47.1 --- a/tools/python/xen/xend/server/pciquirk.py	Mon Mar 26 09:17:25 2007 -0600
    47.2 +++ b/tools/python/xen/xend/server/pciquirk.py	Mon Mar 26 10:10:31 2007 -0600
    47.3 @@ -74,7 +74,7 @@ class PCIQuirk:
    47.4                  self.pci_quirks_config = pci_quirks_config
    47.5              except Exception, ex:
    47.6                  raise XendError("Reading config file %s: %s" %
    47.7 -				(QUIRK_CONFIG_FILE, str(ex)))
    47.8 +                                (QUIRK_CONFIG_FILE, str(ex)))
    47.9          else:
   47.10              log.info("Config file does not exist: %s" % QUIRK_CONFIG_FILE)
   47.11              self.pci_quirks_config = ['xend-pci-quirks']
   47.12 @@ -83,7 +83,7 @@ class PCIQuirk:
   47.13          for dev in devices:
   47.14              ids = child_at(child(dev,'pci_ids'),0)
   47.15              fields = child_at(child(dev,'pci_config_space_fields'),0)
   47.16 -	    if self.__matchPCIdev( ids ):
   47.17 +            if self.__matchPCIdev( ids ):
   47.18                  log.info("Quirks found for PCI device [%s]" % self.devid)
   47.19                  return fields
   47.20  
   47.21 @@ -93,11 +93,11 @@ class PCIQuirk:
   47.22      def __sendQuirks(self):
   47.23          for quirk in self.quirks:
   47.24              log.debug("Quirk Info: %04x:%02x:%02x.%1x-%s" % (self.domain,
   47.25 -		    self.bus, self.slot, self.func, quirk))
   47.26 +                      self.bus, self.slot, self.func, quirk))
   47.27              try:
   47.28                  f = file(QUIRK_SYSFS_NODE ,"w")
   47.29                  f.write( "%04x:%02x:%02x.%1x-%s" % (self.domain, self.bus,
   47.30 -			self.slot, self.func, quirk) )
   47.31 +                        self.slot, self.func, quirk) )
   47.32                  f.close()
   47.33              except Exception, e:
   47.34                  raise VmError("pci: failed to open/write/close quirks " +
   47.35 @@ -118,13 +118,13 @@ class PCIQuirk:
   47.36                  self.pci_perm_dev_config = pci_perm_dev_config
   47.37              except Exception, ex:
   47.38                  raise XendError("Reading config file %s: %s" %
   47.39 -				(PERMISSIVE_CONFIG_FILE,str(ex)))
   47.40 +                                (PERMISSIVE_CONFIG_FILE,str(ex)))
   47.41          else:
   47.42              log.info("Config file does not exist: %s" % PERMISSIVE_CONFIG_FILE)
   47.43              self.pci_perm_dev_config = ['xend-pci-perm-devs']
   47.44  
   47.45          devices = child_at(child(pci_perm_dev_config, 'unconstrained_dev_ids'),0)
   47.46 -	if self.__matchPCIdev( devices ):
   47.47 +        if self.__matchPCIdev( devices ):
   47.48              log.debug("Permissive mode enabled for PCI device [%s]" %
   47.49                        self.devid)
   47.50              return True
   47.51 @@ -133,7 +133,7 @@ class PCIQuirk:
   47.52          return False
   47.53  
   47.54      def __sendPermDevs(self):
   47.55 -	if self.__devIsUnconstrained( ):
   47.56 +        if self.__devIsUnconstrained( ):
   47.57              log.debug("Unconstrained device: %04x:%02x:%02x.%1x" %
   47.58                        (self.domain, self.bus, self.slot, self.func))
   47.59              try:
    48.1 --- a/tools/python/xen/xm/main.py	Mon Mar 26 09:17:25 2007 -0600
    48.2 +++ b/tools/python/xen/xm/main.py	Mon Mar 26 10:10:31 2007 -0600
    48.3 @@ -502,6 +502,13 @@ def get_default_Network():
    48.4      return [network_ref
    48.5              for network_ref in server.xenapi.network.get_all()][0]
    48.6  
    48.7 +class XenAPIUnsupportedException(Exception):
    48.8 +    pass
    48.9 +
   48.10 +def xenapi_unsupported():
   48.11 +    if serverType == SERVER_XEN_API:
   48.12 +        raise XenAPIUnsupportedException, "This function is not supported by Xen-API"
   48.13 +
   48.14  def map2sxp(m):
   48.15      return [[k, m[k]] for k in m.keys()]
   48.16  
   48.17 @@ -550,10 +557,13 @@ def err(msg):
   48.18  
   48.19  
   48.20  def get_single_vm(dom):
   48.21 -    uuids = server.xenapi.VM.get_by_name_label(dom)
   48.22 -    n = len(uuids)
   48.23 -    if n == 1:
   48.24 -        return uuids[0]
   48.25 +    if serverType == SERVER_XEN_API:
   48.26 +        uuids = server.xenapi.VM.get_by_name_label(dom)
   48.27 +        n = len(uuids)
   48.28 +        if n > 0:
   48.29 +            return uuids[0]
   48.30 +        else:
   48.31 +            raise OptionError("Domain '%s' not found." % dom)
   48.32      else:
   48.33          dominfo = server.xend.domain(dom, False)
   48.34          return dominfo['uuid']
   48.35 @@ -569,9 +579,12 @@ class Shell(cmd.Cmd):
   48.36          cmd.Cmd.__init__(self)
   48.37          self.prompt = "xm> "
   48.38          if serverType == SERVER_XEN_API:
   48.39 -            res = server.xenapi._UNSUPPORTED_list_all_methods()
   48.40 -            for f in res:
   48.41 -                setattr(Shell, 'do_' + f + ' ', self.default)
   48.42 +            try:
   48.43 +                res = server.xenapi._UNSUPPORTED_list_all_methods()
   48.44 +                for f in res:
   48.45 +                    setattr(Shell, 'do_' + f + ' ', self.default)
   48.46 +            except:
   48.47 +                pass
   48.48  
   48.49      def preloop(self):
   48.50          cmd.Cmd.preloop(self)
   48.51 @@ -627,14 +640,18 @@ def xm_shell(args):
   48.52  #########################################################################
   48.53  
   48.54  def xm_save(args):
   48.55 +
   48.56      arg_check(args, "save", 2, 3)
   48.57 -
   48.58 +    
   48.59      try:
   48.60          (options, params) = getopt.gnu_getopt(args, 'c', ['checkpoint'])
   48.61      except getopt.GetoptError, opterr:
   48.62          err(opterr)
   48.63          sys.exit(1)
   48.64  
   48.65 +    dom = params[0]
   48.66 +    savefile = params[1]
   48.67 +
   48.68      checkpoint = False
   48.69      for (k, v) in options:
   48.70          if k in ['-c', '--checkpoint']:
   48.71 @@ -645,19 +662,22 @@ def xm_save(args):
   48.72          usage('save')
   48.73          sys.exit(1)
   48.74  
   48.75 -    try:
   48.76 -        dominfo = parse_doms_info(server.xend.domain(params[0]))
   48.77 -    except xmlrpclib.Fault, ex:
   48.78 -        raise ex
   48.79 -    
   48.80 -    domid = dominfo['domid']
   48.81 -    savefile = os.path.abspath(params[1])
   48.82 +    savefile = os.path.abspath(savefile)
   48.83  
   48.84      if not os.access(os.path.dirname(savefile), os.W_OK):
   48.85          err("xm save: Unable to create file %s" % savefile)
   48.86          sys.exit(1)
   48.87 +        
   48.88 +    if serverType == SERVER_XEN_API:       
   48.89 +        server.xenapi.VM.save(get_single_vm(dom), savefile, checkpoint)
   48.90 +    else:
   48.91 +        try:
   48.92 +            dominfo = parse_doms_info(server.xend.domain(dom))
   48.93 +        except xmlrpclib.Fault, ex:
   48.94 +            raise ex
   48.95      
   48.96 -    server.xend.domain.save(domid, savefile, checkpoint)
   48.97 +        domid = dominfo['domid']
   48.98 +        server.xend.domain.save(domid, savefile, checkpoint)
   48.99      
  48.100  def xm_restore(args):
  48.101      arg_check(args, "restore", 1, 2)
  48.102 @@ -683,7 +703,10 @@ def xm_restore(args):
  48.103          err("xm restore: Unable to read file %s" % savefile)
  48.104          sys.exit(1)
  48.105  
  48.106 -    server.xend.domain.restore(savefile, paused)
  48.107 +    if serverType == SERVER_XEN_API:
  48.108 +        server.xenapi.VM.restore(savefile, paused)
  48.109 +    else:
  48.110 +        server.xend.domain.restore(savefile, paused)
  48.111  
  48.112  
  48.113  def getDomains(domain_names, state, full = 0):
  48.114 @@ -695,12 +718,24 @@ def getDomains(domain_names, state, full
  48.115              dom_rec = server.xenapi.VM.get_record(dom_ref)
  48.116              dom_metrics_ref = server.xenapi.VM.get_metrics(dom_ref)
  48.117              dom_metrics = server.xenapi.VM_metrics.get_record(dom_metrics_ref)
  48.118 +
  48.119 +            states = ('running', 'blocked', 'paused', 'shutdown',
  48.120 +                      'crashed', 'dying')
  48.121 +            def state_on_off(state):
  48.122 +                if dom_metrics['state'].find(state) > -1:
  48.123 +                    return state[0]
  48.124 +                else:
  48.125 +                    return "-"
  48.126 +            state_str = "".join([state_on_off(state)
  48.127 +                                 for state in states])
  48.128 +            
  48.129              dom_rec.update({'name':     dom_rec['name_label'],
  48.130                              'memory_actual': int(dom_metrics['memory_actual'])/1024,
  48.131 -                            'vcpus':    dom_metrics['vcpus_number'],
  48.132 -                            'state':    '-----',
  48.133 -                            'cpu_time': dom_metrics['vcpus_utilisation']})
  48.134 -			
  48.135 +                            'vcpus':    dom_metrics['VCPUs_number'],
  48.136 +                            'state':    state_str,
  48.137 +                            'cpu_time': dom_metrics['VCPUs_utilisation'],
  48.138 +                            'start_time': dom_metrics['start_time']})
  48.139 +
  48.140              doms_sxp.append(['domain'] + map2sxp(dom_rec))
  48.141              doms_dict.append(dom_rec)
  48.142              
  48.143 @@ -885,11 +920,71 @@ def xm_label_list(doms):
  48.144  
  48.145  
  48.146  def xm_vcpu_list(args):
  48.147 -    if args:
  48.148 -        dominfo = map(server.xend.domain.getVCPUInfo, args)
  48.149 -    else:
  48.150 -        doms = server.xend.domains(False)
  48.151 -        dominfo = map(server.xend.domain.getVCPUInfo, doms)
  48.152 +    if serverType == SERVER_XEN_API:
  48.153 +        if args:
  48.154 +            vm_refs = map(get_single_vm, args)
  48.155 +        else:
  48.156 +            vm_refs = server.xenapi.VM.get_all()
  48.157 +            
  48.158 +        vm_records = dict(map(lambda vm_ref:
  48.159 +                                  (vm_ref, server.xenapi.VM.get_record(
  48.160 +                                      vm_ref)),
  48.161 +                              vm_refs))
  48.162 +
  48.163 +        vm_metrics = dict(map(lambda (ref, record):
  48.164 +                                  (ref,
  48.165 +                                   server.xenapi.VM_metrics.get_record(
  48.166 +                                       record['metrics'])),
  48.167 +                              vm_records.items()))
  48.168 +
  48.169 +        dominfo = []
  48.170 +
  48.171 +        # vcpu_list doesn't list 'managed' domains
  48.172 +        # when they are not running, so filter them out
  48.173 +
  48.174 +        vm_refs = [vm_ref
  48.175 +                  for vm_ref in vm_refs
  48.176 +                  if vm_records[vm_ref]["power_state"] != "Halted"]
  48.177 +
  48.178 +        for vm_ref in vm_refs:
  48.179 +            info = ['domain',
  48.180 +                    ['domid',      vm_records[vm_ref]['domid']],
  48.181 +                    ['name',       vm_records[vm_ref]['name_label']],
  48.182 +                    ['vcpu_count', vm_records[vm_ref]['VCPUs_max']]]
  48.183 +
  48.184 +            
  48.185 +
  48.186 +            for i in range(int(vm_records[vm_ref]['VCPUs_max'])):
  48.187 +                def chk_flag(flag):
  48.188 +                    return vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
  48.189 +                           .find(flag) > -1 and 1 or 0
  48.190 +                
  48.191 +                vcpu_info = ['vcpu',
  48.192 +                             ['number',
  48.193 +                                  i],
  48.194 +                             ['online',
  48.195 +                                  chk_flag("online")],
  48.196 +                             ['blocked',
  48.197 +                                  chk_flag("blocked")],
  48.198 +                             ['running',
  48.199 +                                  chk_flag("running")],
  48.200 +                             ['cpu_time',
  48.201 +                                  vm_metrics[vm_ref]['VCPUs_utilisation'][str(i)]],
  48.202 +                             ['cpu',
  48.203 +                                  vm_metrics[vm_ref]['VCPUs_CPU'][str(i)]],
  48.204 +                             ['cpumap',
  48.205 +                                  vm_metrics[vm_ref]['VCPUs_params']\
  48.206 +                                  ['cpumap%i' % i].split(",")]]
  48.207 +                
  48.208 +                info.append(vcpu_info)
  48.209 +
  48.210 +            dominfo.append(info)
  48.211 +    else:    
  48.212 +        if args:
  48.213 +            dominfo = map(server.xend.domain.getVCPUInfo, args)
  48.214 +        else:
  48.215 +            doms = server.xend.domains(False)
  48.216 +            dominfo = map(server.xend.domain.getVCPUInfo, doms)
  48.217  
  48.218      print '%-32s %3s %5s %5s %5s %9s %s' % \
  48.219            ('Name', 'ID', 'VCPU', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
  48.220 @@ -947,16 +1042,20 @@ def xm_vcpu_list(args):
  48.221              cpumap = map(lambda x: int(x), cpumap)
  48.222              cpumap.sort()
  48.223  
  48.224 -            for x in server.xend.node.info()[1:]:
  48.225 -                if len(x) > 1 and x[0] == 'nr_cpus':
  48.226 -                    nr_cpus = int(x[1])
  48.227 -                    # normalize cpumap by modulus nr_cpus, and drop duplicates
  48.228 -                    cpumap = dict.fromkeys(
  48.229 -                                map(lambda x: x % nr_cpus, cpumap)).keys()
  48.230 -                    if len(cpumap) == nr_cpus:
  48.231 -                        return "any cpu"
  48.232 -                    break
  48.233 - 
  48.234 +            if serverType == SERVER_XEN_API:
  48.235 +                nr_cpus = len(server.xenapi.host.get_host_CPUs(
  48.236 +                    server.xenapi.session.get_this_host()))
  48.237 +            else:
  48.238 +                for x in server.xend.node.info()[1:]:
  48.239 +                    if len(x) > 1 and x[0] == 'nr_cpus':
  48.240 +                        nr_cpus = int(x[1])
  48.241 +
  48.242 +            # normalize cpumap by modulus nr_cpus, and drop duplicates
  48.243 +            cpumap = dict.fromkeys(
  48.244 +                       map(lambda x: x % nr_cpus, cpumap)).keys()
  48.245 +            if len(cpumap) == nr_cpus:
  48.246 +                return "any cpu"
  48.247 +
  48.248              return format_pairs(list_to_rangepairs(cpumap))
  48.249  
  48.250          name  =     get_info('name')
  48.251 @@ -1154,13 +1253,17 @@ def xm_vcpu_pin(args):
  48.252          return cpus
  48.253  
  48.254      dom  = args[0]
  48.255 -    vcpu = args[1]
  48.256 +    vcpu = int(args[1])
  48.257      if args[2] == 'all':
  48.258          cpumap = cpu_make_map('0-63')
  48.259      else:
  48.260          cpumap = cpu_make_map(args[2])
  48.261 -    
  48.262 -    server.xend.domain.pincpu(dom, vcpu, cpumap)
  48.263 +
  48.264 +    if serverType == SERVER_XEN_API:
  48.265 +        server.xenapi.VM.add_to_VCPUs_params_live(
  48.266 +            get_single_vm(dom), "cpumap%i" % vcpu, ",".join(cpumap))
  48.267 +    else:
  48.268 +        server.xend.domain.pincpu(dom, vcpu, cpumap)
  48.269  
  48.270  def xm_mem_max(args):
  48.271      arg_check(args, "mem-max", 2)
  48.272 @@ -1181,8 +1284,10 @@ def xm_mem_set(args):
  48.273  
  48.274      if serverType == SERVER_XEN_API:
  48.275          mem_target = int_unit(args[1], 'm') * 1024 * 1024
  48.276 -        server.xenapi.VM.set_memory_dynamic_max(get_single_vm(dom), mem_target)
  48.277 -        server.xenapi.VM.set_memory_dynamic_min(get_single_vm(dom), mem_target)
  48.278 +        server.xenapi.VM.set_memory_dynamic_max_live(get_single_vm(dom),
  48.279 +                                                     mem_target)
  48.280 +        server.xenapi.VM.set_memory_dynamic_min_live(get_single_vm(dom),
  48.281 +                                                     mem_target)
  48.282      else:
  48.283          mem_target = int_unit(args[1], 'm')
  48.284          server.xend.domain.setMemoryTarget(dom, mem_target)
  48.285 @@ -1194,7 +1299,7 @@ def xm_vcpu_set(args):
  48.286      vcpus = int(args[1])
  48.287  
  48.288      if serverType == SERVER_XEN_API:
  48.289 -        server.xenapi.VM.set_vcpus_live(get_single_vm(dom), vcpus)
  48.290 +        server.xenapi.VM.set_VCPUs_number_live(get_single_vm(dom), vcpus)
  48.291      else:
  48.292          server.xend.domain.setVCpuCount(dom, vcpus)
  48.293  
  48.294 @@ -1231,6 +1336,8 @@ def xm_domname(args):
  48.295          print sxp.child_value(dom, 'name')
  48.296  
  48.297  def xm_sched_sedf(args):
  48.298 +    xenapi_unsupported()
  48.299 +    
  48.300      def ns_to_ms(val):
  48.301          return float(val) * 0.000001
  48.302      
  48.303 @@ -1355,10 +1462,21 @@ def xm_sched_credit(args):
  48.304          
  48.305          for d in doms:
  48.306              try:
  48.307 -                info = server.xend.domain.sched_credit_get(d['domid'])
  48.308 +                if serverType == SERVER_XEN_API:
  48.309 +                    info = server.xenapi.VM_metrics.get_VCPUs_params(
  48.310 +                        server.xenapi.VM.get_metrics(
  48.311 +                            get_single_vm(d['name'])))
  48.312 +                else:
  48.313 +                    info = server.xend.domain.sched_credit_get(d['domid'])
  48.314              except xmlrpclib.Fault:
  48.315 +                pass
  48.316 +
  48.317 +            if 'weight' not in info or 'cap' not in info:
  48.318                  # domain does not support sched-credit?
  48.319                  info = {'weight': -1, 'cap': -1}
  48.320 +
  48.321 +            info['weight'] = int(info['weight'])
  48.322 +            info['cap']    = int(info['cap'])
  48.323              
  48.324              info['name']  = d['name']
  48.325              info['domid'] = int(d['domid'])
  48.326 @@ -1368,10 +1486,20 @@ def xm_sched_credit(args):
  48.327              # place holder for system-wide scheduler parameters
  48.328              err("No domain given.")
  48.329              usage('sched-credit')
  48.330 -        
  48.331 -        result = server.xend.domain.sched_credit_set(domid, weight, cap)
  48.332 -        if result != 0:
  48.333 -            err(str(result))
  48.334 +
  48.335 +        if serverType == SERVER_XEN_API:
  48.336 +            server.xenapi.VM.add_to_VCPUs_params_live(
  48.337 +                get_single_vm(domid),
  48.338 +                "weight",
  48.339 +                weight)
  48.340 +            server.xenapi.VM.add_to_VCPUs_params_live(
  48.341 +                get_single_vm(domid),
  48.342 +                "cap",
  48.343 +                cap)            
  48.344 +        else:
  48.345 +            result = server.xend.domain.sched_credit_set(domid, weight, cap)
  48.346 +            if result != 0:
  48.347 +                err(str(result))
  48.348  
  48.349  def xm_info(args):
  48.350      arg_check(args, "info", 0)
  48.351 @@ -1754,6 +1882,7 @@ def xm_block_list(args):
  48.352                     % ni)
  48.353  
  48.354  def xm_vtpm_list(args):
  48.355 +    xenapi_unsupported()
  48.356      (use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
  48.357  
  48.358      dom = params[0]
  48.359 @@ -1883,7 +2012,10 @@ def xm_network_attach(args):
  48.360              record = vif_record
  48.361              for key in keys[:-1]:
  48.362                  record = record[key]
  48.363 -            record[keys[-1]] = val 
  48.364 +            record[keys[-1]] = val
  48.365 +
  48.366 +        def get_net_from_bridge(bridge):
  48.367 +            raise "Not supported just yet"
  48.368           
  48.369          vif_conv = {
  48.370              'type':
  48.371 @@ -1991,6 +2123,7 @@ def xm_network_detach(args):
  48.372  
  48.373  
  48.374  def xm_vnet_list(args):
  48.375 +    xenapi_unsupported()
  48.376      try:
  48.377          (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
  48.378      except getopt.GetoptError, opterr:
  48.379 @@ -2019,6 +2152,7 @@ def xm_vnet_list(args):
  48.380              print vnet, ex
  48.381  
  48.382  def xm_vnet_create(args):
  48.383 +    xenapi_unsupported()
  48.384      arg_check(args, "vnet-create", 1)
  48.385      conf = args[0]
  48.386      if not os.access(conf, os.R_OK):
  48.387 @@ -2028,6 +2162,7 @@ def xm_vnet_create(args):
  48.388      server.xend_vnet_create(conf)
  48.389  
  48.390  def xm_vnet_delete(args):
  48.391 +    xenapi_unsupported()
  48.392      arg_check(args, "vnet-delete", 1)
  48.393      vnet = args[0]
  48.394      server.xend_vnet_delete(vnet)
  48.395 @@ -2044,7 +2179,7 @@ commands = {
  48.396      "domid": xm_domid,
  48.397      "domname": xm_domname,
  48.398      "dump-core": xm_dump_core,
  48.399 -    "reboot": xm_reboot,    
  48.400 +    "reboot": xm_reboot,
  48.401      "rename": xm_rename,
  48.402      "restore": xm_restore,
  48.403      "resume": xm_resume,
  48.404 @@ -2228,6 +2363,8 @@ def _run_cmd(cmd, cmd_name, args):
  48.405          err(str(e))
  48.406          _usage(cmd_name)
  48.407          print e.usage
  48.408 +    except XenAPIUnsupportedException, e:
  48.409 +        err(str(e))
  48.410      except Exception, e:
  48.411          if serverType != SERVER_XEN_API:
  48.412             from xen.util import security
    49.1 --- a/tools/python/xen/xm/xenapi_create.py	Mon Mar 26 09:17:25 2007 -0600
    49.2 +++ b/tools/python/xen/xm/xenapi_create.py	Mon Mar 26 10:10:31 2007 -0600
    49.3 @@ -242,9 +242,9 @@ class xenapi_create:
    49.4              "user_version":
    49.5                  get_text_in_child_node(vm, "version"),
    49.6              "is_a_template":
    49.7 -                vm.attributes["is_a_template"].value,
    49.8 +                vm.attributes["is_a_template"].value == 'true',
    49.9              "auto_power_on":
   49.10 -                vm.attributes["auto_power_on"].value,
   49.11 +                vm.attributes["auto_power_on"].value == 'true',
   49.12              "memory_static_max":
   49.13                  get_child_node_attribute(vm, "memory", "static_max"),
   49.14              "memory_static_min":
   49.15 @@ -253,11 +253,11 @@ class xenapi_create:
   49.16                  get_child_node_attribute(vm, "memory", "dynamic_max"),
   49.17              "memory_dynamic_min":
   49.18                  get_child_node_attribute(vm, "memory", "dynamic_min"),
   49.19 -            "vcpus_params":
   49.20 +            "VCPUs_params":
   49.21                  get_child_nodes_as_dict(vm, "vcpu_param", "key", "value"),
   49.22 -            "vcpus_max":
   49.23 +            "VCPUs_max":
   49.24                  vm.attributes["vcpus_max"].value,
   49.25 -            "vcpus_at_startup":
   49.26 +            "VCPUs_at_startup":
   49.27                  vm.attributes["vcpus_at_startup"].value,
   49.28              "actions_after_shutdown":
   49.29                  vm.attributes["actions_after_shutdown"].value,
   49.30 @@ -591,7 +591,6 @@ class sxp2xml:
   49.31      def extract_vdi(self, vbd_sxp, document):
   49.32          src = get_child_by_name(vbd_sxp, "uname")
   49.33          name = "vdi" + str(src.__hash__())
   49.34 -        path = src[src.find(":")+1:]
   49.35  
   49.36          vdi = document.createElement("vdi")
   49.37  
   49.38 @@ -599,8 +598,7 @@ class sxp2xml:
   49.39          vdi.attributes["read_only"] \
   49.40              = (get_child_by_name(vbd_sxp, "mode") != "w") \
   49.41                 and "true" or "false"
   49.42 -        vdi.attributes["size"] \
   49.43 -            = str(os.path.getsize(path))
   49.44 +        vdi.attributes["size"] = '-1'
   49.45          vdi.attributes["type"] = "system"
   49.46          vdi.attributes["shareable"] = "false"
   49.47          vdi.attributes["name"] = name
   49.48 @@ -613,7 +611,10 @@ class sxp2xml:
   49.49  
   49.50          vif = document.createElement("vif")
   49.51  
   49.52 -        dev = get_child_by_name(vif_sxp, "vifname", "eth0")
   49.53 +        dev = get_child_by_name(vif_sxp, "vifname", None)
   49.54 +
   49.55 +        if dev is None:
   49.56 +            dev = self.getFreshEthDevice()
   49.57  
   49.58          vif.attributes["name"] \
   49.59              = "vif" + str(dev.__hash__())
   49.60 @@ -630,7 +631,8 @@ class sxp2xml:
   49.61          
   49.62          return vif
   49.63  
   49.64 -
   49.65 +    _eths = -1
   49.66  
   49.67 -
   49.68 -
   49.69 +    def getFreshEthDevice(self):
   49.70 +        self._eths += 1
   49.71 +        return "eth%i" % self._eths
    50.1 --- a/tools/xenmon/xenmon.py	Mon Mar 26 09:17:25 2007 -0600
    50.2 +++ b/tools/xenmon/xenmon.py	Mon Mar 26 10:10:31 2007 -0600
    50.3 @@ -166,7 +166,7 @@ class DomainInfo:
    50.4  
    50.5      def ec_stats(self, passed):
    50.6          total = float(self.exec_count/(float(passed)/10**9))
    50.7 -	return total
    50.8 +        return total
    50.9  
   50.10      def io_stats(self, passed):
   50.11          total = float(self.iocount_sum)
   50.12 @@ -235,7 +235,7 @@ def time_scale(ns):
   50.13      elif ns < 1000*1000:
   50.14          return "%4.2f us" % (float(ns)/10**3)
   50.15      elif ns < 10**9:
   50.16 -	    return "%4.2f ms" % (float(ns)/10**6)
   50.17 +        return "%4.2f ms" % (float(ns)/10**6)
   50.18      else:
   50.19          return "%4.2f s" % (float(ns)/10**9)
   50.20  
   50.21 @@ -534,20 +534,20 @@ def show_livestats(cpu):
   50.22  # write does the file get created
   50.23  class Delayed(file):
   50.24      def __init__(self, filename, mode):
   50.25 -	self.filename = filename
   50.26 -	self.saved_mode = mode
   50.27 -	self.delay_data = ""
   50.28 -	self.opened = 0
   50.29 +        self.filename = filename
   50.30 +        self.saved_mode = mode
   50.31 +        self.delay_data = ""
   50.32 +        self.opened = 0
   50.33  
   50.34      def delayed_write(self, str):
   50.35 -	self.delay_data = str
   50.36 +        self.delay_data = str
   50.37  
   50.38      def write(self, str):
   50.39 -	if not self.opened:
   50.40 -	    self.file = open(self.filename, self.saved_mode)
   50.41 -	    self.opened = 1
   50.42 +        if not self.opened:
   50.43 +            self.file = open(self.filename, self.saved_mode)
   50.44 +            self.opened = 1
   50.45              self.file.write(self.delay_data)
   50.46 -	self.file.write(str)
   50.47 +        self.file.write(str)
   50.48  
   50.49      def rename(self, name):
   50.50          self.filename = name
    51.1 --- a/tools/xm-test/lib/XmTestLib/NetConfig.py	Mon Mar 26 09:17:25 2007 -0600
    51.2 +++ b/tools/xm-test/lib/XmTestLib/NetConfig.py	Mon Mar 26 10:10:31 2007 -0600
    51.3 @@ -87,7 +87,7 @@ class NetConfig:
    51.4          else:
    51.5              self.netmask = NETMASK
    51.6              self.network = NETWORK
    51.7 -	    s_ip = ''
    51.8 +            s_ip = ''
    51.9  
   51.10              # Get starting ip and max ip from configured ip range
   51.11              s_ip = NETWORK_IP_RANGE
    52.1 --- a/tools/xm-test/lib/XmTestLib/XenDevice.py	Mon Mar 26 09:17:25 2007 -0600
    52.2 +++ b/tools/xm-test/lib/XmTestLib/XenDevice.py	Mon Mar 26 10:10:31 2007 -0600
    52.3 @@ -98,8 +98,8 @@ class XenDevice:
    52.4          self.domain = domain
    52.5          self.configNode = None
    52.6          # Commands run when domain is started or devices added and removed.
    52.7 -	self.dom0_cmds = []
    52.8 -	self.domU_cmds = []
    52.9 +        self.dom0_cmds = []
   52.10 +        self.domU_cmds = []
   52.11  
   52.12      def __str__(self):
   52.13          """Convert device config to XenConfig node compatible string"""
   52.14 @@ -178,7 +178,7 @@ class XenNetDevice(XenDevice):
   52.15          self.dom0_alias_ip = None
   52.16  
   52.17          if domain.getDomainType() == "HVM":
   52.18 -	    self.config["type"] = "ioemu"
   52.19 +            self.config["type"] = "ioemu"
   52.20              if not self.config.has_key('bridge'):
   52.21                  self.config["bridge"] = "xenbr0"
   52.22  
   52.23 @@ -252,7 +252,7 @@ class XenNetDevice(XenDevice):
   52.24          if (self.ip and not ip) or ((self.ip and ip) and (self.ip != ip)): 
   52.25              self.releaseNetDevIP()
   52.26  
   52.27 -	if not self.netmask:
   52.28 +        if not self.netmask:
   52.29              self.netmask = xmtest_netconf.getNetMask()
   52.30  
   52.31          if not self.network:
    53.1 --- a/tools/xm-test/lib/XmTestLib/arch.py	Mon Mar 26 09:17:25 2007 -0600
    53.2 +++ b/tools/xm-test/lib/XmTestLib/arch.py	Mon Mar 26 10:10:31 2007 -0600
    53.3 @@ -94,7 +94,7 @@ def ppc_checkBuffer(buffer):
    53.4      for i in range(0, len(checks)):
    53.5          check=checks[i]
    53.6          if check.get('pattern').search(buffer):
    53.7 -		FAIL(check.get('message'))
    53.8 +            FAIL(check.get('message'))
    53.9  
   53.10      return
   53.11  
    54.1 --- a/tools/xm-test/lib/XmTestReport/OSReport.py	Mon Mar 26 09:17:25 2007 -0600
    54.2 +++ b/tools/xm-test/lib/XmTestReport/OSReport.py	Mon Mar 26 10:10:31 2007 -0600
    54.3 @@ -149,16 +149,16 @@ class OperatingSystem:
    54.4              return None, None
    54.5  
    54.6      def __debianStyleRelease(self):
    54.7 -	if os.access("/etc/debian_version", os.R_OK):
    54.8 -	    rFile = file("/etc/debian_version")
    54.9 -	else:
   54.10 -	    rFile = None
   54.11 +        if os.access("/etc/debian_version", os.R_OK):
   54.12 +            rFile = file("/etc/debian_version")
   54.13 +        else:
   54.14 +            rFile = None
   54.15  
   54.16 -	if not rFile:
   54.17 -	    return None, None
   54.18 +        if not rFile:
   54.19 +            return None, None
   54.20  
   54.21 -	line = rFile.readline()
   54.22 -	return "Debian", line.rstrip("\n");
   54.23 +        line = rFile.readline()
   54.24 +        return "Debian", line.rstrip("\n");
   54.25  
   54.26      def __lsbStyleRelease(self):
   54.27          if os.access("/etc/lsb-release", os.R_OK):
    55.1 --- a/tools/xm-test/lib/XmTestReport/Report.py	Mon Mar 26 09:17:25 2007 -0600
    55.2 +++ b/tools/xm-test/lib/XmTestReport/Report.py	Mon Mar 26 10:10:31 2007 -0600
    55.3 @@ -86,7 +86,7 @@ def encodeForm(fieldList):
    55.4  
    55.5  def postResults(report_server, results):
    55.6      if not re.match('http://', report_server):
    55.7 -	report_server = 'http://'+report_server
    55.8 +        report_server = 'http://'+report_server
    55.9      (report_host,report_url) = urlparse(report_server)[1:3]
   55.10      conn = httplib.HTTPConnection(report_host)
   55.11  
    56.1 --- a/tools/xm-test/tests/create/04_create_conflictname_neg.py	Mon Mar 26 09:17:25 2007 -0600
    56.2 +++ b/tools/xm-test/tests/create/04_create_conflictname_neg.py	Mon Mar 26 10:10:31 2007 -0600
    56.3 @@ -34,8 +34,8 @@ try:
    56.4  except DomainError, e:
    56.5      eyecatcher = "Fail"
    56.6      # Stop the domain1 (nice shutdown)
    56.7 -    domain1.stop()	
    56.8 +    domain1.stop()
    56.9  
   56.10  if eyecatcher != "Fail":
   56.11 -	domain2.stop()
   56.12 -	FAIL("xm create let me create a duplicate-named domain!") 
   56.13 +    domain2.stop()
   56.14 +    FAIL("xm create let me create a duplicate-named domain!") 
    57.1 --- a/tools/xm-test/tests/create/06_create_mem_neg.py	Mon Mar 26 09:17:25 2007 -0600
    57.2 +++ b/tools/xm-test/tests/create/06_create_mem_neg.py	Mon Mar 26 10:10:31 2007 -0600
    57.3 @@ -16,7 +16,7 @@ from XmTestLib import *
    57.4  
    57.5  rdpath = os.environ.get("RD_PATH")
    57.6  if not rdpath:
    57.7 -	rdpath = "../ramdisk"
    57.8 +    rdpath = "../ramdisk"
    57.9  
   57.10  # Test 1: create a domain with mem=0
   57.11  config1 = {"memory": 0}
   57.12 @@ -29,8 +29,8 @@ except DomainError, e:
   57.13      eyecatcher1 = "Fail"
   57.14  
   57.15  if eyecatcher1 != "Fail":
   57.16 -	domain1.stop()
   57.17 -        FAIL("xm create let me create a domain with 0 memory")
   57.18 +    domain1.stop()
   57.19 +    FAIL("xm create let me create a domain with 0 memory")
   57.20  
   57.21  
   57.22  # Test 2: create a domain with mem>sys_mem
   57.23 @@ -48,6 +48,6 @@ except DomainError, e:
   57.24      eyecatcher2 = "Fail"
   57.25  
   57.26  if eyecatcher2 != "Fail":
   57.27 -        domain2.stop()
   57.28 -        FAIL("xm create let me create a domain with mem > sys_mem")
   57.29 +    domain2.stop()
   57.30 +    FAIL("xm create let me create a domain with mem > sys_mem")
   57.31  
    58.1 --- a/tools/xm-test/tests/create/07_create_mem64_pos.py	Mon Mar 26 09:17:25 2007 -0600
    58.2 +++ b/tools/xm-test/tests/create/07_create_mem64_pos.py	Mon Mar 26 10:10:31 2007 -0600
    58.3 @@ -15,12 +15,12 @@ from XmTestLib import *
    58.4  
    58.5  rdpath = os.environ.get("RD_PATH")
    58.6  if not rdpath:
    58.7 -        rdpath = "../ramdisk"
    58.8 +    rdpath = "../ramdisk"
    58.9  
   58.10  #get current free memory info
   58.11  mem = int(getInfo("free_memory"))
   58.12  if mem < 64:
   58.13 -	SKIP("This test needs 64 MB of free memory (%i MB avail)" % mem)
   58.14 +    SKIP("This test needs 64 MB of free memory (%i MB avail)" % mem)
   58.15  
   58.16  #create a domain with mem=64
   58.17  config = {"memory": 64}
   58.18 @@ -39,11 +39,11 @@ except DomainError, e:
   58.19  
   58.20  eyecatcher1 = str(isDomainRunning(domain_mem64.getName()))
   58.21  if eyecatcher1 != "True":
   58.22 -	FAIL("Failed to verify that a 64MB domain started")
   58.23 +    FAIL("Failed to verify that a 64MB domain started")
   58.24  
   58.25  eyecatcher2 = getDomMem(domain_mem64.getName())
   58.26  if eyecatcher2 not in range(62, 65):
   58.27 -	FAIL("Started domain with 64MB, but it got %i MB" % eyecatcher2)
   58.28 +    FAIL("Started domain with 64MB, but it got %i MB" % eyecatcher2)
   58.29  
   58.30  #stop the domain (nice shutdown)
   58.31  domain_mem64.stop()
    59.1 --- a/tools/xm-test/tests/create/08_create_mem128_pos.py	Mon Mar 26 09:17:25 2007 -0600
    59.2 +++ b/tools/xm-test/tests/create/08_create_mem128_pos.py	Mon Mar 26 10:10:31 2007 -0600
    59.3 @@ -15,12 +15,12 @@ from XmTestLib import *
    59.4  
    59.5  rdpath = os.environ.get("RD_PATH")
    59.6  if not rdpath:
    59.7 -        rdpath = "../ramdisk"
    59.8 +    rdpath = "../ramdisk"
    59.9  
   59.10  #get current free memory info
   59.11  mem = int(getInfo("free_memory"))
   59.12  if mem < 128:
   59.13 -        SKIP("This test needs 128 MB of free memory (%i MB avail)" % mem)
   59.14 +    SKIP("This test needs 128 MB of free memory (%i MB avail)" % mem)
   59.15  
   59.16  #create a domain with mem=128
   59.17  config={"memory": 128}
   59.18 @@ -39,11 +39,11 @@ except DomainError, e:
   59.19  
   59.20  eyecatcher1 = str(isDomainRunning(domain_mem128.getName()))
   59.21  if eyecatcher1 != "True":
   59.22 -	FAIL("Failed to verify that a 128MB domain started")
   59.23 +    FAIL("Failed to verify that a 128MB domain started")
   59.24  
   59.25  eyecatcher2 = getDomMem(domain_mem128.getName())
   59.26  if eyecatcher2 not in range(126, 129):
   59.27 -	FAIL("Started domain with 128MB, but it got %i MB" % eyecatcher2)
   59.28 +    FAIL("Started domain with 128MB, but it got %i MB" % eyecatcher2)
   59.29  
   59.30  #stop the domain (nice shutdown)
   59.31  domain_mem128.stop()
    60.1 --- a/tools/xm-test/tests/create/09_create_mem256_pos.py	Mon Mar 26 09:17:25 2007 -0600
    60.2 +++ b/tools/xm-test/tests/create/09_create_mem256_pos.py	Mon Mar 26 10:10:31 2007 -0600
    60.3 @@ -15,12 +15,12 @@ from XmTestLib import *
    60.4  
    60.5  rdpath = os.environ.get("RD_PATH")
    60.6  if not rdpath:
    60.7 -        rdpath = "../ramdisk"
    60.8 +    rdpath = "../ramdisk"
    60.9  
   60.10  #get current free memory info
   60.11  mem = int(getInfo("free_memory"))
   60.12  if mem < 256:
   60.13 -        SKIP("This test needs 256 MB of free memory (%i MB avail)" % mem)
   60.14 +    SKIP("This test needs 256 MB of free memory (%i MB avail)" % mem)
   60.15  
   60.16  #create a domain with mem=256
   60.17  config = {"memory": 256}
   60.18 @@ -39,11 +39,11 @@ except DomainError, e:
   60.19  
   60.20  eyecatcher1 = str(isDomainRunning(domain_mem256.getName()))
   60.21  if eyecatcher1 != "True":
   60.22 -	FAIL("Failed to verify that a 256MB domain started")
   60.23 +    FAIL("Failed to verify that a 256MB domain started")
   60.24  
   60.25  eyecatcher2 = getDomMem(domain_mem256.getName())
   60.26  if eyecatcher2 not in range(254, 257):
   60.27 -	FAIL("Started domain with 256MB, but it got %i MB" % eyecatcher2)
   60.28 +    FAIL("Started domain with 256MB, but it got %i MB" % eyecatcher2)
   60.29  
   60.30  #stop the domain (nice shutdown)
   60.31  domain_mem256.stop()
    61.1 --- a/tools/xm-test/tests/list/02_list_badparm_neg.py	Mon Mar 26 09:17:25 2007 -0600
    61.2 +++ b/tools/xm-test/tests/list/02_list_badparm_neg.py	Mon Mar 26 10:10:31 2007 -0600
    61.3 @@ -11,6 +11,6 @@ status, output = traceCommand("xm list -
    61.4  eyecatcher = "Error:"
    61.5  where = output.find(eyecatcher)
    61.6  if status == 0:
    61.7 -    FAIL("xm list returned invalud %i != 0" % status)
    61.8 +    FAIL("xm list returned invalid %i != 0" % status)
    61.9  elif where == -1:
   61.10      FAIL("xm list failed to report error for bad arg")
    62.1 --- a/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py	Mon Mar 26 09:17:25 2007 -0600
    62.2 +++ b/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py	Mon Mar 26 10:10:31 2007 -0600
    62.3 @@ -51,12 +51,12 @@ except TimeoutError, e:
    62.4      FAIL(str(e))
    62.5      
    62.6  if status != 0:
    62.7 -	FAIL("xm migrate returned invalid %i != 0" % status)
    62.8 +    FAIL("xm migrate returned invalid %i != 0" % status)
    62.9  
   62.10  new_domid = domid(domain.getName())
   62.11  
   62.12  if (old_domid == new_domid):
   62.13 -	FAIL("xm migrate failed, domain id is still %s" % old_domid)
   62.14 +    FAIL("xm migrate failed, domain id is still %s" % old_domid)
   62.15  
   62.16  # Attach a console to it
   62.17  try:
    63.1 --- a/tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py	Mon Mar 26 09:17:25 2007 -0600
    63.2 +++ b/tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py	Mon Mar 26 10:10:31 2007 -0600
    63.3 @@ -10,6 +10,6 @@ status, output = traceCommand("xm networ
    63.4  eyecatcher = "Error"
    63.5  where = output.find(eyecatcher)
    63.6  if status == 0:
    63.7 -	FAIL("xm network-attach returned bad status, expected non 0, status is: %i" % status )
    63.8 +    FAIL("xm network-attach returned bad status, expected non 0, status is: %i" % status )
    63.9  elif where == -1:
   63.10 -	FAIL("xm network-attach returned bad output, expected Error, output is: %s" % output )
   63.11 +    FAIL("xm network-attach returned bad output, expected Error, output is: %s" % output )
    64.1 --- a/tools/xm-test/tests/network-attach/network_utils.py	Mon Mar 26 09:17:25 2007 -0600
    64.2 +++ b/tools/xm-test/tests/network-attach/network_utils.py	Mon Mar 26 10:10:31 2007 -0600
    64.3 @@ -51,6 +51,6 @@ def network_detach(domain_name, console,
    64.4  
    64.5      eths_after = count_eth(console)
    64.6      if eths_after != (eths_before-1):
    64.7 -    	return -2, "Network device was not actually disconnected from domU"
    64.8 +        return -2, "Network device was not actually disconnected from domU"
    64.9  
   64.10      return 0, None
    65.1 --- a/tools/xm-test/tests/pause/01_pause_basic_pos.py	Mon Mar 26 09:17:25 2007 -0600
    65.2 +++ b/tools/xm-test/tests/pause/01_pause_basic_pos.py	Mon Mar 26 10:10:31 2007 -0600
    65.3 @@ -39,7 +39,7 @@ domain.closeConsole()
    65.4  # Pause the domain
    65.5  status, output = traceCommand("xm pause %s" % domain.getName())
    65.6  if status != 0:
    65.7 -	FAIL("xm pause returned invalid %i != 0", status)
    65.8 +    FAIL("xm pause returned invalid %i != 0", status)
    65.9  
   65.10  # Try to attach a console to it
   65.11  try:
   65.12 @@ -56,7 +56,7 @@ domain.closeConsole()
   65.13  
   65.14  status, output = traceCommand("xm unpause %s" % domain.getName())
   65.15  if status != 0:
   65.16 -	FAIL("xm unpause returned invalid %i != 0", status)
   65.17 +    FAIL("xm unpause returned invalid %i != 0", status)
   65.18  
   65.19  # Stop the domain (nice shutdown)
   65.20  domain.stop()
    66.1 --- a/tools/xm-test/tests/security-acm/06_security-acm_dom_block_attach.py	Mon Mar 26 09:17:25 2007 -0600
    66.2 +++ b/tools/xm-test/tests/security-acm/06_security-acm_dom_block_attach.py	Mon Mar 26 10:10:31 2007 -0600
    66.3 @@ -46,9 +46,9 @@ ACMLabelResource(resource1, resourcelabe
    66.4  block_utils.block_attach(domain, resource1, "xvda1")
    66.5  
    66.6  try:
    66.7 -	run1 = console.runCmd("cat /proc/partitions")
    66.8 +    run1 = console.runCmd("cat /proc/partitions")
    66.9  except ConsoleError, e:
   66.10 -	FAIL(str(e))
   66.11 +    FAIL(str(e))
   66.12  
   66.13  #Explicitly label the 2nd resource
   66.14  ACMLabelResource(resource2, resourcelabel2)
   66.15 @@ -62,9 +62,9 @@ for i in range(10):
   66.16      time.sleep(1)
   66.17  
   66.18  try:
   66.19 -	run2 = console.runCmd("cat /proc/partitions")
   66.20 +    run2 = console.runCmd("cat /proc/partitions")
   66.21  except ConsoleError, e:
   66.22 -	FAIL(str(e))
   66.23 +    FAIL(str(e))
   66.24  
   66.25  # Close the console
   66.26  domain.closeConsole()
    67.1 --- a/tools/xm-test/tests/unpause/01_unpause_basic_pos.py	Mon Mar 26 09:17:25 2007 -0600
    67.2 +++ b/tools/xm-test/tests/unpause/01_unpause_basic_pos.py	Mon Mar 26 10:10:31 2007 -0600
    67.3 @@ -46,18 +46,17 @@ for i in range(100):
    67.4          # Pause the domain
    67.5          status, output = traceCommand("xm pause %s" % domain.getName())
    67.6          if status != 0:
    67.7 -	        FAIL("xm pause returned invalid %i != 0", status)
    67.8 +            FAIL("xm pause returned invalid %i != 0", status)
    67.9      else:
   67.10          # Unpause the domain
   67.11          status, output = traceCommand("xm unpause %s" % domain.getName())
   67.12          if status != 0:
   67.13 -	        FAIL("xm unpause returned invalud %i != 0", status)
   67.14 -	
   67.15 +            FAIL("xm unpause returned invalid %i != 0", status)
   67.16  
   67.17  # Make sure the domain is unpaused before we finish up
   67.18  status, output = traceCommand("xm unpause %s" % domain.getName())
   67.19  if status != 0:
   67.20 -	FAIL("xm unpause returned invalid %i != 0", status)
   67.21 +    FAIL("xm unpause returned invalid %i != 0", status)
   67.22  
   67.23  # Are we still alive after all that?
   67.24  try:
    68.1 --- a/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py	Mon Mar 26 09:17:25 2007 -0600
    68.2 +++ b/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py	Mon Mar 26 10:10:31 2007 -0600
    68.3 @@ -49,4 +49,4 @@ domain.stop()
    68.4  vtpm_cleanup(domName)
    68.5  
    68.6  if not re.search("PCR-00:",run["output"]):
    68.7 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    68.8 +    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    69.1 --- a/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py	Mon Mar 26 09:17:25 2007 -0600
    69.2 +++ b/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py	Mon Mar 26 10:10:31 2007 -0600
    69.3 @@ -97,7 +97,7 @@ while loop < 3:
    69.4      if not re.search("PCR-00:",run["output"]):
    69.5          saveLog(console.getHistory())
    69.6          vtpm_cleanup(domName)
    69.7 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    69.8 +        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    69.9  
   69.10      loop += 1
   69.11  
    70.1 --- a/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py	Mon Mar 26 09:17:25 2007 -0600
    70.2 +++ b/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py	Mon Mar 26 10:10:31 2007 -0600
    70.3 @@ -91,7 +91,7 @@ while loop < 3:
    70.4      if not re.search("PCR-00:",run["output"]):
    70.5          saveLog(console.getHistory())
    70.6          vtpm_cleanup(domName)
    70.7 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    70.8 +        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    70.9  
   70.10      loop += 1
   70.11  
    71.1 --- a/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py	Mon Mar 26 09:17:25 2007 -0600
    71.2 +++ b/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py	Mon Mar 26 10:10:31 2007 -0600
    71.3 @@ -91,7 +91,7 @@ while loop < 3:
    71.4      if not re.search("PCR-00:",run["output"]):
    71.5          saveLog(console.getHistory())
    71.6          vtpm_cleanup(domName)
    71.7 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    71.8 +        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    71.9  
   71.10      loop += 1
   71.11  
    72.1 --- a/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py	Mon Mar 26 09:17:25 2007 -0600
    72.2 +++ b/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py	Mon Mar 26 10:10:31 2007 -0600
    72.3 @@ -122,12 +122,12 @@ while loop < 3:
    72.4      if not re.search("PCR-00:",run["output"]):
    72.5          saveLog(console.getHistory())
    72.6          vtpm_cleanup(domName)
    72.7 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    72.8 +        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    72.9  
   72.10      if not re.search("PCR-00: 1E A7 BD",run["output"]):
   72.11          saveLog(console.getHistory())
   72.12          vtpm_cleanup(domName)
   72.13 -	FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
   72.14 +        FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
   72.15  
   72.16      loop += 1
   72.17  
    73.1 --- a/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py	Mon Mar 26 09:17:25 2007 -0600
    73.2 +++ b/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py	Mon Mar 26 10:10:31 2007 -0600
    73.3 @@ -116,12 +116,12 @@ while loop < 3:
    73.4      if not re.search("PCR-00:",run["output"]):
    73.5          saveLog(console.getHistory())
    73.6          vtpm_cleanup(domName)
    73.7 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    73.8 +        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    73.9  
   73.10      if not re.search("PCR-00: 1E A7 BD",run["output"]):
   73.11          saveLog(console.getHistory())
   73.12          vtpm_cleanup(domName)
   73.13 -	FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
   73.14 +        FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
   73.15  
   73.16      loop += 1
   73.17  
    74.1 --- a/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py	Mon Mar 26 09:17:25 2007 -0600
    74.2 +++ b/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py	Mon Mar 26 10:10:31 2007 -0600
    74.3 @@ -116,12 +116,12 @@ while loop < 3:
    74.4      if not re.search("PCR-00:",run["output"]):
    74.5          saveLog(console.getHistory())
    74.6          vtpm_cleanup(domName)
    74.7 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    74.8 +        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    74.9  
   74.10      if not re.search("PCR-00: 1E A7 BD",run["output"]):
   74.11          saveLog(console.getHistory())
   74.12          vtpm_cleanup(domName)
   74.13 -	FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
   74.14 +        FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
   74.15  
   74.16      loop += 1
   74.17  
    75.1 --- a/xen/arch/x86/hvm/hvm.c	Mon Mar 26 09:17:25 2007 -0600
    75.2 +++ b/xen/arch/x86/hvm/hvm.c	Mon Mar 26 10:10:31 2007 -0600
    75.3 @@ -218,6 +218,7 @@ void hvm_domain_destroy(struct domain *d
    75.4  {
    75.5      pit_deinit(d);
    75.6      rtc_deinit(d);
    75.7 +    pmtimer_deinit(d);
    75.8      hpet_deinit(d);
    75.9  
   75.10      if ( d->arch.hvm_domain.shared_page_va )
   75.11 @@ -303,7 +304,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
   75.12  
   75.13      pit_init(v, cpu_khz);
   75.14      rtc_init(v, RTC_PORT(0));
   75.15 -    pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS);
   75.16 +    pmtimer_init(v);
   75.17      hpet_init(v);
   75.18   
   75.19      /* Init guest TSC to start from zero. */
    76.1 --- a/xen/arch/x86/hvm/pmtimer.c	Mon Mar 26 09:17:25 2007 -0600
    76.2 +++ b/xen/arch/x86/hvm/pmtimer.c	Mon Mar 26 10:10:31 2007 -0600
    76.3 @@ -1,12 +1,172 @@
    76.4 +/*
    76.5 + * hvm/pmtimer.c: emulation of the ACPI PM timer 
    76.6 + *
    76.7 + * Copyright (c) 2007, XenSource inc.
    76.8 + * Copyright (c) 2006, Intel Corporation.
    76.9 + *
   76.10 + * This program is free software; you can redistribute it and/or modify it
   76.11 + * under the terms and conditions of the GNU General Public License,
   76.12 + * version 2, as published by the Free Software Foundation.
   76.13 + *
   76.14 + * This program is distributed in the hope it will be useful, but WITHOUT
   76.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   76.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   76.17 + * more details.
   76.18 + *
   76.19 + * You should have received a copy of the GNU General Public License along with
   76.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   76.21 + * Place - Suite 330, Boston, MA 02111-1307 USA.
   76.22 + */
   76.23 +
   76.24  #include <asm/hvm/vpt.h>
   76.25  #include <asm/hvm/io.h>
   76.26  #include <asm/hvm/support.h>
   76.27  
   76.28 +/* Slightly more readable port I/O addresses for the registers we intercept */
   76.29 +#define PM1a_STS_ADDR (ACPI_PM1A_EVT_BLK_ADDRESS)
   76.30 +#define PM1a_EN_ADDR  (ACPI_PM1A_EVT_BLK_ADDRESS + 2)
   76.31 +#define TMR_VAL_ADDR  (ACPI_PM_TMR_BLK_ADDRESS)
   76.32 +
   76.33 +/* The interesting bit of the PM1a_STS register */
   76.34 +#define TMR_STS    (1 << 0)
   76.35 +#define PWRBTN_STS (1 << 5)
   76.36 +#define GBL_STS    (1 << 8)
   76.37 +
   76.38 +/* The same in PM1a_EN */
   76.39 +#define TMR_EN     (1 << 0)
   76.40 +#define PWRBTN_EN  (1 << 5)
   76.41 +#define GBL_EN     (1 << 8)
   76.42 +
   76.43 +/* Mask of bits in PM1a_STS that can generate an SCI.  Although the ACPI
   76.44 + * spec lists other bits, the PIIX4, which we are emulating, only
   76.45 + * supports these three.  For now, we only use TMR_STS; in future we
   76.46 + * will let qemu set the other bits */
   76.47 +#define SCI_MASK (TMR_STS|PWRBTN_STS|GBL_STS) 
   76.48 +
   76.49 +/* SCI IRQ number (must match SCI_INT number in ACPI FADT in hvmloader) */
   76.50 +#define SCI_IRQ 9
   76.51 +
   76.52 +/* We provide a 32-bit counter (must match the TMR_VAL_EXT bit in the FADT) */
   76.53 +#define TMR_VAL_MASK  (0xffffffff)
   76.54 +#define TMR_VAL_MSB   (0x80000000)
   76.55 +
   76.56 +
   76.57 +/* Dispatch SCIs based on the PM1a_STS and PM1a_EN registers */
   76.58 +static void pmt_update_sci(PMTState *s)
   76.59 +{
   76.60 +    if ( s->pm.pm1a_en & s->pm.pm1a_sts & SCI_MASK )
   76.61 +        hvm_isa_irq_assert(s->vcpu->domain, SCI_IRQ);
   76.62 +    else
   76.63 +        hvm_isa_irq_deassert(s->vcpu->domain, SCI_IRQ);
   76.64 +}
   76.65 +
   76.66 +/* Set the correct value in the timer, accounting for time elapsed
   76.67 + * since the last time we did that. */
   76.68 +static void pmt_update_time(PMTState *s)
   76.69 +{
   76.70 +    uint64_t curr_gtime;
   76.71 +    uint32_t msb = s->pm.tmr_val & TMR_VAL_MSB;
   76.72 +    
   76.73 +    /* Update the timer */
   76.74 +    curr_gtime = hvm_get_guest_time(s->vcpu);
   76.75 +    s->pm.tmr_val += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
   76.76 +    s->pm.tmr_val &= TMR_VAL_MASK;
   76.77 +    s->last_gtime = curr_gtime;
   76.78 +    
   76.79 +    /* If the counter's MSB has changed, set the status bit */
   76.80 +    if ( (s->pm.tmr_val & TMR_VAL_MSB) != msb )
   76.81 +    {
   76.82 +        s->pm.pm1a_sts |= TMR_STS;
   76.83 +        pmt_update_sci(s);
   76.84 +    }
   76.85 +}
   76.86 +
   76.87 +/* This function should be called soon after each time the MSB of the
   76.88 + * pmtimer register rolls over, to make sure we update the status
   76.89 + * registers and SCI at least once per rollover */
   76.90 +static void pmt_timer_callback(void *opaque)
   76.91 +{
   76.92 +    PMTState *s = opaque;
   76.93 +    uint32_t pmt_cycles_until_flip;
   76.94 +    uint64_t time_until_flip;
   76.95 +    
   76.96 +    /* Recalculate the timer and make sure we get an SCI if we need one */
   76.97 +    pmt_update_time(s);
   76.98 +    
   76.99 +    /* How close are we to the next MSB flip? */
  76.100 +    pmt_cycles_until_flip = TMR_VAL_MSB - (s->pm.tmr_val & (TMR_VAL_MSB - 1));
  76.101 +    
  76.102 +    /* Overall time between MSB flips */
  76.103 +    time_until_flip = (1000000000ULL << 31) / FREQUENCE_PMTIMER;
  76.104 +    
  76.105 +    /* Reduced appropriately */
  76.106 +    time_until_flip = (time_until_flip * pmt_cycles_until_flip) / (1ULL<<31);
  76.107 +    
  76.108 +    /* Wake up again near the next bit-flip */
  76.109 +    set_timer(&s->timer, NOW() + time_until_flip + MILLISECS(1));
  76.110 +}
  76.111 +
  76.112 +
  76.113 +/* Handle port I/O to the PM1a_STS and PM1a_EN registers */
  76.114 +static int handle_evt_io(ioreq_t *p)
  76.115 +{
  76.116 +    struct vcpu *v = current;
  76.117 +    PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
  76.118 +    uint32_t addr, data, byte;
  76.119 +    int i;
  76.120 +
  76.121 +    if ( p->dir == 0 ) /* Write */
  76.122 +    {
  76.123 +        /* Handle this I/O one byte at a time */
  76.124 +        for ( i = p->size, addr = p->addr, data = p->data;
  76.125 +              i > 0;
  76.126 +              i--, addr++, data >>= 8 )
  76.127 +        {
  76.128 +            byte = data & 0xff;
  76.129 +            switch(addr) 
  76.130 +            {
  76.131 +                /* PM1a_STS register bits are write-to-clear */
  76.132 +            case PM1a_STS_ADDR:
  76.133 +                s->pm.pm1a_sts &= ~byte;
  76.134 +                break;
  76.135 +            case PM1a_STS_ADDR + 1:
  76.136 +                s->pm.pm1a_sts &= ~(byte << 8);
  76.137 +                break;
  76.138 +                
  76.139 +            case PM1a_EN_ADDR:
  76.140 +                s->pm.pm1a_en = (s->pm.pm1a_en & 0xff00) | byte;
  76.141 +                break;
  76.142 +            case PM1a_EN_ADDR + 1:
  76.143 +                s->pm.pm1a_en = (s->pm.pm1a_en & 0xff) | (byte << 8);
  76.144 +                break;
  76.145 +                
  76.146 +            default:
  76.147 +                gdprintk(XENLOG_WARNING, 
  76.148 +                         "Bad ACPI PM register write: %"PRIu64
  76.149 +                         " bytes (%#"PRIx64") at %"PRIx64"\n", 
  76.150 +                         p->size, p->data, p->addr);
  76.151 +            }
  76.152 +        }
  76.153 +        /* Fix up the SCI state to match the new register state */
  76.154 +        pmt_update_sci(s);
  76.155 +    }
  76.156 +    else /* Read */
  76.157 +    {
  76.158 +        data = s->pm.pm1a_sts | (((uint32_t) s->pm.pm1a_en) << 16);
  76.159 +        data >>= 8 * (p->addr - PM1a_STS_ADDR);
  76.160 +        if ( p->size == 1 ) data &= 0xff;
  76.161 +        else if ( p->size == 2 ) data &= 0xffff;
  76.162 +        p->data = data;
  76.163 +    }
  76.164 +    return 1;
  76.165 +}
  76.166 +
  76.167 +
  76.168 +/* Handle port I/O to the TMR_VAL register */
  76.169  static int handle_pmt_io(ioreq_t *p)
  76.170  {
  76.171      struct vcpu *v = current;
  76.172      PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
  76.173 -    uint64_t curr_gtime;
  76.174  
  76.175      if (p->size != 4 ||
  76.176          p->data_is_ptr ||
  76.177 @@ -19,12 +179,8 @@ static int handle_pmt_io(ioreq_t *p)
  76.178          /* PM_TMR_BLK is read-only */
  76.179          return 1;
  76.180      } else if (p->dir == 1) { /* read */
  76.181 -        /* Set the correct value in the timer, accounting for time
  76.182 -         * elapsed since the last time we did that. */
  76.183 -        curr_gtime = hvm_get_guest_time(s->vcpu);
  76.184 -        s->pm.timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
  76.185 -        p->data = s->pm.timer;
  76.186 -        s->last_gtime = curr_gtime;
  76.187 +        pmt_update_time(s);
  76.188 +        p->data = s->pm.tmr_val;
  76.189          return 1;
  76.190      }
  76.191      return 0;
  76.192 @@ -33,6 +189,7 @@ static int handle_pmt_io(ioreq_t *p)
  76.193  static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
  76.194  {
  76.195      PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
  76.196 +    uint32_t msb = s->pm.tmr_val & TMR_VAL_MSB;
  76.197      uint32_t x;
  76.198  
  76.199      /* Update the counter to the guest's current time.  We always save
  76.200 @@ -40,7 +197,12 @@ static int pmtimer_save(struct domain *d
  76.201       * last_gtime, but just in case, make sure we only go forwards */
  76.202      x = ((s->vcpu->arch.hvm_vcpu.guest_time - s->last_gtime) * s->scale) >> 32;
  76.203      if ( x < 1UL<<31 )
  76.204 -        s->pm.timer += x;
  76.205 +        s->pm.tmr_val += x;
  76.206 +    if ( (s->pm.tmr_val & TMR_VAL_MSB) != msb )
  76.207 +        s->pm.pm1a_sts |= TMR_STS;
  76.208 +    /* No point in setting the SCI here because we'll already have saved the 
  76.209 +     * IRQ and *PIC state; we'll fix it up when we restore the domain */
  76.210 +
  76.211      return hvm_save_entry(PMTIMER, 0, h, &s->pm);
  76.212  }
  76.213  
  76.214 @@ -48,12 +210,15 @@ static int pmtimer_load(struct domain *d
  76.215  {
  76.216      PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
  76.217  
  76.218 -    /* Reload the counter */
  76.219 +    /* Reload the registers */
  76.220      if ( hvm_load_entry(PMTIMER, h, &s->pm) )
  76.221          return -EINVAL;
  76.222  
  76.223      /* Calculate future counter values from now. */
  76.224      s->last_gtime = hvm_get_guest_time(s->vcpu);
  76.225 +
  76.226 +    /* Set the SCI state from the registers */ 
  76.227 +    pmt_update_sci(s);
  76.228      
  76.229      return 0;
  76.230  }
  76.231 @@ -62,19 +227,30 @@ HVM_REGISTER_SAVE_RESTORE(PMTIMER, pmtim
  76.232                            1, HVMSR_PER_DOM);
  76.233  
  76.234  
  76.235 -void pmtimer_init(struct vcpu *v, int base)
  76.236 +void pmtimer_init(struct vcpu *v)
  76.237  {
  76.238      PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
  76.239  
  76.240 -    s->pm.timer = 0;
  76.241 +    s->pm.tmr_val = 0;
  76.242 +    s->pm.pm1a_sts = 0;
  76.243 +    s->pm.pm1a_en = 0;
  76.244 +
  76.245      s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
  76.246      s->vcpu = v;
  76.247  
  76.248 -    /* Not implemented: we should set TMR_STS (bit 0 of PM1a_STS) every
  76.249 -     * time the timer's top bit flips, and generate an SCI if TMR_EN
  76.250 -     * (bit 0 of PM1a_EN) is set.  For now, those registers are in
  76.251 -     * qemu-dm, and we just calculate the timer's value on demand. */  
  76.252 +    /* Intercept port I/O (need two handlers because PM1a_CNT is between
  76.253 +     * PM1a_EN and TMR_VAL and is handled by qemu) */
  76.254 +    register_portio_handler(v->domain, TMR_VAL_ADDR, 4, handle_pmt_io);
  76.255 +    register_portio_handler(v->domain, PM1a_STS_ADDR, 4, handle_evt_io);
  76.256  
  76.257 -    register_portio_handler(v->domain, base, 4, handle_pmt_io);
  76.258 +    /* Set up callback to fire SCIs when the MSB of TMR_VAL changes */
  76.259 +    init_timer(&s->timer, pmt_timer_callback, s, v->processor);
  76.260 +    pmt_timer_callback(s);
  76.261  }
  76.262  
  76.263 +
  76.264 +void pmtimer_deinit(struct domain *d)
  76.265 +{
  76.266 +    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
  76.267 +    kill_timer(&s->timer);
  76.268 +}
    77.1 --- a/xen/common/schedule.c	Mon Mar 26 09:17:25 2007 -0600
    77.2 +++ b/xen/common/schedule.c	Mon Mar 26 10:10:31 2007 -0600
    77.3 @@ -524,6 +524,7 @@ int sched_id(void)
    77.4  long sched_adjust(struct domain *d, struct xen_domctl_scheduler_op *op)
    77.5  {
    77.6      struct vcpu *v;
    77.7 +    long ret;
    77.8      
    77.9      if ( (op->sched_id != ops.sched_id) ||
   77.10           ((op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) &&
   77.11 @@ -552,8 +553,8 @@ long sched_adjust(struct domain *d, stru
   77.12      if ( d == current->domain )
   77.13          vcpu_schedule_lock_irq(current);
   77.14  
   77.15 -    SCHED_OP(adjust, d, op);
   77.16 -    TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
   77.17 +    if ( (ret = SCHED_OP(adjust, d, op)) == 0 )
   77.18 +        TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
   77.19  
   77.20      if ( d == current->domain )
   77.21          vcpu_schedule_unlock_irq(current);
   77.22 @@ -564,7 +565,7 @@ long sched_adjust(struct domain *d, stru
   77.23              vcpu_unpause(v);
   77.24      }
   77.25  
   77.26 -    return 0;
   77.27 +    return ret;
   77.28  }
   77.29  
   77.30  static void vcpu_periodic_timer_work(struct vcpu *v)
    78.1 --- a/xen/include/asm-x86/hvm/io.h	Mon Mar 26 09:17:25 2007 -0600
    78.2 +++ b/xen/include/asm-x86/hvm/io.h	Mon Mar 26 10:10:31 2007 -0600
    78.3 @@ -80,7 +80,7 @@ struct hvm_io_op {
    78.4      struct cpu_user_regs    io_context; /* current context */
    78.5  };
    78.6  
    78.7 -#define MAX_IO_HANDLER              8
    78.8 +#define MAX_IO_HANDLER              9
    78.9  
   78.10  #define HVM_PORTIO                  0
   78.11  #define HVM_MMIO                    1
    79.1 --- a/xen/include/asm-x86/hvm/vpt.h	Mon Mar 26 09:17:25 2007 -0600
    79.2 +++ b/xen/include/asm-x86/hvm/vpt.h	Mon Mar 26 10:10:31 2007 -0600
    79.3 @@ -101,6 +101,7 @@ typedef struct PMTState {
    79.4      struct vcpu *vcpu;          /* Keeps sync with this vcpu's guest-time */
    79.5      uint64_t last_gtime;        /* Last (guest) time we updated the timer */
    79.6      uint64_t scale;             /* Multiplier to get from tsc to timer ticks */
    79.7 +    struct timer timer;         /* To make sure we send SCIs */
    79.8  } PMTState;
    79.9  
   79.10  struct pl_time {    /* platform time */
   79.11 @@ -132,7 +133,8 @@ void rtc_init(struct vcpu *v, int base);
   79.12  void rtc_migrate_timers(struct vcpu *v);
   79.13  void rtc_deinit(struct domain *d);
   79.14  int is_rtc_periodic_irq(void *opaque);
   79.15 -void pmtimer_init(struct vcpu *v, int base);
   79.16 +void pmtimer_init(struct vcpu *v);
   79.17 +void pmtimer_deinit(struct domain *d);
   79.18  
   79.19  void hpet_migrate_timers(struct vcpu *v);
   79.20  void hpet_init(struct vcpu *v);
    80.1 --- a/xen/include/public/hvm/save.h	Mon Mar 26 09:17:25 2007 -0600
    80.2 +++ b/xen/include/public/hvm/save.h	Mon Mar 26 10:10:31 2007 -0600
    80.3 @@ -392,7 +392,9 @@ DECLARE_HVM_SAVE_TYPE(HPET, 12, struct h
    80.4   */
    80.5  
    80.6  struct hvm_hw_pmtimer {
    80.7 -    uint32_t timer;
    80.8 +    uint32_t tmr_val;   /* PM_TMR_BLK.TMR_VAL: 24bit free-running counter */
    80.9 +    uint16_t pm1a_sts;  /* PM1a_EVT_BLK.PM1a_STS: status register */
   80.10 +    uint16_t pm1a_en;   /* PM1a_EVT_BLK.PM1a_EN: enable register */
   80.11  };
   80.12  
   80.13  DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);