[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg



# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1174925431 21600
# Node ID 56caf0e37e6afcf97d4b38ee4a50133f0bb7eb03
# Parent  16198b57f53513b86dd3ce9af4fa206bbd1920ab
# Parent  3afefd64e39271dbd0d9ea26f79f41a05b89fdd8
merge with xen-unstable.hg
---
 tools/misc/xc_shadow.c                                                |   72 --
 config/StdGNU.mk                                                      |    2 
 docs/xen-api/xenapi-datamodel.tex                                     |  260 
++++++++-
 tools/ioemu/hw/piix4acpi.c                                            |  243 
--------
 tools/libxen/include/xen_common.h                                     |   67 ++
 tools/libxen/include/xen_host_metrics.h                               |    8 
 tools/libxen/include/xen_pif_metrics.h                                |    8 
 tools/libxen/include/xen_user.h                                       |    6 
 tools/libxen/include/xen_vbd_metrics.h                                |    8 
 tools/libxen/include/xen_vif_metrics.h                                |    8 
 tools/libxen/include/xen_vm.h                                         |    8 
 tools/libxen/include/xen_vm_guest_metrics.h                           |    8 
 tools/libxen/include/xen_vm_metrics.h                                 |    8 
 tools/libxen/src/xen_common.c                                         |  160 
+++++
 tools/libxen/src/xen_console.c                                        |   15 
 tools/libxen/src/xen_crashdump.c                                      |   11 
 tools/libxen/src/xen_host.c                                           |   15 
 tools/libxen/src/xen_host_cpu.c                                       |   15 
 tools/libxen/src/xen_host_metrics.c                                   |   32 +
 tools/libxen/src/xen_network.c                                        |   15 
 tools/libxen/src/xen_pbd.c                                            |   15 
 tools/libxen/src/xen_pif.c                                            |   15 
 tools/libxen/src/xen_pif_metrics.c                                    |   32 +
 tools/libxen/src/xen_sr.c                                             |   15 
 tools/libxen/src/xen_user.c                                           |   17 
 tools/libxen/src/xen_vbd.c                                            |   15 
 tools/libxen/src/xen_vbd_metrics.c                                    |   32 +
 tools/libxen/src/xen_vdi.c                                            |   15 
 tools/libxen/src/xen_vif.c                                            |   15 
 tools/libxen/src/xen_vif_metrics.c                                    |   32 +
 tools/libxen/src/xen_vm.c                                             |   31 -
 tools/libxen/src/xen_vm_guest_metrics.c                               |   36 +
 tools/libxen/src/xen_vm_metrics.c                                     |   36 +
 tools/libxen/src/xen_vtpm.c                                           |   11 
 tools/libxen/test/test_bindings.c                                     |  119 
+++-
 tools/misc/Makefile                                                   |    4 
 tools/python/xen/util/xmlrpclib2.py                                   |    5 
 tools/python/xen/xend/XendAPI.py                                      |  286 
+++++++---
 tools/python/xen/xend/XendConfig.py                                   |   70 +-
 tools/python/xen/xend/XendDomain.py                                   |   78 +-
 tools/python/xen/xend/XendDomainInfo.py                               |   64 +-
 tools/python/xen/xend/XendNode.py                                     |    4 
 tools/python/xen/xend/XendPIFMetrics.py                               |    4 
 tools/python/xen/xend/XendQCoWStorageRepo.py                          |   23 
 tools/python/xen/xend/XendVMMetrics.py                                |  119 
+++-
 tools/python/xen/xend/server/SrvDomain.py                             |   14 
 tools/python/xen/xend/server/pciquirk.py                              |   14 
 tools/python/xen/xm/main.py                                           |  237 
++++++--
 tools/python/xen/xm/xenapi_create.py                                  |   28 
 tools/xenmon/xenmon.py                                                |   22 
 tools/xm-test/lib/XmTestLib/NetConfig.py                              |    2 
 tools/xm-test/lib/XmTestLib/XenDevice.py                              |    8 
 tools/xm-test/lib/XmTestLib/arch.py                                   |    2 
 tools/xm-test/lib/XmTestReport/OSReport.py                            |   20 
 tools/xm-test/lib/XmTestReport/Report.py                              |    2 
 tools/xm-test/tests/create/04_create_conflictname_neg.py              |    6 
 tools/xm-test/tests/create/06_create_mem_neg.py                       |   10 
 tools/xm-test/tests/create/07_create_mem64_pos.py                     |    8 
 tools/xm-test/tests/create/08_create_mem128_pos.py                    |    8 
 tools/xm-test/tests/create/09_create_mem256_pos.py                    |    8 
 tools/xm-test/tests/list/02_list_badparm_neg.py                       |    2 
 tools/xm-test/tests/migrate/01_migrate_localhost_pos.py               |    4 
 tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py |    4 
 tools/xm-test/tests/network-attach/network_utils.py                   |    2 
 tools/xm-test/tests/pause/01_pause_basic_pos.py                       |    4 
 tools/xm-test/tests/security-acm/06_security-acm_dom_block_attach.py  |    8 
 tools/xm-test/tests/unpause/01_unpause_basic_pos.py                   |    7 
 tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py                          |    2 
 tools/xm-test/tests/vtpm/03_vtpm-susp_res.py                          |    2 
 tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py                          |    2 
 tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py                          |    2 
 tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py                     |    4 
 tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py                          |    4 
 tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py                          |    4 
 xen/arch/x86/hvm/hvm.c                                                |    3 
 xen/arch/x86/hvm/pmtimer.c                                            |  220 
++++++-
 xen/common/schedule.c                                                 |    7 
 xen/include/asm-x86/hvm/io.h                                          |    2 
 xen/include/asm-x86/hvm/vpt.h                                         |    4 
 xen/include/public/hvm/save.h                                         |    4 
 80 files changed, 1933 insertions(+), 809 deletions(-)

diff -r 16198b57f535 -r 56caf0e37e6a config/StdGNU.mk
--- a/config/StdGNU.mk  Mon Mar 26 09:17:25 2007 -0600
+++ b/config/StdGNU.mk  Mon Mar 26 10:10:31 2007 -0600
@@ -1,7 +1,7 @@ AS         = $(CROSS_COMPILE)as
 AS         = $(CROSS_COMPILE)as
 LD         = $(CROSS_COMPILE)ld
 CC         = $(CROSS_COMPILE)gcc
-CPP        = $(CROSS_COMPILE)gcc -E
+CPP        = $(CC) -E
 AR         = $(CROSS_COMPILE)ar
 RANLIB     = $(CROSS_COMPILE)ranlib
 NM         = $(CROSS_COMPILE)nm
diff -r 16198b57f535 -r 56caf0e37e6a docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Mon Mar 26 09:17:25 2007 -0600
+++ b/docs/xen-api/xenapi-datamodel.tex Mon Mar 26 10:10:31 2007 -0600
@@ -1062,7 +1062,7 @@ Quals & Field & Type & Description \\
 $\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & 
additional configuration \\
 $\mathit{RO}_\mathit{run}$ &  {\tt domid} & int & domain ID (if available, -1 
otherwise) \\
 $\mathit{RO}_\mathit{run}$ &  {\tt is\_control\_domain} & bool & true if this 
is a control domain (domain 0 or a driver domain) \\
-$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VM\_metrics ref & metrics 
associated with this VM. \\
+$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VM\_metrics ref & metrics 
associated with this VM \\
 $\mathit{RO}_\mathit{run}$ &  {\tt guest\_metrics} & VM\_guest\_metrics ref & 
metrics associated with the running guest \\
 \hline
 \end{longtable}
@@ -1379,7 +1379,7 @@ specified VM is in the Running state.
 \begin{tabular}{|c|c|p{7cm}|}
  \hline
 {\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VM ref } & vm & The VM to hibernate \\ \hline 
+{\tt VM ref } & vm & The VM to suspend \\ \hline 
 
 \end{tabular}
 
@@ -1414,9 +1414,9 @@ specified VM is in the Suspended state.
 \begin{tabular}{|c|c|p{7cm}|}
  \hline
 {\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VM ref } & vm & The VM to unhibernate \\ \hline 
-
-{\tt bool } & start\_paused & Unhibernate VM in paused state if set to true. 
\\ \hline 
+{\tt VM ref } & vm & The VM to resume \\ \hline 
+
+{\tt bool } & start\_paused & Resume VM in paused state if set to true. \\ 
\hline 
 
 \end{tabular}
 
@@ -1434,6 +1434,41 @@ void
 \noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE}
 
 \vspace{0.6cm}
+\subsubsection{RPC name:~set\_VCPUs\_number\_live}
+
+{\bf Overview:} 
+Set this VM's VCPUs/at\_startup value, and set the same value on the VM, if
+running.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void set_VCPUs_number_live (session_id s, VM ref self, int 
nvcpu)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VM ref } & self & The VM \\ \hline 
+
+{\tt int } & nvcpu & The number of VCPUs \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
 \subsubsection{RPC name:~get\_all}
 
 {\bf Overview:} 
@@ -3983,6 +4018,7 @@ Quals & Field & Type & Description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt memory/actual} & int & Guest's actual 
memory (bytes) \\
 $\mathit{RO}_\mathit{run}$ &  {\tt VCPUs/number} & int & Current number of 
VCPUs \\
 $\mathit{RO}_\mathit{run}$ &  {\tt VCPUs/utilisation} & (int $\rightarrow$ 
float) Map & Utilisation for all of guest's current VCPUs \\
+$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which 
this information was last updated \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: VM\_metrics}
@@ -4128,6 +4164,38 @@ Get the VCPUs/utilisation field of the g
  \noindent {\bf Return Type:} 
 {\tt 
 (int $\rightarrow$ float) Map
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_last\_updated}
+
+{\bf Overview:} 
+Get the last\_updated field of the given VM\_metrics.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} datetime get_last_updated (session_id s, VM_metrics ref 
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VM\_metrics ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+datetime
 }
 
 
@@ -4219,6 +4287,7 @@ Quals & Field & Type & Description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt disks} & (string $\rightarrow$ string) Map 
& disk configuration/free space \\
 $\mathit{RO}_\mathit{run}$ &  {\tt networks} & (string $\rightarrow$ string) 
Map & network configuration \\
 $\mathit{RO}_\mathit{run}$ &  {\tt other} & (string $\rightarrow$ string) Map 
& anything else \\
+$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which 
this information was last updated \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: VM\_guest\_metrics}
@@ -4460,6 +4529,38 @@ Get the other field of the given VM\_gue
  \noindent {\bf Return Type:} 
 {\tt 
 (string $\rightarrow$ string) Map
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_last\_updated}
+
+{\bf Overview:} 
+Get the last\_updated field of the given VM\_guest\_metrics.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} datetime get_last_updated (session_id s, VM_guest_metrics ref 
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VM\_guest\_metrics ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+datetime
 }
 
 
@@ -4562,7 +4663,7 @@ Quals & Field & Type & Description \\
 $\mathit{RW}$ &  {\tt crash\_dump\_sr} & SR ref & The SR in which VDIs for 
crash dumps are created \\
 $\mathit{RO}_\mathit{run}$ &  {\tt PBDs} & (PBD ref) Set & physical 
blockdevices \\
 $\mathit{RO}_\mathit{run}$ &  {\tt host\_CPUs} & (host\_cpu ref) Set & The 
physical CPUs on this host \\
-$\mathit{RO}_\mathit{ins}$ &  {\tt metrics} & host\_metrics ref & metrics 
associated with this host. \\
+$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & host\_metrics ref & metrics 
associated with this host \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: host}
@@ -5816,6 +5917,7 @@ Quals & Field & Type & Description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object 
reference \\
 $\mathit{RO}_\mathit{run}$ &  {\tt memory/total} & int & Host's total memory 
(bytes) \\
 $\mathit{RO}_\mathit{run}$ &  {\tt memory/free} & int & Host's free memory 
(bytes) \\
+$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which 
this information was last updated \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: host\_metrics}
@@ -5929,6 +6031,38 @@ Get the memory/free field of the given h
  \noindent {\bf Return Type:} 
 {\tt 
 int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_last\_updated}
+
+{\bf Overview:} 
+Get the last\_updated field of the given host\_metrics.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} datetime get_last_updated (session_id s, host_metrics ref 
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt host\_metrics ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+datetime
 }
 
 
@@ -6852,7 +6986,7 @@ Quals & Field & Type & Description \\
 $\mathit{RW}$ &  {\tt qos/algorithm\_type} & string & QoS algorithm to use \\
 $\mathit{RW}$ &  {\tt qos/algorithm\_params} & (string $\rightarrow$ string) 
Map & parameters for chosen QoS algorithm \\
 $\mathit{RO}_\mathit{run}$ &  {\tt qos/supported\_algorithms} & string Set & 
supported QoS algorithms for this VIF \\
-$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VIF\_metrics ref & metrics 
associated with this VIF. \\
+$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VIF\_metrics ref & metrics 
associated with this VIF \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: VIF}
@@ -7745,6 +7879,7 @@ Quals & Field & Type & Description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object 
reference \\
 $\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth 
(KiB/s) \\
 $\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth 
(KiB/s) \\
+$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which 
this information was last updated \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: VIF\_metrics}
@@ -7858,6 +7993,38 @@ Get the io/write\_kbs field of the given
  \noindent {\bf Return Type:} 
 {\tt 
 float
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_last\_updated}
+
+{\bf Overview:} 
+Get the last\_updated field of the given VIF\_metrics.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} datetime get_last_updated (session_id s, VIF_metrics ref 
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VIF\_metrics ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+datetime
 }
 
 
@@ -7950,7 +8117,7 @@ Quals & Field & Type & Description \\
 $\mathit{RW}$ &  {\tt MAC} & string & ethernet MAC address of physical 
interface \\
 $\mathit{RW}$ &  {\tt MTU} & int & MTU in octets \\
 $\mathit{RW}$ &  {\tt VLAN} & int & VLAN tag for all traffic passing through 
this interface \\
-$\mathit{RO}_\mathit{ins}$ &  {\tt metrics} & PIF\_metrics ref & metrics 
associated with this PIF. \\
+$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & PIF\_metrics ref & metrics 
associated with this PIF \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: PIF}
@@ -8522,6 +8689,7 @@ Quals & Field & Type & Description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object 
reference \\
 $\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth 
(KiB/s) \\
 $\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth 
(KiB/s) \\
+$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which 
this information was last updated \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: PIF\_metrics}
@@ -8635,6 +8803,38 @@ Get the io/write\_kbs field of the given
  \noindent {\bf Return Type:} 
 {\tt 
 float
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_last\_updated}
+
+{\bf Overview:} 
+Get the last\_updated field of the given PIF\_metrics.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} datetime get_last_updated (session_id s, PIF_metrics ref 
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt PIF\_metrics ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+datetime
 }
 
 
@@ -11293,6 +11493,7 @@ Quals & Field & Type & Description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object 
reference \\
 $\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth 
(KiB/s) \\
 $\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth 
(KiB/s) \\
+$\mathit{RO}_\mathit{run}$ &  {\tt last\_updated} & datetime & Time at which 
this information was last updated \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: VBD\_metrics}
@@ -11406,6 +11607,38 @@ Get the io/write\_kbs field of the given
  \noindent {\bf Return Type:} 
 {\tt 
 float
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_last\_updated}
+
+{\bf Overview:} 
+Get the last\_updated field of the given VBD\_metrics.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} datetime get_last_updated (session_id s, VBD_metrics ref 
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD\_metrics ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+datetime
 }
 
 
@@ -13384,14 +13617,3 @@ HVM is required for this operation
 {\bf Signature:}
 \begin{verbatim}VM_HVM_REQUIRED(vm)\end{verbatim}
 \begin{center}\rule{10em}{0.1pt}\end{center}
-
-
-
-\newpage
-\section{DTD}
-General notes:
-\begin{itemize}
-\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)''
-\item Values of enumeration types are represented as strings (e.g. ``PAE'', 
``3DNow!'')
-\item Object References are represented as UUIDs, written in string form
-\end{itemize}
diff -r 16198b57f535 -r 56caf0e37e6a tools/ioemu/hw/piix4acpi.c
--- a/tools/ioemu/hw/piix4acpi.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/ioemu/hw/piix4acpi.c        Mon Mar 26 10:10:31 2007 -0600
@@ -52,126 +52,16 @@ typedef struct AcpiDeviceState AcpiDevic
 typedef struct AcpiDeviceState AcpiDeviceState;
 AcpiDeviceState *acpi_device_table;
 
-typedef struct PM1Event_BLK {
-    uint16_t pm1_status; /* pm1a_EVT_BLK */
-    uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
-}PM1Event_BLK;
-
 typedef struct PCIAcpiState {
     PCIDevice dev;
-    uint16_t irq;
-    uint16_t pm1_status; /* pm1a_EVT_BLK */
-    uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
     uint16_t pm1_control; /* pm1a_ECNT_BLK */
-    uint32_t pm1_timer; /* pmtmr_BLK */
-    uint64_t old_vmck_ticks; /* using vm_clock counter */
 } PCIAcpiState;
-
-static PCIAcpiState *acpi_state;
-
-static void acpi_reset(PCIAcpiState *s)
-{
-    uint8_t *pci_conf;
-    pci_conf = s->dev.config;
-
-    pci_conf[0x42] = 0x00;
-    pci_conf[0x43] = 0x00;
-    s->irq = 9;
-    s->pm1_status = 0;
-    s->pm1_enable = 0x00;    /* TMROF_EN should cleared */
-    s->pm1_control = SCI_EN; /* SCI_EN */
-    s->pm1_timer = 0;
-    s->old_vmck_ticks = qemu_get_clock(vm_clock);
-}
-
-/*byte access  */
-static void acpiPm1Status_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIAcpiState *s = opaque;
-
-    if ((val&TMROF_STS)==TMROF_STS)
-        s->pm1_status = s->pm1_status&!TMROF_STS;
-
-    if ((val&GBL_STS)==GBL_STS)
-        s->pm1_status = s->pm1_status&!GBL_STS;
-
-/*     printf("acpiPm1Status_writeb \n addr %x val:%x pm1_status:%x \n", addr, 
val,s->pm1_status); */
-}
-
-static uint32_t acpiPm1Status_readb(void *opaque, uint32_t addr)
-{
-    PCIAcpiState *s = opaque;
-    uint32_t val;
-
-    val = s->pm1_status;
-/*         printf("acpiPm1Status_readb \n addr %x val:%x\n", addr, val); */
-
-   return val;
-}
-
-static void acpiPm1StatusP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIAcpiState *s = opaque;
-
-    s->pm1_status = (val<<8)||(s->pm1_status);
-/*     printf("acpiPm1StatusP1_writeb \n addr %x val:%x\n", addr, val); */
-}
-
-static uint32_t acpiPm1StatusP1_readb(void *opaque, uint32_t addr)
-{
-    PCIAcpiState *s = opaque;
-    uint32_t val;
-
-    val = (s->pm1_status)>>8;
-    printf("acpiPm1StatusP1_readb \n addr %x val:%x\n", addr, val);
-
-    return val;
-}
-
-static void acpiPm1Enable_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIAcpiState *s = opaque;
-
-    s->pm1_enable = val;
-/*   printf("acpiPm1Enable_writeb \n addr %x val:%x\n", addr, val); */
-}
-
-static uint32_t acpiPm1Enable_readb(void *opaque, uint32_t addr)
-{
-    PCIAcpiState *s = opaque;
-    uint32_t val;
-
-    val = (s->pm1_enable)||0x1;
-/*  printf("acpiPm1Enable_readb \n addr %x val:%x\n", addr, val); */
-
-    return val;
-}
-
-static void acpiPm1EnableP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIAcpiState *s = opaque;
-
-    s->pm1_enable = (val<<8)||(s->pm1_enable);
-/*    printf("acpiPm1EnableP1_writeb \n addr %x val:%x\n", addr, val); */
-
-}
-
-static uint32_t acpiPm1EnableP1_readb(void *opaque, uint32_t addr)
-{
-    PCIAcpiState *s = opaque;
-    uint32_t val;
-
-    val = (s->pm1_enable)>>8;
-/*  printf("acpiPm1EnableP1_readb \n addr %x val:%x\n", addr, val); */
-
-    return val;
-}
 
 static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     PCIAcpiState *s = opaque;
 
-    s->pm1_control = val;
+    s->pm1_control = (s->pm1_control & 0xff00) | (val & 0xff);
 /*  printf("acpiPm1Control_writeb \n addr %x val:%x\n", addr, val); */
 
 }
@@ -181,7 +71,8 @@ static uint32_t acpiPm1Control_readb(voi
     PCIAcpiState *s = opaque;
     uint32_t val;
 
-    val = s->pm1_control;
+    /* Mask out the write-only bits */
+    val = s->pm1_control & ~(GBL_RLS|SLP_EN) & 0xff;
 /*    printf("acpiPm1Control_readb \n addr %x val:%x\n", addr, val); */
 
     return val;
@@ -191,14 +82,13 @@ static void acpiPm1ControlP1_writeb(void
 {
     PCIAcpiState *s = opaque;
 
-    s->pm1_control = (val<<8)||(s->pm1_control);
+    s->pm1_control = (s->pm1_control & 0xff) | (val << 8);
 /*    printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */
 
     // Check for power off request
-
+    val <<= 8;
     if (((val & SLP_EN) != 0) &&
         ((val & SLP_TYP_MASK) == SLP_VAL)) {
-        s->pm1_timer=0x0; //clear ACPI timer
         qemu_system_shutdown_request();
     }
 }
@@ -208,7 +98,8 @@ static uint32_t acpiPm1ControlP1_readb(v
     PCIAcpiState *s = opaque;
     uint32_t val;
 
-    val = (s->pm1_control)>>8;
+    /* Mask out the write-only bits */
+    val = (s->pm1_control & ~(GBL_RLS|SLP_EN)) >> 8;
 /*    printf("acpiPm1ControlP1_readb \n addr %x val:%x\n", addr, val); */
 
     return val;
@@ -216,50 +107,6 @@ static uint32_t acpiPm1ControlP1_readb(v
 
 
 /* word access   */
-
-static void acpiPm1Status_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIAcpiState *s = opaque;
-
-    if ((val&TMROF_STS)==TMROF_STS)
-        s->pm1_status = s->pm1_status&!TMROF_STS;
-
-    if ((val&GBL_STS)==GBL_STS)
-        s->pm1_status = s->pm1_status&!GBL_STS;
-
-/*    printf("acpiPm1Status_writew \n addr %x val:%x pm1_status:%x \n", addr, 
val,s->pm1_status); */
-}
-
-static uint32_t acpiPm1Status_readw(void *opaque, uint32_t addr)
-{
-    PCIAcpiState *s = opaque;
-    uint32_t val;
-
-    val = s->pm1_status;
-/*    printf("acpiPm1Status_readw \n addr %x val:%x\n", addr, val); */
-
-    return val;
-}
-
-static void acpiPm1Enable_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIAcpiState *s = opaque;
-
-    s->pm1_enable = val;
-/*    printf("acpiPm1Enable_writew \n addr %x val:%x\n", addr, val); */
-
-}
-
-static uint32_t acpiPm1Enable_readw(void *opaque, uint32_t addr)
-{
-    PCIAcpiState *s = opaque;
-    uint32_t val;
-
-    val = s->pm1_enable;
-/*    printf("acpiPm1Enable_readw \n addr %x val:%x\n", addr, val); */
-
-   return val;
-}
 
 static void acpiPm1Control_writew(void *opaque, uint32_t addr, uint32_t val)
 {
@@ -282,56 +129,13 @@ static uint32_t acpiPm1Control_readw(voi
     PCIAcpiState *s = opaque;
     uint32_t val;
 
-    val = s->pm1_control;
+    /* Mask out the write-only bits */
+    val = s->pm1_control & ~(GBL_RLS|SLP_EN);
 /*    printf("acpiPm1Control_readw \n addr %x val:%x\n", addr, val);  */
 
     return val;
 }
 
-/* dword access */
-
-static void acpiPm1Event_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIAcpiState *s = opaque;
-
-    s->pm1_status = val;
-    s->pm1_enable = val>>16;
-/*     printf("acpiPm1Event_writel \n addr %x val:%x \n", addr, val); */
-
-}
-
-static uint32_t acpiPm1Event_readl(void *opaque, uint32_t addr)
-{
-    PCIAcpiState *s = opaque;
-    uint32_t val;
-
-    val = s->pm1_status|(s->pm1_enable<<16);
-/*    printf("acpiPm1Event_readl \n addr %x val:%x\n", addr, val);    */
-
-    return val;
-}
-
-static void acpiPm1Timer_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    PCIAcpiState *s = opaque;
-
-    s->pm1_timer = val;
-    s->old_vmck_ticks = qemu_get_clock(vm_clock) +
-        muldiv64(val, FREQUENCE_PMTIMER, ticks_per_sec);
-}
-
-static uint32_t acpiPm1Timer_readl(void *opaque, uint32_t addr)
-{
-    PCIAcpiState *s = opaque;
-    int64_t current_vmck_ticks = qemu_get_clock(vm_clock);
-    int64_t vmck_ticks_delta = current_vmck_ticks - s->old_vmck_ticks;
-
-    if (s->old_vmck_ticks)
-        s->pm1_timer += muldiv64(vmck_ticks_delta, FREQUENCE_PMTIMER,
-                                 ticks_per_sec);
-    s->old_vmck_ticks = current_vmck_ticks;
-    return s->pm1_timer;
-}
 
 static void acpi_map(PCIDevice *pci_dev, int region_num,
                     uint32_t addr, uint32_t size, int type)
@@ -341,37 +145,14 @@ static void acpi_map(PCIDevice *pci_dev,
     printf("register acpi io\n");
 
     /* Byte access */
-    register_ioport_write(addr, 1, 1, acpiPm1Status_writeb, d);
-    register_ioport_read(addr, 1, 1, acpiPm1Status_readb, d);
-    register_ioport_write(addr+1, 1, 1, acpiPm1StatusP1_writeb, d);
-    register_ioport_read(addr+1, 1, 1, acpiPm1StatusP1_readb, d);
-
-    register_ioport_write(addr + 2, 1, 1, acpiPm1Enable_writeb, d);
-    register_ioport_read(addr + 2, 1, 1, acpiPm1Enable_readb, d);
-    register_ioport_write(addr + 2 +1, 1, 1, acpiPm1EnableP1_writeb, d);
-    register_ioport_read(addr + 2 +1, 1, 1, acpiPm1EnableP1_readb, d);
-
     register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d);
     register_ioport_read(addr + 4, 1, 1, acpiPm1Control_readb, d);
     register_ioport_write(addr + 4 + 1, 1, 1, acpiPm1ControlP1_writeb, d);
     register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);
 
     /* Word access */
-    register_ioport_write(addr, 2, 2, acpiPm1Status_writew, d);
-    register_ioport_read(addr, 2, 2, acpiPm1Status_readw, d);
-
-    register_ioport_write(addr + 2, 2, 2, acpiPm1Enable_writew, d);
-    register_ioport_read(addr + 2, 2, 2, acpiPm1Enable_readw, d);
-
     register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d);
     register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
-
-    /* DWord access */
-    register_ioport_write(addr, 4, 4, acpiPm1Event_writel, d);
-    register_ioport_read(addr, 4, 4, acpiPm1Event_readl, d);
-
-    register_ioport_write(addr + 8, 4, 4, acpiPm1Timer_writel, d);
-    register_ioport_read(addr + 8, 4, 4, acpiPm1Timer_readl, d);
 }
 
 /* PIIX4 acpi pci configuration space, func 2 */
@@ -385,7 +166,6 @@ void pci_piix4_acpi_init(PCIBus *bus, in
         bus, "PIIX4 ACPI", sizeof(PCIAcpiState),
         devfn, NULL, NULL);
 
-    acpi_state = d;
     pci_conf = d->dev.config;
     pci_conf[0x00] = 0x86;  /* Intel */
     pci_conf[0x01] = 0x80;
@@ -408,6 +188,9 @@ void pci_piix4_acpi_init(PCIBus *bus, in
      */
     pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
     pci_conf[0x41] = 0x1f;
+    pci_conf[0x42] = 0x00;
+    pci_conf[0x43] = 0x00;
+    d->pm1_control = SCI_EN;
+
     acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
-    acpi_reset(d);
 }
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/include/xen_common.h
--- a/tools/libxen/include/xen_common.h Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/include/xen_common.h Mon Mar 26 10:10:31 2007 -0600
@@ -51,6 +51,30 @@ typedef struct
 } xen_session;
 
 
+typedef struct xen_session_record
+{
+    char *uuid;
+    struct xen_host_record_opt *this_host;
+    char *this_user;
+    time_t last_active;
+} xen_session_record;
+
+
+/**
+ * Allocate a xen_session_record.
+ */
+extern xen_session_record *
+xen_session_record_alloc(void);
+
+
+/**
+ * Free the given xen_session_record, and all referenced values.  The
+ * given record must have been allocated by this library.
+ */
+extern void
+xen_session_record_free(xen_session_record *record);
+
+
 struct xen_task_;
 typedef struct xen_task_ * xen_task_id;
 
@@ -136,10 +160,45 @@ xen_session_logout(xen_session *session)
 
 
 /**
- * Set *result to be a handle to the host to which this session is connected.
- */
-extern int
-xen_session_get_this_host(xen_session *session, xen_host *result);
+ * Get the UUID of the second given session.  Set *result to point at a
+ * string, yours to free.
+ */
+extern bool
+xen_session_get_uuid(xen_session *session, char **result,
+                     xen_session *self_session);
+
+
+/**
+ * Get the this_host field of the second given session.  Set *result to be a
+ * handle to that host.
+ */
+extern bool
+xen_session_get_this_host(xen_session *session, xen_host *result,
+                          xen_session *self_session);
+
+
+/**
+ * Get the this_user field of the second given session.  Set *result to point
+ * at a string, yours to free.
+ */
+extern bool
+xen_session_get_this_user(xen_session *session, char **result,
+                          xen_session *self_session);
+
+
+/**
+ * Get the last_active field of the given session, and place it in *result.
+ */
+extern bool
+xen_session_get_last_active(xen_session *session, time_t *result,
+                            xen_session *self_session);
+
+/**
+ * Get a record containing the current state of the second given session.
+ */
+extern bool
+xen_session_get_record(xen_session *session, xen_session_record **result,
+                       xen_session *self_session);
 
 
 #endif
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/include/xen_host_metrics.h
--- a/tools/libxen/include/xen_host_metrics.h   Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/include/xen_host_metrics.h   Mon Mar 26 10:10:31 2007 -0600
@@ -64,6 +64,7 @@ typedef struct xen_host_metrics_record
     char *uuid;
     int64_t memory_total;
     int64_t memory_free;
+    time_t last_updated;
 } xen_host_metrics_record;
 
 /**
@@ -182,6 +183,13 @@ xen_host_metrics_get_memory_free(xen_ses
 
 
 /**
+ * Get the last_updated field of the given host_metrics.
+ */
+extern bool
+xen_host_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_host_metrics host_metrics);
+
+
+/**
  * Return a list of all the host_metrics instances known to the system.
  */
 extern bool
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/include/xen_pif_metrics.h
--- a/tools/libxen/include/xen_pif_metrics.h    Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/include/xen_pif_metrics.h    Mon Mar 26 10:10:31 2007 -0600
@@ -64,6 +64,7 @@ typedef struct xen_pif_metrics_record
     char *uuid;
     double io_read_kbs;
     double io_write_kbs;
+    time_t last_updated;
 } xen_pif_metrics_record;
 
 /**
@@ -181,6 +182,13 @@ xen_pif_metrics_get_io_write_kbs(xen_ses
 
 
 /**
+ * Get the last_updated field of the given PIF_metrics.
+ */
+extern bool
+xen_pif_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_pif_metrics pif_metrics);
+
+
+/**
  * Return a list of all the PIF_metrics instances known to the system.
  */
 extern bool
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/include/xen_user.h
--- a/tools/libxen/include/xen_user.h   Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/include/xen_user.h   Mon Mar 26 10:10:31 2007 -0600
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -24,8 +24,8 @@
 
 
 /*
- * The user class. 
- *  
+ * The user class.
+ * 
  * A user of the system.
  */
 
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/include/xen_vbd_metrics.h
--- a/tools/libxen/include/xen_vbd_metrics.h    Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/include/xen_vbd_metrics.h    Mon Mar 26 10:10:31 2007 -0600
@@ -64,6 +64,7 @@ typedef struct xen_vbd_metrics_record
     char *uuid;
     double io_read_kbs;
     double io_write_kbs;
+    time_t last_updated;
 } xen_vbd_metrics_record;
 
 /**
@@ -181,6 +182,13 @@ xen_vbd_metrics_get_io_write_kbs(xen_ses
 
 
 /**
+ * Get the last_updated field of the given VBD_metrics.
+ */
+extern bool
+xen_vbd_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_vbd_metrics vbd_metrics);
+
+
+/**
  * Return a list of all the VBD_metrics instances known to the system.
  */
 extern bool
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/include/xen_vif_metrics.h
--- a/tools/libxen/include/xen_vif_metrics.h    Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/include/xen_vif_metrics.h    Mon Mar 26 10:10:31 2007 -0600
@@ -64,6 +64,7 @@ typedef struct xen_vif_metrics_record
     char *uuid;
     double io_read_kbs;
     double io_write_kbs;
+    time_t last_updated;
 } xen_vif_metrics_record;
 
 /**
@@ -181,6 +182,13 @@ xen_vif_metrics_get_io_write_kbs(xen_ses
 
 
 /**
+ * Get the last_updated field of the given VIF_metrics.
+ */
+extern bool
+xen_vif_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_vif_metrics vif_metrics);
+
+
+/**
  * Return a list of all the VIF_metrics instances known to the system.
  */
 extern bool
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/include/xen_vm.h
--- a/tools/libxen/include/xen_vm.h     Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/include/xen_vm.h     Mon Mar 26 10:10:31 2007 -0600
@@ -830,6 +830,14 @@ xen_vm_resume(xen_session *session, xen_
 
 
 /**
+ * Set this VM's VCPUs/at_startup value, and set the same value on the
+ * VM, if running
+ */
+extern bool
+xen_vm_set_vcpus_number_live(xen_session *session, xen_vm self, int64_t nvcpu);
+
+
+/**
  * Return a list of all the VMs known to the system.
  */
 extern bool
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/include/xen_vm_guest_metrics.h
--- a/tools/libxen/include/xen_vm_guest_metrics.h       Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/libxen/include/xen_vm_guest_metrics.h       Mon Mar 26 10:10:31 
2007 -0600
@@ -69,6 +69,7 @@ typedef struct xen_vm_guest_metrics_reco
     xen_string_string_map *disks;
     xen_string_string_map *networks;
     xen_string_string_map *other;
+    time_t last_updated;
 } xen_vm_guest_metrics_record;
 
 /**
@@ -216,6 +217,13 @@ xen_vm_guest_metrics_get_other(xen_sessi
 
 
 /**
+ * Get the last_updated field of the given VM_guest_metrics.
+ */
+extern bool
+xen_vm_guest_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_vm_guest_metrics vm_guest_metrics);
+
+
+/**
  * Return a list of all the VM_guest_metrics instances known to the
  * system.
  */
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/include/xen_vm_metrics.h
--- a/tools/libxen/include/xen_vm_metrics.h     Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/include/xen_vm_metrics.h     Mon Mar 26 10:10:31 2007 -0600
@@ -66,6 +66,7 @@ typedef struct xen_vm_metrics_record
     int64_t memory_actual;
     int64_t vcpus_number;
     xen_int_float_map *vcpus_utilisation;
+    time_t last_updated;
 } xen_vm_metrics_record;
 
 /**
@@ -190,6 +191,13 @@ xen_vm_metrics_get_vcpus_utilisation(xen
 
 
 /**
+ * Get the last_updated field of the given VM_metrics.
+ */
+extern bool
+xen_vm_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_vm_metrics vm_metrics);
+
+
+/**
  * Return a list of all the VM_metrics instances known to the system.
  */
 extern bool
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_common.c
--- a/tools/libxen/src/xen_common.c     Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_common.c     Mon Mar 26 10:10:31 2007 -0600
@@ -16,12 +16,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
 
+#define _XOPEN_SOURCE
 #include <assert.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
 #include <libxml/parser.h>
 #include <libxml/tree.h>
@@ -30,6 +32,7 @@
 #include <libxml/xpath.h>
 
 #include "xen_common.h"
+#include "xen_host.h"
 #include "xen_internal.h"
 #include "xen_int_float_map.h"
 #include "xen_string_string_map.h"
@@ -136,6 +139,20 @@ xen_fini(void)
 }
 
 
+void
+xen_session_record_free(xen_session_record *record)
+{
+    if (record == NULL)
+    {
+        return;
+    }
+    free(record->uuid);
+    xen_host_record_opt_free(record->this_host);
+    free(record->this_user);
+    free(record);
+}
+
+
 xen_session *
 xen_session_login_with_password(xen_call_func call_func, void *handle,
                                 const char *uname, const char *pwd)
@@ -185,15 +202,111 @@ xen_session_logout(xen_session *session)
 }
 
 
-int
-xen_session_get_this_host(xen_session *session, xen_host *result)
+bool
+xen_session_get_uuid(xen_session *session, char **result,
+                     xen_session *self_session)
 {
     abstract_value params[] =
         {
+            { .type = &abstract_type_string,
+              .u.string_val = self_session->session_id }
         };
 
-    xen_call_(session, "session.get_this_host", params, 0,
+    xen_call_(session, "session.get_uuid", params, 1,
               &abstract_type_string, result);
+    return session->ok;
+}
+
+
+bool
+xen_session_get_this_host(xen_session *session, xen_host *result,
+                          xen_session *self_session)
+{
+    abstract_value params[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = self_session->session_id }
+        };
+
+    xen_call_(session, "session.get_this_host", params, 1,
+              &abstract_type_string, result);
+    return session->ok;
+}
+
+
+bool
+xen_session_get_this_user(xen_session *session, char **result,
+                          xen_session *self_session)
+{
+    abstract_value params[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = self_session->session_id }
+        };
+
+    xen_call_(session, "session.get_this_user", params, 1,
+              &abstract_type_string, result);
+    return session->ok;
+}
+
+
+bool
+xen_session_get_last_active(xen_session *session, time_t *result,
+                            xen_session *self_session)
+{
+    abstract_value params[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = self_session->session_id }
+        };
+
+    xen_call_(session, "session.get_last_active", params, 1,
+              &abstract_type_datetime, result);
+    return session->ok;
+}
+
+
+static const struct_member xen_session_record_struct_members[] =
+    {
+        { .key = "uuid",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_session_record, uuid) },
+        { .key = "this_host",
+          .type = &abstract_type_ref,
+          .offset = offsetof(xen_session_record, this_host) },
+        { .key = "this_user",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_session_record, this_user) },
+        { .key = "last_active",
+          .type = &abstract_type_datetime,
+          .offset = offsetof(xen_session_record, last_active) },
+    };
+
+const abstract_type xen_session_record_abstract_type_ =
+    {
+       .typename = STRUCT,
+       .struct_size = sizeof(xen_session_record),
+       .member_count =
+           sizeof(xen_session_record_struct_members) / sizeof(struct_member),
+       .members = xen_session_record_struct_members
+    };
+
+
+bool
+xen_session_get_record(xen_session *session, xen_session_record **result,
+                       xen_session *self_session)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = self_session->session_id }
+        };
+
+    abstract_type result_type = xen_session_record_abstract_type_;
+
+    *result = NULL;
+    XEN_CALL_("session.get_record");
+
     return session->ok;
 }
 
@@ -493,16 +606,18 @@ static void destring(xen_session *s, xml
 
 
 /**
- * result_type : STRING => value : char **, the char * is yours.
- * result_type : ENUM   => value : int *
- * result_type : INT    => value : int64_t *
- * result_type : FLOAT  => value : double *
- * result_type : BOOL   => value : bool *
- * result_type : SET    => value : arbitrary_set **, the set is yours.
- * result_type : MAP    => value : arbitrary_map **, the map is yours.
- * result_type : OPT    => value : arbitrary_record_opt **,
- *                                 the record is yours, the handle is filled.
- * result_type : STRUCT => value : void **, the void * is yours.
+ * result_type : STRING   => value : char **, the char * is yours.
+ * result_type : ENUM     => value : int *
+ * result_type : INT      => value : int64_t *
+ * result_type : FLOAT    => value : double *
+ * result_type : BOOL     => value : bool *
+ * result_type : DATETIME => value : time_t *
+ * result_type : SET      => value : arbitrary_set **, the set is yours.
+ * result_type : MAP      => value : arbitrary_map **, the map is yours.
+ * result_type : OPT      => value : arbitrary_record_opt **,
+ *                                   the record is yours, the handle is
+ *                                   filled.
+ * result_type : STRUCT   => value : void **, the void * is yours.
  */
 static void parse_into(xen_session *s, xmlNode *value_node,
                        const abstract_type *result_type, void *value,
@@ -620,6 +735,25 @@ static void parse_into(xen_session *s, x
         else
         {
             ((bool *)value)[slot] = (0 == strcmp((char *)string, "1"));
+            free(string);
+        }
+    }
+    break;
+
+    case DATETIME:
+    {
+        xmlChar *string = string_from_value(value_node, "dateTime.iso8601");
+        if (string == NULL)
+        {
+            server_error(
+                s, "Expected an DateTime from the server but didn't get one");
+        }
+        else
+        {
+            struct tm tm;
+            memset(&tm, 0, sizeof(tm));
+            strptime((char *)string, "%Y%m%dT%H:%M:%S", &tm);
+            ((time_t *)value)[slot] = (time_t)mktime(&tm);
             free(string);
         }
     }
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_console.c
--- a/tools/libxen/src/xen_console.c    Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_console.c    Mon Mar 26 10:10:31 2007 -0600
@@ -284,6 +284,15 @@ bool
 bool
 xen_console_get_uuid(xen_session *session, char **result, xen_console console)
 {
-    *result = session->ok ? xen_strdup_((char *)console) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = console }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("console.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_crashdump.c
--- a/tools/libxen/src/xen_crashdump.c  Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_crashdump.c  Mon Mar 26 10:10:31 2007 -0600
@@ -177,6 +177,15 @@ bool
 bool
 xen_crashdump_get_uuid(xen_session *session, char **result, xen_crashdump 
crashdump)
 {
-    *result = session->ok ? xen_strdup_((char *)crashdump) : NULL;
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = crashdump }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("crashdump.get_uuid");
     return session->ok;
 }
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_host.c
--- a/tools/libxen/src/xen_host.c       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_host.c       Mon Mar 26 10:10:31 2007 -0600
@@ -754,6 +754,15 @@ bool
 bool
 xen_host_get_uuid(xen_session *session, char **result, xen_host host)
 {
-    *result = session->ok ? xen_strdup_((char *)host) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = host }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("host.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_host_cpu.c
--- a/tools/libxen/src/xen_host_cpu.c   Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_host_cpu.c   Mon Mar 26 10:10:31 2007 -0600
@@ -282,6 +282,15 @@ bool
 bool
 xen_host_cpu_get_uuid(xen_session *session, char **result, xen_host_cpu 
host_cpu)
 {
-    *result = session->ok ? xen_strdup_((char *)host_cpu) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = host_cpu }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("host_cpu.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_host_metrics.c
--- a/tools/libxen/src/xen_host_metrics.c       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_host_metrics.c       Mon Mar 26 10:10:31 2007 -0600
@@ -44,7 +44,10 @@ static const struct_member xen_host_metr
           .offset = offsetof(xen_host_metrics_record, memory_total) },
         { .key = "memory_free",
           .type = &abstract_type_int,
-          .offset = offsetof(xen_host_metrics_record, memory_free) }
+          .offset = offsetof(xen_host_metrics_record, memory_free) },
+        { .key = "last_updated",
+          .type = &abstract_type_datetime,
+          .offset = offsetof(xen_host_metrics_record, last_updated) }
     };
 
 const abstract_type xen_host_metrics_record_abstract_type_ =
@@ -143,6 +146,22 @@ xen_host_metrics_get_memory_free(xen_ses
 
 
 bool
+xen_host_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_host_metrics host_metrics)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = host_metrics }
+        };
+
+    abstract_type result_type = abstract_type_datetime;
+
+    XEN_CALL_("host_metrics.get_last_updated");
+    return session->ok;
+}
+
+
+bool
 xen_host_metrics_get_all(xen_session *session, struct xen_host_metrics_set 
**result)
 {
 
@@ -157,6 +176,15 @@ bool
 bool
 xen_host_metrics_get_uuid(xen_session *session, char **result, 
xen_host_metrics host_metrics)
 {
-    *result = session->ok ? xen_strdup_((char *)host_metrics) : NULL;
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = host_metrics }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("host_metrics.get_uuid");
     return session->ok;
 }
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_network.c
--- a/tools/libxen/src/xen_network.c    Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_network.c    Mon Mar 26 10:10:31 2007 -0600
@@ -285,6 +285,15 @@ bool
 bool
 xen_network_get_uuid(xen_session *session, char **result, xen_network network)
 {
-    *result = session->ok ? xen_strdup_((char *)network) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = network }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("network.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_pbd.c
--- a/tools/libxen/src/xen_pbd.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_pbd.c        Mon Mar 26 10:10:31 2007 -0600
@@ -235,6 +235,15 @@ bool
 bool
 xen_pbd_get_uuid(xen_session *session, char **result, xen_pbd pbd)
 {
-    *result = session->ok ? xen_strdup_((char *)pbd) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = pbd }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("PBD.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_pif.c
--- a/tools/libxen/src/xen_pif.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_pif.c        Mon Mar 26 10:10:31 2007 -0600
@@ -366,6 +366,15 @@ bool
 bool
 xen_pif_get_uuid(xen_session *session, char **result, xen_pif pif)
 {
-    *result = session->ok ? xen_strdup_((char *)pif) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = pif }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("PIF.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_pif_metrics.c
--- a/tools/libxen/src/xen_pif_metrics.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_pif_metrics.c        Mon Mar 26 10:10:31 2007 -0600
@@ -44,7 +44,10 @@ static const struct_member xen_pif_metri
           .offset = offsetof(xen_pif_metrics_record, io_read_kbs) },
         { .key = "io_write_kbs",
           .type = &abstract_type_float,
-          .offset = offsetof(xen_pif_metrics_record, io_write_kbs) }
+          .offset = offsetof(xen_pif_metrics_record, io_write_kbs) },
+        { .key = "last_updated",
+          .type = &abstract_type_datetime,
+          .offset = offsetof(xen_pif_metrics_record, last_updated) }
     };
 
 const abstract_type xen_pif_metrics_record_abstract_type_ =
@@ -143,6 +146,22 @@ xen_pif_metrics_get_io_write_kbs(xen_ses
 
 
 bool
+xen_pif_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_pif_metrics pif_metrics)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = pif_metrics }
+        };
+
+    abstract_type result_type = abstract_type_datetime;
+
+    XEN_CALL_("PIF_metrics.get_last_updated");
+    return session->ok;
+}
+
+
+bool
 xen_pif_metrics_get_all(xen_session *session, struct xen_pif_metrics_set 
**result)
 {
 
@@ -157,6 +176,15 @@ bool
 bool
 xen_pif_metrics_get_uuid(xen_session *session, char **result, xen_pif_metrics 
pif_metrics)
 {
-    *result = session->ok ? xen_strdup_((char *)pif_metrics) : NULL;
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = pif_metrics }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("PIF_metrics.get_uuid");
     return session->ok;
 }
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_sr.c
--- a/tools/libxen/src/xen_sr.c Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_sr.c Mon Mar 26 10:10:31 2007 -0600
@@ -388,6 +388,15 @@ bool
 bool
 xen_sr_get_uuid(xen_session *session, char **result, xen_sr sr)
 {
-    *result = session->ok ? xen_strdup_((char *)sr) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = sr }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("SR.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_user.c
--- a/tools/libxen/src/xen_user.c       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_user.c       Mon Mar 26 10:10:31 2007 -0600
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -196,6 +196,15 @@ bool
 bool
 xen_user_get_uuid(xen_session *session, char **result, xen_user user)
 {
-    *result = session->ok ? xen_strdup_((char *)user) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = user }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("user.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_vbd.c
--- a/tools/libxen/src/xen_vbd.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_vbd.c        Mon Mar 26 10:10:31 2007 -0600
@@ -591,6 +591,15 @@ bool
 bool
 xen_vbd_get_uuid(xen_session *session, char **result, xen_vbd vbd)
 {
-    *result = session->ok ? xen_strdup_((char *)vbd) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vbd }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VBD.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_vbd_metrics.c
--- a/tools/libxen/src/xen_vbd_metrics.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_vbd_metrics.c        Mon Mar 26 10:10:31 2007 -0600
@@ -44,7 +44,10 @@ static const struct_member xen_vbd_metri
           .offset = offsetof(xen_vbd_metrics_record, io_read_kbs) },
         { .key = "io_write_kbs",
           .type = &abstract_type_float,
-          .offset = offsetof(xen_vbd_metrics_record, io_write_kbs) }
+          .offset = offsetof(xen_vbd_metrics_record, io_write_kbs) },
+        { .key = "last_updated",
+          .type = &abstract_type_datetime,
+          .offset = offsetof(xen_vbd_metrics_record, last_updated) }
     };
 
 const abstract_type xen_vbd_metrics_record_abstract_type_ =
@@ -143,6 +146,22 @@ xen_vbd_metrics_get_io_write_kbs(xen_ses
 
 
 bool
+xen_vbd_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_vbd_metrics vbd_metrics)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vbd_metrics }
+        };
+
+    abstract_type result_type = abstract_type_datetime;
+
+    XEN_CALL_("VBD_metrics.get_last_updated");
+    return session->ok;
+}
+
+
+bool
 xen_vbd_metrics_get_all(xen_session *session, struct xen_vbd_metrics_set 
**result)
 {
 
@@ -157,6 +176,15 @@ bool
 bool
 xen_vbd_metrics_get_uuid(xen_session *session, char **result, xen_vbd_metrics 
vbd_metrics)
 {
-    *result = session->ok ? xen_strdup_((char *)vbd_metrics) : NULL;
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vbd_metrics }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VBD_metrics.get_uuid");
     return session->ok;
 }
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_vdi.c
--- a/tools/libxen/src/xen_vdi.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_vdi.c        Mon Mar 26 10:10:31 2007 -0600
@@ -555,6 +555,15 @@ bool
 bool
 xen_vdi_get_uuid(xen_session *session, char **result, xen_vdi vdi)
 {
-    *result = session->ok ? xen_strdup_((char *)vdi) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vdi }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VDI.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_vif.c
--- a/tools/libxen/src/xen_vif.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_vif.c        Mon Mar 26 10:10:31 2007 -0600
@@ -542,6 +542,15 @@ bool
 bool
 xen_vif_get_uuid(xen_session *session, char **result, xen_vif vif)
 {
-    *result = session->ok ? xen_strdup_((char *)vif) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vif }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VIF.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_vif_metrics.c
--- a/tools/libxen/src/xen_vif_metrics.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_vif_metrics.c        Mon Mar 26 10:10:31 2007 -0600
@@ -44,7 +44,10 @@ static const struct_member xen_vif_metri
           .offset = offsetof(xen_vif_metrics_record, io_read_kbs) },
         { .key = "io_write_kbs",
           .type = &abstract_type_float,
-          .offset = offsetof(xen_vif_metrics_record, io_write_kbs) }
+          .offset = offsetof(xen_vif_metrics_record, io_write_kbs) },
+        { .key = "last_updated",
+          .type = &abstract_type_datetime,
+          .offset = offsetof(xen_vif_metrics_record, last_updated) }
     };
 
 const abstract_type xen_vif_metrics_record_abstract_type_ =
@@ -143,6 +146,22 @@ xen_vif_metrics_get_io_write_kbs(xen_ses
 
 
 bool
+xen_vif_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_vif_metrics vif_metrics)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vif_metrics }
+        };
+
+    abstract_type result_type = abstract_type_datetime;
+
+    XEN_CALL_("VIF_metrics.get_last_updated");
+    return session->ok;
+}
+
+
+bool
 xen_vif_metrics_get_all(xen_session *session, struct xen_vif_metrics_set 
**result)
 {
 
@@ -157,6 +176,15 @@ bool
 bool
 xen_vif_metrics_get_uuid(xen_session *session, char **result, xen_vif_metrics 
vif_metrics)
 {
-    *result = session->ok ? xen_strdup_((char *)vif_metrics) : NULL;
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vif_metrics }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VIF_metrics.get_uuid");
     return session->ok;
 }
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_vm.c
--- a/tools/libxen/src/xen_vm.c Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_vm.c Mon Mar 26 10:10:31 2007 -0600
@@ -1594,6 +1594,22 @@ xen_vm_resume(xen_session *session, xen_
 
 
 bool
+xen_vm_set_vcpus_number_live(xen_session *session, xen_vm self, int64_t nvcpu)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = self },
+            { .type = &abstract_type_int,
+              .u.int_val = nvcpu }
+        };
+
+    xen_call_(session, "VM.set_VCPUs_number_live", param_values, 2, NULL, 
NULL);
+    return session->ok;
+}
+
+
+bool
 xen_vm_get_all(xen_session *session, struct xen_vm_set **result)
 {
 
@@ -1608,6 +1624,15 @@ bool
 bool
 xen_vm_get_uuid(xen_session *session, char **result, xen_vm vm)
 {
-    *result = session->ok ? xen_strdup_((char *)vm) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_vm_guest_metrics.c
--- a/tools/libxen/src/xen_vm_guest_metrics.c   Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_vm_guest_metrics.c   Mon Mar 26 10:10:31 2007 -0600
@@ -57,7 +57,10 @@ static const struct_member xen_vm_guest_
           .offset = offsetof(xen_vm_guest_metrics_record, networks) },
         { .key = "other",
           .type = &abstract_type_string_string_map,
-          .offset = offsetof(xen_vm_guest_metrics_record, other) }
+          .offset = offsetof(xen_vm_guest_metrics_record, other) },
+        { .key = "last_updated",
+          .type = &abstract_type_datetime,
+          .offset = offsetof(xen_vm_guest_metrics_record, last_updated) }
     };
 
 const abstract_type xen_vm_guest_metrics_record_abstract_type_ =
@@ -232,6 +235,22 @@ xen_vm_guest_metrics_get_other(xen_sessi
 
 
 bool
+xen_vm_guest_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_vm_guest_metrics vm_guest_metrics)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm_guest_metrics }
+        };
+
+    abstract_type result_type = abstract_type_datetime;
+
+    XEN_CALL_("VM_guest_metrics.get_last_updated");
+    return session->ok;
+}
+
+
+bool
 xen_vm_guest_metrics_get_all(xen_session *session, struct 
xen_vm_guest_metrics_set **result)
 {
 
@@ -246,6 +265,15 @@ bool
 bool
 xen_vm_guest_metrics_get_uuid(xen_session *session, char **result, 
xen_vm_guest_metrics vm_guest_metrics)
 {
-    *result = session->ok ? xen_strdup_((char *)vm_guest_metrics) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm_guest_metrics }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM_guest_metrics.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_vm_metrics.c
--- a/tools/libxen/src/xen_vm_metrics.c Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_vm_metrics.c Mon Mar 26 10:10:31 2007 -0600
@@ -48,7 +48,10 @@ static const struct_member xen_vm_metric
           .offset = offsetof(xen_vm_metrics_record, vcpus_number) },
         { .key = "VCPUs_utilisation",
           .type = &abstract_type_int_float_map,
-          .offset = offsetof(xen_vm_metrics_record, vcpus_utilisation) }
+          .offset = offsetof(xen_vm_metrics_record, vcpus_utilisation) },
+        { .key = "last_updated",
+          .type = &abstract_type_datetime,
+          .offset = offsetof(xen_vm_metrics_record, last_updated) }
     };
 
 const abstract_type xen_vm_metrics_record_abstract_type_ =
@@ -165,6 +168,22 @@ xen_vm_metrics_get_vcpus_utilisation(xen
 
 
 bool
+xen_vm_metrics_get_last_updated(xen_session *session, time_t *result, 
xen_vm_metrics vm_metrics)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm_metrics }
+        };
+
+    abstract_type result_type = abstract_type_datetime;
+
+    XEN_CALL_("VM_metrics.get_last_updated");
+    return session->ok;
+}
+
+
+bool
 xen_vm_metrics_get_all(xen_session *session, struct xen_vm_metrics_set 
**result)
 {
 
@@ -179,6 +198,15 @@ bool
 bool
 xen_vm_metrics_get_uuid(xen_session *session, char **result, xen_vm_metrics 
vm_metrics)
 {
-    *result = session->ok ? xen_strdup_((char *)vm_metrics) : NULL;
-    return session->ok;
-}
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm_metrics }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM_metrics.get_uuid");
+    return session->ok;
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/src/xen_vtpm.c
--- a/tools/libxen/src/xen_vtpm.c       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/src/xen_vtpm.c       Mon Mar 26 10:10:31 2007 -0600
@@ -182,6 +182,15 @@ bool
 bool
 xen_vtpm_get_uuid(xen_session *session, char **result, xen_vtpm vtpm)
 {
-    *result = session->ok ? xen_strdup_((char *)vtpm) : NULL;
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vtpm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VTPM.get_uuid");
     return session->ok;
 }
diff -r 16198b57f535 -r 56caf0e37e6a tools/libxen/test/test_bindings.c
--- a/tools/libxen/test/test_bindings.c Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/libxen/test/test_bindings.c Mon Mar 26 10:10:31 2007 -0600
@@ -17,6 +17,7 @@
  */
 
 #define _GNU_SOURCE
+#include <assert.h>
 #include <inttypes.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -33,6 +34,7 @@
 #include "xen_vm.h"
 #include "xen_vm_metrics.h"
 
+//#define PRINT_XML
 
 static void usage()
 {
@@ -61,6 +63,7 @@ typedef struct
 
 
 static xen_vm create_new_vm(xen_session *session, bool hvm);
+static void print_session_info(xen_session *session);
 static void print_vm_power_state(xen_session *session, xen_vm vm);
 static void print_vm_metrics(xen_session *session, xen_vm vm);
 
@@ -69,6 +72,11 @@ write_func(void *ptr, size_t size, size_
 write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
 {
     size_t n = size * nmemb;
+#ifdef PRINT_XML
+    printf("\n\n---Result from server -----------------------\n");
+    printf("%s\n",((char*) ptr));
+    fflush(stdout);
+#endif
     return comms->func(ptr, n, comms->handle) ? n : 0;
 }
 
@@ -78,6 +86,12 @@ call_func(const void *data, size_t len, 
           void *result_handle, xen_result_func result_func)
 {
     (void)user_handle;
+
+#ifdef PRINT_XML
+    printf("\n\n---Data to server: -----------------------\n");
+    printf("%s\n",((char*) data));
+    fflush(stdout);
+#endif
 
     CURL *curl = curl_easy_init();
     if (!curl) {
@@ -144,6 +158,14 @@ int main(int argc, char **argv)
     xen_session *session =
         xen_session_login_with_password(call_func, NULL, username, password);
 
+    print_session_info(session);
+    if (!session->ok)
+    {
+        /* Error has been logged, just clean up. */
+        CLEANUP;
+        return 1;
+    }
+
     xen_vm vm;
     if (!xen_vm_get_by_uuid(session, &vm,
                             "00000000-0000-0000-0000-000000000000"))
@@ -184,7 +206,7 @@ int main(int argc, char **argv)
     }
 
     xen_host host;
-    if (!xen_session_get_this_host(session, &host))
+    if (!xen_session_get_this_host(session, &host, session))
     {
         print_error(session);
         xen_vm_record_free(vm_record);
@@ -256,12 +278,12 @@ int main(int argc, char **argv)
 
     printf("%s.\n", vm_uuid);
 
-    fprintf(stderr, "In bytes, the VM UUID is ");
+    printf("In bytes, the VM UUID is ");
     for (int i = 0; i < 15; i++)
     {
-        fprintf(stderr, "%x, ", (unsigned int)vm_uuid_bytes[i]);
-    }
-    fprintf(stderr, "%x.\n", (unsigned int)vm_uuid_bytes[15]);
+        printf("%x, ", (unsigned int)vm_uuid_bytes[i]);
+    }
+    printf("%x.\n", (unsigned int)vm_uuid_bytes[15]);
 
     printf("%zd.\n", versions->size);
 
@@ -369,16 +391,16 @@ static xen_vm create_new_vm(xen_session 
             .name_description = hvm ? "New HVM VM" : "New PV VM",
             .user_version = 1,
             .is_a_template = false,
-            .memory_static_max = 256,
-            .memory_dynamic_max = 256,
-            .memory_dynamic_min = 128,
-            .memory_static_min = 128,
+            .memory_static_max = 256 * 1024 * 1024,
+            .memory_dynamic_max = 256 * 1024 * 1024,
+            .memory_dynamic_min = 128 * 1024 * 1024,
+            .memory_static_min = 128 * 1024 * 1024,
             .vcpus_params = vcpus_params,
             .vcpus_max = 4,
             .vcpus_at_startup = 2,
             .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
             .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
-            .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
+            .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_RESTART,
             .hvm_boot_policy = hvm ? "BIOS order" : NULL,
             .hvm_boot_params = hvm ? hvm_boot_params : NULL,
             .pv_bootloader   = hvm ? NULL : "pygrub",
@@ -403,7 +425,7 @@ static xen_vm create_new_vm(xen_session 
      * Create a new disk for the new VM.
      */
     xen_sr_set *srs;
-    if (!xen_sr_get_by_name_label(session, &srs, "Local") ||
+    if (!xen_sr_get_by_name_label(session, &srs, "QCoW") ||
         srs->size < 1)
     {
         fprintf(stderr, "SR lookup failed.\n");
@@ -519,16 +541,14 @@ static xen_vm create_new_vm(xen_session 
     }
 
     if (hvm) {
-        fprintf(stderr,
-                "Created a new HVM VM, with UUID %s, VDI UUID %s, VBD "
-                "UUID %s, and VNC console UUID %s.\n",
-                vm_uuid, vdi0_uuid, vbd0_uuid, vnc_uuid);
+        printf("Created a new HVM VM, with UUID %s, VDI UUID %s, VBD "
+               "UUID %s, and VNC console UUID %s.\n",
+               vm_uuid, vdi0_uuid, vbd0_uuid, vnc_uuid);
     }
     else {
-        fprintf(stderr,
-                "Created a new PV VM, with UUID %s, VDI UUID %s, and VBD "
-                "UUID %s.\n",
-                vm_uuid, vdi0_uuid, vbd0_uuid);
+        printf("Created a new PV VM, with UUID %s, VDI UUID %s, and VBD "
+               "UUID %s.\n",
+               vm_uuid, vdi0_uuid, vbd0_uuid);
     }
 
     xen_uuid_free(vm_uuid);
@@ -569,6 +589,58 @@ static void print_vm_power_state(xen_ses
            xen_vm_power_state_to_string(power_state));
 
     xen_uuid_free(vm_uuid);
+
+    fflush(stdout);
+}
+
+
+/**
+ * Workaround for whinging GCCs, as suggested by strftime(3).
+ */
+static size_t my_strftime(char *s, size_t max, const char *fmt,
+                          const struct tm *tm)
+{
+    return strftime(s, max, fmt, tm);
+}
+
+
+/**
+ * Print some session details.
+ */
+static void print_session_info(xen_session *session)
+{
+    xen_session_record *record;
+    if (!xen_session_get_record(session, &record, session))
+    {
+        print_error(session);
+        return;
+    }
+
+    printf("Session UUID: %s.\n", record->uuid);
+    printf("Session user: %s.\n", record->this_user);
+    char time[256];
+    struct tm *tm = localtime(&record->last_active);
+    my_strftime(time, 256, "Session last active: %c, local time.\n", tm);
+    printf(time);
+
+    char *uuid = NULL;
+    char *this_user = NULL;
+    xen_session_get_uuid(session, &uuid, session);
+    xen_session_get_this_user(session, &this_user, session);
+
+    if (!session->ok)
+    {
+        xen_session_record_free(record);
+        print_error(session);
+        return;
+    }
+
+    assert(!strcmp(record->uuid, uuid));
+    assert(!strcmp(record->this_user, this_user));
+
+    xen_session_record_free(record);
+
+    fflush(stdout);
 }
 
 
@@ -592,6 +664,11 @@ static void print_vm_metrics(xen_session
         return;
     }
 
+    char time[256];
+    struct tm *tm = localtime(&vm_metrics_record->last_updated);
+    my_strftime(time, 256, "Metrics updated at %c, local time.\n", tm);
+    printf(time);
+
     for (size_t i = 0; i < vm_metrics_record->vcpus_utilisation->size; i++)
     {
         printf("%"PRId64" -> %lf.\n",
@@ -601,4 +678,6 @@ static void print_vm_metrics(xen_session
 
     xen_vm_metrics_record_free(vm_metrics_record);
     xen_vm_metrics_free(vm_metrics);
-}
+
+    fflush(stdout);
+}
diff -r 16198b57f535 -r 56caf0e37e6a tools/misc/Makefile
--- a/tools/misc/Makefile       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/misc/Makefile       Mon Mar 26 10:10:31 2007 -0600
@@ -9,7 +9,7 @@ CFLAGS   += $(INCLUDES)
 
 HDRS     = $(wildcard *.h)
 
-TARGETS-y := xenperf xc_shadow
+TARGETS-y := xenperf
 TARGETS-$(CONFIG_X86) += xen-detect
 TARGETS := $(TARGETS-y)
 
@@ -43,5 +43,5 @@ clean:
 %.o: %.c $(HDRS) Makefile
        $(CC) -c $(CFLAGS) -o $@ $<
 
-xenperf xc_shadow: %: %.o Makefile
+xenperf: %: %.o Makefile
        $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl
diff -r 16198b57f535 -r 56caf0e37e6a tools/misc/xc_shadow.c
--- a/tools/misc/xc_shadow.c    Mon Mar 26 09:17:25 2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2005 - Rolf Neugebauer - Intel Research Cambridge
- ****************************************************************************
- *
- *        File: xc_shadow.c
- *      Author: Rolf Neugebauer (rolf.neugebauer@xxxxxxxxx)
- *        Date: Mar 2005
- * 
- * Description: 
- */
-
-
-#include <xenctrl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <string.h>
-
-void usage(void)
-{
-    printf("xc_shadow: -[0|1|2]\n");
-    printf("    set shadow mode\n");
-    exit(0);
-}
-
-int main(int argc, char *argv[])
-{
-    int xc_handle;
-    int mode = 0;
-
-    if ( argc > 1 )
-    {
-        char *p = argv[1];
-        if (*p++ == '-') {
-            if (*p == '1')
-                mode = 1;
-            else if (*p == '2')
-                mode = 2;
-            else if (*p == '0')
-                mode = 0;
-            else
-                usage();
-        } else
-            usage();
-    } 
-    else
-        usage();
-
-    if ( (xc_handle = xc_interface_open()) == -1 )
-    {
-        fprintf(stderr, "Error opening xc interface: %d (%s)\n",
-                errno, strerror(errno));
-        return 1;
-    }
-
-    if ( xc_shadow_control(xc_handle,
-                           0,
-                           mode, 
-                           NULL,
-                           0,
-                           NULL,
-                           0,
-                           NULL) < 0 )
-    {    
-        fprintf(stderr, "Error reseting performance counters: %d (%s)\n",
-                errno, strerror(errno));
-        return 1;
-    }
-    return 0;
-}
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/util/xmlrpclib2.py       Mon Mar 26 10:10:31 2007 -0600
@@ -54,9 +54,10 @@ def stringify(value):
        (isinstance(value, int) and not isinstance(value, bool)):
         return str(value)
     elif isinstance(value, dict):
+        new_value = {}
         for k, v in value.items():
-            value[k] = stringify(v)
-        return value
+            new_value[stringify(k)] = stringify(v)
+        return new_value
     elif isinstance(value, (tuple, list)):
         return [stringify(v) for v in value]
     else:
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xend/XendAPI.py  Mon Mar 26 10:10:31 2007 -0600
@@ -21,6 +21,8 @@ import sys
 import sys
 import traceback
 import threading
+import time
+import xmlrpclib
 
 from xen.xend import XendDomain, XendDomainInfo, XendNode, XendDmesg
 from xen.xend import XendLogging, XendTaskManager
@@ -76,6 +78,11 @@ def xen_api_todo():
 def xen_api_todo():
     """Temporary method to make sure we track down all the TODOs"""
     return {"Status": "Error", "ErrorDescription": XEND_ERROR_TODO}
+
+
+def now():
+    return xmlrpclib.DateTime(time.strftime("%Y%m%dT%H:%M:%S", time.gmtime()))
+
 
 # ---------------------------------------------------
 # Python Method Decorators for input value validation
@@ -516,8 +523,11 @@ class XendAPI(object):
     # ----------------------------------------------------------------
     # NOTE: Left unwrapped by __init__
 
-    session_attr_ro = ['this_host', 'this_user']
+    session_attr_ro = ['this_host', 'this_user', 'last_active']
     session_methods = [('logout', None)]
+
+    def session_get_all(self, session):
+        return xen_api_success([session])
 
     def session_login_with_password(self, *args):
         if len(args) != 2:
@@ -527,8 +537,8 @@ class XendAPI(object):
         username = args[0]
         password = args[1]
         try:
-            session = (self.auth == AUTH_NONE and
-                       auth_manager().login_unconditionally(username) or
+            session = ((self.auth == AUTH_NONE and
+                        auth_manager().login_unconditionally(username)) or
                        auth_manager().login_with_password(username, password))
             return xen_api_success(session)
         except XendError, e:
@@ -539,26 +549,40 @@ class XendAPI(object):
     def session_logout(self, session):
         auth_manager().logout(session)
         return xen_api_success_void()
-    def session_get_record(self, session):
-        record = {'uuid'     : session,
-                  'this_host': XendNode.instance().uuid,
-                  'this_user': auth_manager().get_user(session)}
+
+    def session_get_record(self, session, self_session):
+        if self_session != session:
+            return xen_api_error(['PERMISSION_DENIED'])
+        record = {'uuid'       : session,
+                  'this_host'  : XendNode.instance().uuid,
+                  'this_user'  : auth_manager().get_user(session),
+                  'last_active': now()}
         return xen_api_success(record)
 
-    def session_get_uuid(self, session):
-        return xen_api_success(session)
-
-    def session_get_by_uuid(self, session):
-        return xen_api_success(session)
+    def session_get_uuid(self, session, self_session):
+        return xen_api_success(self_session)
+
+    def session_get_by_uuid(self, session, self_session):
+        return xen_api_success(self_session)
 
     # attributes (ro)
-    def session_get_this_host(self, session):
+    def session_get_this_host(self, session, self_session):
+        if self_session != session:
+            return xen_api_error(['PERMISSION_DENIED'])
         return xen_api_success(XendNode.instance().uuid)
-    def session_get_this_user(self, session):
+
+    def session_get_this_user(self, session, self_session):
+        if self_session != session:
+            return xen_api_error(['PERMISSION_DENIED'])
         user = auth_manager().get_user(session)
-        if user:
+        if user is not None:
             return xen_api_success(user)
         return xen_api_error(['SESSION_INVALID', session])
+
+    def session_get_last_active(self, session, self_session):
+        if self_session != session:
+            return xen_api_error(['PERMISSION_DENIED'])
+        return xen_api_success(now())
 
 
     # Xen API: Class User
@@ -643,6 +667,7 @@ class XendAPI(object):
 
     host_attr_ro = ['software_version',
                     'resident_VMs',
+                    'PIFs',
                     'host_CPUs',
                     'cpu_configuration',
                     'metrics',
@@ -712,6 +737,8 @@ class XendAPI(object):
         return xen_api_success(XendNode.instance().xen_version())
     def host_get_resident_VMs(self, session, host_ref):
         return xen_api_success(XendDomain.instance().get_domain_refs())
+    def host_get_PIFs(self, session, ref):
+        return xen_api_success(XendNode.instance().get_PIF_refs())
     def host_get_host_CPUs(self, session, host_ref):
         return xen_api_success(XendNode.instance().get_host_cpu_refs())
     def host_get_metrics(self, _, ref):
@@ -847,7 +874,8 @@ class XendAPI(object):
     # ----------------------------------------------------------------
 
     host_metrics_attr_ro = ['memory_total',
-                            'memory_free']
+                            'memory_free',
+                            'last_updated']
     host_metrics_attr_rw = []
     host_metrics_methods = []
 
@@ -862,13 +890,17 @@ class XendAPI(object):
             'uuid'         : ref,
             'memory_total' : self._host_metrics_get_memory_total(),
             'memory_free'  : self._host_metrics_get_memory_free(),
+            'last_updated' : now(),
             })
 
-    def host_metrics_get_memory_total(self, _, ref):
+    def host_metrics_get_memory_total(self, _1, _2):
         return xen_api_success(self._host_metrics_get_memory_total())
 
-    def host_metrics_get_memory_free(self, _, ref):
+    def host_metrics_get_memory_free(self, _1, _2):
         return xen_api_success(self._host_metrics_get_memory_free())
+
+    def host_metrics_get_last_updated(self, _1, _2):
+        return xen_api_success(now())
 
     def _host_metrics_get_memory_total(self):
         node = XendNode.instance()
@@ -1009,7 +1041,8 @@ class XendAPI(object):
     # ----------------------------------------------------------------
 
     PIF_metrics_attr_ro = ['io_read_kbs',
-                           'io_write_kbs']
+                           'io_write_kbs',
+                           'last_updated']
     PIF_metrics_attr_rw = []
     PIF_methods = []
 
@@ -1028,15 +1061,15 @@ class XendAPI(object):
     def PIF_metrics_get_io_write_kbs(self, _, ref):
         return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
 
+    def PIF_metrics_get_last_updated(self, _1, _2):
+        return xen_api_success(now())
+
 
     # Xen API: Class VM
     # ----------------------------------------------------------------        
 
     VM_attr_ro = ['power_state',
                   'resident_on',
-                  'memory_static_max',                  
-                  'memory_static_min',
-                  'VCPUs_number',
                   'consoles',
                   'VIFs',
                   'VBDs',
@@ -1054,6 +1087,10 @@ class XendAPI(object):
                   'auto_power_on',
                   'memory_dynamic_max',
                   'memory_dynamic_min',
+                  'memory_static_max',
+                  'memory_static_min',
+                  'VCPUs_max',
+                  'VCPUs_at_startup',
                   'VCPUs_params',
                   'actions_after_shutdown',
                   'actions_after_reboot',
@@ -1081,17 +1118,23 @@ class XendAPI(object):
                   ('suspend', None),
                   ('resume', None),
                   ('send_sysrq', None),
+                  ('set_VCPUs_number_live', None),
                   ('add_to_HVM_boot_params', None),
                   ('remove_from_HVM_boot_params', None),
                   ('add_to_VCPUs_params', None),
+                  ('add_to_VCPUs_params_live', None),
                   ('remove_from_VCPUs_params', None),
                   ('add_to_platform', None),
                   ('remove_from_platform', None),
                   ('add_to_other_config', None),
                   ('remove_from_other_config', None),
+                  ('save', None),
+                  ('set_memory_dynamic_max_live', None),
+                  ('set_memory_dynamic_min_live', None),
                   ('send_trigger', None)]
     
     VM_funcs  = [('create', 'VM'),
+                 ('restore', None),
                  ('get_by_name_label', 'Set(VM)')]
 
     # parameters required for _create()
@@ -1104,6 +1147,8 @@ class XendAPI(object):
         'memory_dynamic_max',
         'memory_dynamic_min',
         'memory_static_min',
+        'VCPUs_max',
+        'VCPUs_at_startup',
         'VCPUs_params',
         'actions_after_shutdown',
         'actions_after_reboot',
@@ -1150,10 +1195,6 @@ class XendAPI(object):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_memory_static_min())
     
-    def VM_get_VCPUs_number(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success(dom.getVCpuCount())
-    
     def VM_get_VIFs(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_vifs())
@@ -1177,6 +1218,14 @@ class XendAPI(object):
     def VM_get_metrics(self, _, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_metrics())
+
+    def VM_get_VCPUs_max(self, _, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
+
+    def VM_get_VCPUs_at_startup(self, _, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_todo()
 
     # attributes (rw)
     def VM_get_name_label(self, session, vm_ref):
@@ -1191,9 +1240,8 @@ class XendAPI(object):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo()
     
-    def VM_get_is_a_template(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
+    def VM_get_is_a_template(self, session, ref):
+        return self.VM_get('is_a_template', session, ref)
     
     def VM_get_memory_dynamic_max(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -1286,12 +1334,38 @@ class XendAPI(object):
     
     def VM_set_memory_dynamic_max(self, session, vm_ref, mem):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
+        dom.set_memory_dynamic_max(int(mem))
+        return xen_api_success_void()
+
     def VM_set_memory_dynamic_min(self, session, vm_ref, mem):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo()
-    
+        dom.set_memory_dynamic_min(int(mem))
+        return xen_api_success_void()
+
+    def VM_set_memory_static_max(self, session, vm_ref, mem):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        dom.set_memory_static_max(int(mem))
+        return xen_api_success_void()
+    
+    def VM_set_memory_static_min(self, session, vm_ref, mem):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        dom.set_memory_static_min(int(mem))
+        return xen_api_success_void()
+
+    def VM_set_memory_dynamic_max_live(self, session, vm_ref, mem):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        dom.set_memory_dynamic_max(int(mem))
+        # need to pass target as MiB
+        dom.setMemoryTarget(int(mem)/1024/1024)
+        return xen_api_success_void()
+
+    def VM_set_memory_dynamic_min_live(self, session, vm_ref, mem):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        dom.set_memory_dynamic_min(int(mem))
+        # need to pass target as MiB
+        dom.setMemoryTarget(int(mem)/1024/1024)
+        return xen_api_success_void()
+
     def VM_set_VCPUs_params(self, session, vm_ref, value):
         return self.VM_set('vcpus_params', session, vm_ref, value)
 
@@ -1302,6 +1376,36 @@ class XendAPI(object):
         dom.info['vcpus_params'][key] = value
         return self._VM_save(dom)
 
+    def VM_add_to_VCPUs_params_live(self, session, vm_ref, key, value):
+        self.VM_add_to_VCPUs_params(session, vm_ref, key, value)
+        self._VM_VCPUs_params_refresh(vm_ref)
+        return xen_api_success_void()
+
+    def _VM_VCPUs_params_refresh(self, vm_ref):
+        xendom  = XendDomain.instance()
+        xeninfo = xendom.get_vm_by_uuid(vm_ref)
+
+        #update the cpumaps
+        for key, value in xeninfo.info['vcpus_params'].items():
+            if key.startswith("cpumap"):
+                vcpu = int(key[6:])
+                try:
+                    xendom.domain_pincpu(xeninfo.getDomid(), vcpu, value)
+                except Exception, ex:
+                    log.exception(ex)
+
+        #need to update sched params aswell
+        if 'weight' in xeninfo.info['vcpus_params'] \
+           and 'cap' in xeninfo.info['vcpus_params']:
+            weight = xeninfo.info['vcpus_params']['weight']
+            cap = xeninfo.info['vcpus_params']['cap']
+            xendom.domain_sched_credit_set(xeninfo.getDomid(), weight, cap)
+
+    def VM_set_VCPUs_number_live(self, _, vm_ref, num):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        dom.setVCpuCount(int(num))
+        return xen_api_success_void()
+     
     def VM_remove_from_VCPUs_params(self, session, vm_ref, key):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         if 'vcpus_params' in dom.info \
@@ -1442,7 +1546,7 @@ class XendAPI(object):
             'name_label': xeninfo.getName(),
             'name_description': xeninfo.getName(),
             'user_version': 1,
-            'is_a_template': False,
+            'is_a_template': xeninfo.info['is_a_template'],
             'auto_power_on': False,
             'resident_on': XendNode.instance().uuid,
             'memory_static_min': xeninfo.get_memory_static_min(),
@@ -1450,7 +1554,8 @@ class XendAPI(object):
             'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
             'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
             'VCPUs_params': xeninfo.get_vcpus_params(),
-            'VCPUs_number': xeninfo.getVCpuCount(),
+            'VCPUs_at_startup': xeninfo.getVCpuCount(),
+            'VCPUs_max': xeninfo.getVCpuCount(),
             'actions_after_shutdown': xeninfo.get_on_shutdown(),
             'actions_after_reboot': xeninfo.get_on_reboot(),
             'actions_after_suspend': xeninfo.get_on_suspend(),
@@ -1471,7 +1576,8 @@ class XendAPI(object):
             'tools_version': xeninfo.get_tools_version(),
             'other_config': xeninfo.info.get('other_config', {}),
             'domid': domid is None and -1 or domid,
-            'is_control_domain': xeninfo == xendom.privilegedDomain(),
+            'is_control_domain': xeninfo.info['is_control_domain'],
+            'metrics': xeninfo.get_metrics()
         }
         return xen_api_success(record)
 
@@ -1541,14 +1647,31 @@ class XendAPI(object):
         xeninfo = xendom.get_vm_by_uuid(vm_ref)
         xendom.domain_send_trigger(xeninfo.getDomid(), trigger, vcpu)
         return xen_api_success_void()
-        
+
+    def VM_save(self, _, vm_ref, dest, checkpoint):
+        xendom = XendDomain.instance()
+        xeninfo = xendom.get_vm_by_uuid(vm_ref)
+        xendom.domain_save(xeninfo.getDomid(), dest, checkpoint)
+        return xen_api_success_void()
+
+    def VM_restore(self, _, src, paused):
+        xendom = XendDomain.instance()
+        xendom.domain_restore(src, bool(paused))
+        return xen_api_success_void()
+
 
     # Xen API: Class VM_metrics
     # ----------------------------------------------------------------
 
     VM_metrics_attr_ro = ['memory_actual',
-                           'vcpus_number',
-                           'vcpus_utilisation']
+                          'VCPUs_number',
+                          'VCPUs_utilisation',
+                          'VCPUs_CPU',
+                          'VCPUs_flags',
+                          'VCPUs_params',
+                          'state',
+                          'start_time',
+                          'last_updated']
     VM_metrics_attr_rw = []
     VM_metrics_methods = []
 
@@ -1564,11 +1687,30 @@ class XendAPI(object):
     def VM_metrics_get_memory_actual(self, _, ref):
         return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
 
-    def VM_metrics_get_vcpus_number(self, _, ref):
-        return xen_api_success(self._VM_metrics_get(ref).get_vcpus_number())
-
-    def VM_metrics_get_vcpus_utilisation(self, _, ref):
-        return 
xen_api_success(self._VM_metrics_get(ref).get_vcpus_utilisation())
+    def VM_metrics_get_VCPUs_number(self, _, ref):
+        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_number())
+
+    def VM_metrics_get_VCPUs_utilisation(self, _, ref):
+        return 
xen_api_success(self._VM_metrics_get(ref).get_VCPUs_utilisation())
+
+    def VM_metrics_get_VCPUs_CPU(self, _, ref):
+        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_CPU())
+    
+    def VM_metrics_get_VCPUs_flags(self, _, ref):
+        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_flags())
+
+    def VM_metrics_get_VCPUs_params(self, _, ref):
+        return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_params())
+
+    def VM_metrics_get_start_time(self, _, ref):
+        return xen_api_success(self._VM_metrics_get(ref).get_start_time())
+
+    def VM_metrics_get_state(self, _, ref):
+        return xen_api_success(self._VM_metrics_get(ref).get_state())
+
+    def VM_metrics_get_last_updated(self, _1, _2):
+        return xen_api_success(now())
+
 
     # Xen API: Class VBD
     # ----------------------------------------------------------------
@@ -1723,7 +1865,8 @@ class XendAPI(object):
     # ----------------------------------------------------------------
 
     VBD_metrics_attr_ro = ['io_read_kbs',
-                           'io_write_kbs']
+                           'io_write_kbs',
+                           'last_updated']
     VBD_metrics_attr_rw = []
     VBD_methods = []
 
@@ -1733,13 +1876,18 @@ class XendAPI(object):
             return xen_api_error(['HANDLE_INVALID', 'VBD_metrics', ref])
         return xen_api_success(
             { 'io_read_kbs'  : vm.get_dev_property('vbd', ref, 'io_read_kbs'),
-              'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs') 
})
+              'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs'),
+              'last_updated' : now()
+            })
 
     def VBD_metrics_get_io_read_kbs(self, _, ref):
         return self._VBD_get(ref, 'io_read_kbs')
     
     def VBD_metrics_get_io_write_kbs(self, session, ref):
         return self._VBD_get(ref, 'io_write_kbs')
+
+    def VBD_metrics_get_last_updated(self, _1, _2):
+        return xen_api_success(now())
 
 
     # Xen API: Class VIF
@@ -1857,7 +2005,8 @@ class XendAPI(object):
     # ----------------------------------------------------------------
 
     VIF_metrics_attr_ro = ['io_read_kbs',
-                           'io_write_kbs']
+                           'io_write_kbs',
+                           'last_updated']
     VIF_metrics_attr_rw = []
     VIF_methods = []
 
@@ -1867,13 +2016,18 @@ class XendAPI(object):
             return xen_api_error(['HANDLE_INVALID', 'VIF_metrics', ref])
         return xen_api_success(
             { 'io_read_kbs'  : vm.get_dev_property('vif', ref, 'io_read_kbs'),
-              'io_write_kbs' : vm.get_dev_property('vif', ref, 'io_write_kbs') 
})
+              'io_write_kbs' : vm.get_dev_property('vif', ref, 'io_write_kbs'),
+              'last_updated' : now()
+            })
 
     def VIF_metrics_get_io_read_kbs(self, _, ref):
         return self._VIF_get(ref, 'io_read_kbs')
     
     def VIF_metrics_get_io_write_kbs(self, session, ref):
         return self._VIF_get(ref, 'io_write_kbs')
+
+    def VIF_metrics_get_last_updated(self, _1, _2):
+        return xen_api_success(now())
 
 
     # Xen API: Class VDI
@@ -2347,39 +2501,3 @@ class XendAPIAsyncProxy:
                                                 synchronous_method_name,
                                                 session)
         return xen_api_success(task_uuid)
-
-#   
-# Auto generate some stubs based on XendAPI introspection
-#
-if __name__ == "__main__":
-    def output(line):
-        print '    ' + line
-    
-    classes = ['VDI', 'SR']
-    for cls in classes:
-        ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
-        rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
-        methods  = getattr(XendAPI, '%s_methods' % cls, [])
-        funcs    = getattr(XendAPI, '%s_funcs' % cls, [])
-
-        ref = '%s_ref' % cls
-
-        for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
-            getter_name = '%s_get_%s' % (cls, attr_name)
-            output('def %s(self, session, %s):' % (getter_name, ref))
-            output('    return xen_api_todo()')
-
-        for attr_name in rw_attrs + XendAPI.Base_attr_rw:
-            setter_name = '%s_set_%s' % (cls, attr_name)
-            output('def %s(self, session, %s, value):' % (setter_name, ref))
-            output('    return xen_api_todo()')
-
-        for method_name in methods + XendAPI.Base_methods:
-            method_full_name = '%s_%s' % (cls,method_name)
-            output('def %s(self, session, %s):' % (method_full_name, ref))
-            output('    return xen_api_todo()')
-
-        for func_name in funcs + XendAPI.Base_funcs:
-            func_full_name = '%s_%s' % (cls, func_name)
-            output('def %s(self, session):' % func_full_name)
-            output('    return xen_api_todo()')
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xend/XendConfig.py       Mon Mar 26 10:10:31 2007 -0600
@@ -44,7 +44,7 @@ def reverse_dict(adict):
     return dict([(v, k) for k, v in adict.items()])
 
 def bool0(v):
-    return v != '0' and bool(v)
+    return v != '0' and v != 'False' and bool(v)
 
 # Recursively copy a data struct, scrubbing out VNC passwords.
 # Will scrub any dict entry with a key of 'vncpasswd' or any
@@ -81,18 +81,18 @@ def scrub_password(data):
 #
 # CPU fields:
 #
-# vcpus_number -- the maximum number of vcpus that this domain may ever have.
+# VCPUs_max    -- the maximum number of vcpus that this domain may ever have.
 #                 aka XendDomainInfo.getVCpuCount().
 # vcpus        -- the legacy configuration name for above.
 # max_vcpu_id  -- vcpus_number - 1.  This is given to us by Xen.
 #
 # cpus         -- the list of pCPUs available to each vCPU.
 #
-#   vcpu_avail:  a bitmap telling the guest domain whether it may use each of
-#                its VCPUs.  This is translated to
-#                <dompath>/cpu/<id>/availability = {online,offline} for use
-#                by the guest domain.
-# online_vpcus -- the number of VCPUs currently up, as reported by Xen.  This
+# vcpu_avail   -- a bitmap telling the guest domain whether it may use each of
+#                 its VCPUs.  This is translated to
+#                 <dompath>/cpu/<id>/availability = {online,offline} for use
+#                 by the guest domain.
+# VCPUs_live   -- the number of VCPUs currently up, as reported by Xen.  This
 #                 is changed by changing vcpu_avail, and waiting for the
 #                 domain to respond.
 #
@@ -103,7 +103,7 @@ def scrub_password(data):
 
 XENAPI_CFG_TO_LEGACY_CFG = {
     'uuid': 'uuid',
-    'vcpus_number': 'vcpus',
+    'VCPUs_max': 'vcpus',
     'cpus': 'cpus',
     'name_label': 'name',
     'actions_after_shutdown': 'on_poweroff',
@@ -128,7 +128,6 @@ XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 
 
 XENAPI_CFG_TYPES = {
     'uuid': str,
-    'power_state': str,
     'name_label': str,
     'name_description': str,
     'user_version': str,
@@ -139,9 +138,10 @@ XENAPI_CFG_TYPES = {
     'memory_dynamic_min': int,
     'memory_dynamic_max': int,
     'cpus': list,
-    'vcpus_policy': str,
     'vcpus_params': dict,
-    'vcpus_number': int,
+    'VCPUs_max': int,
+    'VCPUs_at_startup': int,
+    'VCPUs_live': int,
     'actions_after_shutdown': str,
     'actions_after_reboot': str,
     'actions_after_crash': str,
@@ -269,7 +269,7 @@ class XendConfig(dict):
             self.update_with_xenapi_config(xapi)
         elif dominfo:
             # output from xc.domain_getinfo
-            self._dominfo_to_xapi(dominfo)
+            self._dominfo_to_xapi(dominfo, update_mem = True)
 
         log.debug('XendConfig.init: %s' % scrub_password(self))
 
@@ -298,6 +298,8 @@ class XendConfig(dict):
             'actions_after_reboot': 'restart',
             'actions_after_crash': 'restart',
             'actions_after_suspend': '',
+            'is_template': False,
+            'is_control_domain': False,
             'features': '',
             'PV_bootloader': '',
             'PV_kernel': '',
@@ -318,7 +320,9 @@ class XendConfig(dict):
             'cpus': [],
             'cpu_weight': 256,
             'cpu_cap': 0,
-            'vcpus_number': 1,
+            'VCPUs_max': 1,
+            'VCPUs_live': 1,
+            'VCPUs_at_startup': 1,
             'vcpus_params': {},
             'console_refs': [],
             'vif_refs': [],
@@ -371,8 +375,8 @@ class XendConfig(dict):
                                       event)
 
     def _vcpus_sanity_check(self):
-        if 'vcpus_number' in self and 'vcpu_avail' not in self:
-            self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
+        if 'VCPUs_max' in self and 'vcpu_avail' not in self:
+            self['vcpu_avail'] = (1 << self['VCPUs_max']) - 1
 
     def _uuid_sanity_check(self):
         """Make sure UUID is in proper string format with hyphens."""
@@ -403,15 +407,17 @@ class XendConfig(dict):
         self._vcpus_sanity_check()
         self._platform_sanity_check()
 
-    def _dominfo_to_xapi(self, dominfo):
+    def _dominfo_to_xapi(self, dominfo, update_mem = False):
         self['domid'] = dominfo['domid']
         self['online_vcpus'] = dominfo['online_vcpus']
-        self['vcpus_number'] = dominfo['max_vcpu_id'] + 1
-
-        self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024
-        self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024
-        self['memory_static_min'] = 0
-        self['memory_static_max'] = dominfo['maxmem_kb'] * 1024
+        self['VCPUs_max'] = dominfo['max_vcpu_id'] + 1
+
+        if update_mem:
+            self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024
+            self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024
+            self['memory_static_min'] = 0
+            self['memory_static_max'] = dominfo['maxmem_kb'] * 1024
+            self._memory_sanity_check()
 
         self['cpu_time'] = dominfo['cpu_time']/1e9
         # TODO: i don't know what the security stuff expects here
@@ -562,12 +568,12 @@ class XendConfig(dict):
             image_vcpus = sxp.child_value(image_sxp, 'vcpus')
             if image_vcpus != None:
                 try:
-                    if 'vcpus_number' not in cfg:
-                        cfg['vcpus_number'] = int(image_vcpus)
-                    elif cfg['vcpus_number'] != int(image_vcpus):
-                        cfg['vcpus_number'] = int(image_vcpus)
+                    if 'VCPUs_max' not in cfg:
+                        cfg['VCPUs_max'] = int(image_vcpus)
+                    elif cfg['VCPUs_max'] != int(image_vcpus):
+                        cfg['VCPUs_max'] = int(image_vcpus)
                         log.warn('Overriding vcpus from %d to %d using image'
-                                 'vcpus value.', cfg['vcpus_number'])
+                                 'vcpus value.', cfg['VCPUs_max'])
                 except ValueError, e:
                     raise XendConfigError('integer expeceted: %s: %s' %
                                           image_sxp, e)
@@ -850,16 +856,6 @@ class XendConfig(dict):
 
         sxpr.append(["maxmem", int(self["memory_static_max"])/MiB])
         sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
-
-        if not legacy_only:
-            sxpr.append(['memory_dynamic_min',
-                     int(self.get('memory_dynamic_min'))])
-            sxpr.append(['memory_dynamic_max',
-                     int(self.get('memory_dynamic_max'))])
-            sxpr.append(['memory_static_max',
-                     int(self.get('memory_static_max'))])
-            sxpr.append(['memory_static_min',
-                     int(self.get('memory_static_min'))])
 
         for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
             if legacy in ('domid', 'uuid'): # skip these
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xend/XendDomain.py       Mon Mar 26 10:10:31 2007 -0600
@@ -34,7 +34,7 @@ import xen.lowlevel.xc
 
 from xen.xend import XendOptions, XendCheckpoint, XendDomainInfo
 from xen.xend.PrettyPrint import prettyprint
-from xen.xend.XendConfig import XendConfig
+from xen.xend import XendConfig
 from xen.xend.XendError import XendError, XendInvalidDomain, VmError
 from xen.xend.XendError import VMBadState
 from xen.xend.XendLogging import log
@@ -191,6 +191,10 @@ class XendDomain:
                         self._managed_domain_register(new_dom)
                     else:
                         self._managed_domain_register(running_dom)
+                        for key in XendConfig.XENAPI_CFG_TYPES.keys():
+                            if key not in XendConfig.LEGACY_XENSTORE_VM_PARAMS 
and \
+                                   key in dom:
+                                running_dom.info[key] = dom[key]
                 except Exception:
                     log.exception("Failed to create reference to managed "
                                   "domain: %s" % dom_name)
@@ -316,7 +320,7 @@ class XendDomain:
         for dom_uuid in dom_uuids:
             try:
                 cfg_file = self._managed_config_path(dom_uuid)
-                cfg = XendConfig(filename = cfg_file)
+                cfg = XendConfig.XendConfig(filename = cfg_file)
                 if cfg.get('uuid') != dom_uuid:
                     # something is wrong with the SXP
                     log.error("UUID mismatch in stored configuration: %s" %
@@ -414,7 +418,7 @@ class XendDomain:
         running_domids = [d['domid'] for d in running if d['dying'] != 1]
         for domid, dom in self.domains.items():
             if domid not in running_domids and domid != DOM0_ID:
-                self.remove_domain(dom, domid)
+                self._remove_domain(dom, domid)
 
 
     def add_domain(self, info):
@@ -433,6 +437,16 @@ class XendDomain:
             self._managed_domain_register(info)
 
     def remove_domain(self, info, domid = None):
+        """Remove the domain from the list of running domains, taking the
+        domains_lock first.
+        """
+        self.domains_lock.acquire()
+        try:
+            self._remove_domain(info, domid)
+        finally:
+            self.domains_lock.release()
+
+    def _remove_domain(self, info, domid = None):
         """Remove the domain from the list of running domains
         
         @requires: Expects to be protected by the domains_lock.
@@ -639,14 +653,16 @@ class XendDomain:
     def get_dev_property_by_uuid(self, klass, dev_uuid, field):
         value = None
         self.domains_lock.acquire()
-        try:
-            dom = self.get_vm_with_dev_uuid(klass, dev_uuid)
-            if dom:
-                value = dom.get_dev_property(klass, dev_uuid, field)
-        except ValueError, e:
-            pass
-
-        self.domains_lock.release()
+
+        try:
+            try:
+                dom = self.get_vm_with_dev_uuid(klass, dev_uuid)
+                if dom:
+                    value = dom.get_dev_property(klass, dev_uuid, field)
+            except ValueError, e:
+                pass
+        finally:
+            self.domains_lock.release()
         
         return value
 
@@ -683,7 +699,7 @@ class XendDomain:
         self.domains_lock.acquire()
         try:
             try:
-                xeninfo = XendConfig(xapi = xenapi_vm)
+                xeninfo = XendConfig.XendConfig(xapi = xenapi_vm)
                 dominfo = XendDomainInfo.createDormant(xeninfo)
                 log.debug("Creating new managed domain: %s: %s" %
                           (dominfo.getName(), dominfo.get_uuid()))
@@ -906,7 +922,7 @@ class XendDomain:
         self.domains_lock.acquire()
         try:
             try:
-                domconfig = XendConfig(sxp_obj = config)
+                domconfig = XendConfig.XendConfig(sxp_obj = config)
                 dominfo = XendDomainInfo.createDormant(domconfig)
                 log.debug("Creating new managed domain: %s" %
                           dominfo.getName())
@@ -971,18 +987,34 @@ class XendDomain:
                     raise VMBadState("Domain is still running",
                                      POWER_STATE_NAMES[DOM_STATE_HALTED],
                                      POWER_STATE_NAMES[dominfo.state])
-
-                log.info("Domain %s (%s) deleted." %
-                         (dominfo.getName(), dominfo.info.get('uuid')))
-
-                self._managed_domain_unregister(dominfo)
-                self.remove_domain(dominfo)
-                XendDevices.destroy_device_state(dominfo)
+                
+                self._domain_delete_by_info(dominfo)
             except Exception, ex:
                 raise XendError(str(ex))
         finally:
             self.domains_lock.release()
-        
+
+
+    def domain_delete_by_dominfo(self, dominfo):
+        """Only for use by XendDomainInfo.
+        """
+        self.domains_lock.acquire()
+        try:
+            self._domain_delete_by_info(dominfo)
+        finally:
+            self.domains_lock.release()
+
+
+    def _domain_delete_by_info(self, dominfo):
+        """Expects to be protected by domains_lock.
+        """
+        log.info("Domain %s (%s) deleted." %
+                 (dominfo.getName(), dominfo.info.get('uuid')))
+                
+        self._managed_domain_unregister(dominfo)
+        self._remove_domain(dominfo)
+        XendDevices.destroy_device_state(dominfo)
+
 
     def domain_configure(self, config):
         """Configure an existing domain.
@@ -1230,7 +1262,9 @@ class XendDomain:
             try:
                 rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap)
             except Exception, ex:
-                raise XendError(str(ex))
+                log.exception(ex)
+                raise XendError("Cannot pin vcpu: %s to cpu: %s - %s" % \
+                                (v, cpumap, str(ex)))
         return rc
 
     def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Mar 26 10:10:31 2007 -0600
@@ -127,6 +127,8 @@ def recreate(info, priv):
     assert not info['dying']
 
     xeninfo = XendConfig.XendConfig(dominfo = info)
+    xeninfo['is_control_domain'] = priv
+    xeninfo['is_a_template'] = False
     domid = xeninfo['domid']
     uuid1 = uuid.fromString(xeninfo['uuid'])
     needs_reinitialising = False
@@ -614,9 +616,9 @@ class XendDomainInfo:
             sxpr = ['domain',
                     ['domid',      self.domid],
                     ['name',       self.info['name_label']],
-                    ['vcpu_count', self.info['vcpus_number']]]
-
-            for i in range(0, self.info['vcpus_number']):
+                    ['vcpu_count', self.info['VCPUs_max']]]
+
+            for i in range(0, self.info['VCPUs_max']):
                 info = xc.vcpu_getinfo(self.domid, i)
 
                 sxpr.append(['vcpu',
@@ -660,7 +662,6 @@ class XendDomainInfo:
         vm_config = dict(zip(augment_entries, vm_config))
         
         for arg in augment_entries:
-            xapicfg = arg
             val = vm_config[arg]
             if val != None:
                 if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
@@ -678,7 +679,7 @@ class XendDomainInfo:
         # settings to take precedence over any entries in the store.
         if priv:
             xeninfo = dom_get(self.domid)
-            self.info['vcpus_number'] = xeninfo['online_vcpus']
+            self.info['VCPUs_max'] = xeninfo['online_vcpus']
             self.info['vcpu_avail'] = (1 << xeninfo['online_vcpus']) - 1
 
         # read image value
@@ -831,7 +832,7 @@ class XendDomainInfo:
                 return 'offline'
 
         result = {}
-        for v in range(0, self.info['vcpus_number']):
+        for v in range(0, self.info['VCPUs_max']):
             result["cpu/%d/availability" % v] = availability(v)
         return result
 
@@ -952,7 +953,7 @@ class XendDomainInfo:
         return self.info['features']
 
     def getVCpuCount(self):
-        return self.info['vcpus_number']
+        return self.info['VCPUs_max']
 
     def setVCpuCount(self, vcpus):
         if vcpus <= 0:
@@ -964,16 +965,16 @@ class XendDomainInfo:
             # update dom differently depending on whether we are adjusting
             # vcpu number up or down, otherwise _vcpuDomDetails does not
             # disable the vcpus
-            if self.info['vcpus_number'] > vcpus:
+            if self.info['VCPUs_max'] > vcpus:
                 # decreasing
                 self._writeDom(self._vcpuDomDetails())
-                self.info['vcpus_number'] = vcpus
+                self.info['VCPUs_live'] = vcpus
             else:
                 # same or increasing
-                self.info['vcpus_number'] = vcpus
+                self.info['VCPUs_live'] = vcpus
                 self._writeDom(self._vcpuDomDetails())
         else:
-            self.info['vcpus_number'] = vcpus
+            self.info['VCPUs_live'] = vcpus
             xen.xend.XendDomain.instance().managed_config_save(self)
         log.info("Set VCPU count on domain %s to %d", self.info['name_label'],
                  vcpus)
@@ -1427,7 +1428,7 @@ class XendDomainInfo:
         self._recreateDom()
 
         # Set maximum number of vcpus in domain
-        xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number']))
+        xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
 
         # register the domain in the list 
         from xen.xend import XendDomain
@@ -1464,7 +1465,7 @@ class XendDomainInfo:
             # this is done prior to memory allocation to aide in memory
             # distribution for NUMA systems.
             if self.info['cpus'] is not None and len(self.info['cpus']) > 0:
-                for v in range(0, self.info['vcpus_number']):
+                for v in range(0, self.info['VCPUs_max']):
                     xc.vcpu_setaffinity(self.domid, v, self.info['cpus'])
 
             # Use architecture- and image-specific calculations to determine
@@ -1651,6 +1652,12 @@ class XendDomainInfo:
 
         self._cleanup_phantom_devs(paths)
 
+        if "transient" in self.info["other_config"] \
+           and bool(self.info["other_config"]["transient"]):
+            from xen.xend import XendDomain
+            XendDomain.instance().domain_delete_by_dominfo(self)
+
+
     def destroyDomain(self):
         log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
 
@@ -1662,25 +1669,16 @@ class XendDomainInfo:
                 self.domid = None
                 for state in DOM_STATES_OLD:
                     self.info[state] = 0
+                self._stateSet(DOM_STATE_HALTED)
         except:
             log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
 
         from xen.xend import XendDomain
-
-        if "transient" in self.info["other_config"]\
-           and bool(self.info["other_config"]["transient"]):
-            xendDomainInstance = XendDomain.instance()
-            
-            xendDomainInstance.domains_lock.acquire()
-            xendDomainInstance._refresh(refresh_shutdown = False)
-            xendDomainInstance.domains_lock.release()
-            
-            xendDomainInstance.domain_delete(self.info["name_label"])
-        else:
-            XendDomain.instance().remove_domain(self)
+        XendDomain.instance().remove_domain(self)
 
         self.cleanupDomain()
         self._cleanup_phantom_devs(paths)
+
 
     def resumeDomain(self):
         log.debug("XendDomainInfo.resumeDomain(%s)", str(self.domid))
@@ -1860,7 +1858,7 @@ class XendDomainInfo:
         if arch.type == "x86":
             # 1MB per vcpu plus 4Kib/Mib of RAM.  This is higher than 
             # the minimum that Xen would allocate if no value were given.
-            overhead_kb = self.info['vcpus_number'] * 1024 + \
+            overhead_kb = self.info['VCPUs_max'] * 1024 + \
                           (self.info['memory_static_max'] / 1024 / 1024) * 4
             overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
             # The domain might already have some shadow memory
@@ -2082,6 +2080,16 @@ class XendDomainInfo:
         return self.info.get('memory_dynamic_max', 0)
     def get_memory_dynamic_min(self):
         return self.info.get('memory_dynamic_min', 0)
+
+    def set_memory_static_max(self, val):
+        self.info['memory_static_max'] = val
+    def set_memory_static_min(self, val):
+        self.info['memory_static_min'] = val
+    def set_memory_dynamic_max(self, val):
+        self.info['memory_dynamic_max'] = val
+    def set_memory_dynamic_min(self, val):
+        self.info['memory_dynamic_min'] = val
+    
     def get_vcpus_params(self):
         if self.getDomid() is None:
             return self.info['vcpus_params']
@@ -2258,8 +2266,8 @@ class XendDomainInfo:
     def get_vcpus_util(self):
         vcpu_util = {}
         xennode = XendNode.instance()
-        if 'vcpus_number' in self.info and self.domid != None:
-            for i in range(0, self.info['vcpus_number']):
+        if 'VCPUs_max' in self.info and self.domid != None:
+            for i in range(0, self.info['VCPUs_max']):
                 util = xennode.get_vcpu_util(self.domid, i)
                 vcpu_util[str(i)] = util
                 
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xend/XendNode.py Mon Mar 26 10:10:31 2007 -0600
@@ -215,6 +215,10 @@ class XendNode:
         self.save_networks()
 
 
+    def get_PIF_refs(self):
+        return self.pifs.keys()
+
+
     def _PIF_create(self, name, mtu, vlan, mac, network, persist = True,
                     pif_uuid = None, metrics_uuid = None):
         for pif in self.pifs.values():
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xend/XendPIFMetrics.py
--- a/tools/python/xen/xend/XendPIFMetrics.py   Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xend/XendPIFMetrics.py   Mon Mar 26 10:10:31 2007 -0600
@@ -40,8 +40,10 @@ class XendPIFMetrics:
         return 0.0
 
     def get_record(self):
+        import xen.xend.XendAPI as XendAPI
         return {'uuid'         : self.uuid,
                 'PIF'          : self.pif.uuid,
                 'io_read_kbs'  : self.get_io_read_kbs(),
-                'io_write_kbs' : self.get_io_write_kbs()
+                'io_write_kbs' : self.get_io_write_kbs(),
+                'last_updated' : XendAPI.now(),
                 }
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/python/xen/xend/XendQCoWStorageRepo.py
--- a/tools/python/xen/xend/XendQCoWStorageRepo.py      Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/python/xen/xend/XendQCoWStorageRepo.py      Mon Mar 26 10:10:31 
2007 -0600
@@ -208,7 +208,8 @@ class XendQCoWStorageRepo(XendStorageRep
         self.lock.acquire()
         try:
             if not self._has_space_available_for(desired_size_bytes):
-                raise XendError("Not enough space")
+                raise XendError("Not enough space (need %d)" %
+                                desired_size_bytes)
 
             image_uuid = uuid.createString()
             qcow_path = os.path.join(self.location,
@@ -251,6 +252,7 @@ class XendQCoWStorageRepo(XendStorageRep
                 except OSError:
                     log.exception("Failed to destroy image")
                 del self.images[image_uuid]
+                self._refresh()
                 return True
         finally:
             self.lock.release()
@@ -317,15 +319,12 @@ class XendQCoWStorageRepo(XendStorageRep
     def create_vdi(self, vdi_struct):
         image_uuid = None
         try:
-            sector_count = int(vdi_struct.get('virtual_size', 0))
-            sector_size = int(vdi_struct.get('sector_size', 1024))
-            size_bytes = (sector_count * sector_size)
+            size_bytes = int(vdi_struct.get('virtual_size', 0))
 
             image_uuid = self._create_image_files(size_bytes)
             
             image = self.images[image_uuid]
             image_cfg = {
-                'sector_size': sector_size,
                 'virtual_size': size_bytes,
                 'type': vdi_struct.get('type', 'system'),
                 'name_label': vdi_struct.get('name_label', ''),
@@ -350,17 +349,3 @@ class XendQCoWStorageRepo(XendStorageRep
             raise
 
         return image_uuid
-
-
-# remove everything below this line!! for testing only
-if __name__ == "__main__":
-    xsr = XendStorageRepository()
-    print 'Free Space: %d MB' % (xsr.free_space_bytes()/MB)
-    print "Create Image:",
-    print xsr._create_image_files(10 * MB)
-    print 'Delete all images:'
-    for image_uuid in xsr.list_images():
-        print image_uuid,
-        xsr._destroy_image_files(image_uuid)
-
-    print
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xend/XendVMMetrics.py
--- a/tools/python/xen/xend/XendVMMetrics.py    Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xend/XendVMMetrics.py    Mon Mar 26 10:10:31 2007 -0600
@@ -13,9 +13,13 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (c) 2006-2007 Xensource Inc.
+# Copyright (c) 2007 Tom Wilkie
 #============================================================================
 
 from xen.xend.XendLogging import log
+import xen.lowlevel.xc
+
+xc = xen.lowlevel.xc.xc()
 
 instances = {}
 
@@ -46,25 +50,106 @@ class XendVMMetrics:
         return self.uuid
 
     def get_memory_actual(self):
-        return self.get_record()["memory_actual"]
+        domInfo = self.xend_domain_instance.getDomInfo()
+        if domInfo:
+            return domInfo["mem_kb"] * 1024
+        else:
+            return 0
 
-    def get_vcpus_number(self):
-        return self.get_record()["vcpus_number"]
+    def get_VCPUs_number(self):
+        domInfo = self.xend_domain_instance.getDomInfo()
+        if domInfo:
+            return domInfo["online_vcpus"]
+        else:
+            return 0
     
-    def get_vcpus_utilisation(self):
+    def get_VCPUs_utilisation(self):
         return self.xend_domain_instance.get_vcpus_util()
 
+    def get_VCPUs_CPU(self):
+        domid = self.xend_domain_instance.getDomid()
+        if domid is not None:
+            vcpus_cpu = {}
+            vcpus_max = self.xend_domain_instance.info['VCPUs_max']
+            for i in range(0, vcpus_max):
+                info = xc.vcpu_getinfo(domid, i)
+                vcpus_cpu[i] = info['cpu']
+            return vcpus_cpu
+        else:
+            return {}
+
+    def get_VCPUs_flags(self):
+        domid = self.xend_domain_instance.getDomid()
+        if domid is not None:
+            vcpus_flags = {}
+            vcpus_max = self.xend_domain_instance.info['VCPUs_max']
+            for i in range(0, vcpus_max):
+                info = xc.vcpu_getinfo(domid, i)
+                flags = []
+                def set_flag(flag):
+                    if info[flag] == 1:
+                        flags.append(flag)
+                set_flag('blocked')
+                set_flag('online')
+                set_flag('running')
+                vcpus_flags[i] = ",".join(flags)
+            return vcpus_flags
+        else:
+            return {}
+
+    def get_state(self):
+        try:
+            domid = self.xend_domain_instance.getDomid()
+            domlist = xc.domain_getinfo(domid, 1)
+            if domlist and domid == domlist[0]['domid']:
+                dominfo = domlist[0]
+
+                states = []
+                def addState(key):
+                    if dominfo[key] == 1:
+                        states.append(key)
+
+                addState("running")
+                addState("blocked")
+                addState("paused")
+                addState("dying")
+                addState("crashed")
+                addState("shutdown")
+                return ",".join(states)
+        except Exception, err:
+            # ignore missing domain
+            log.trace("domain_getinfo(%d) failed, ignoring: %s", domid, 
str(err))
+        return ""
+
+    def get_VCPUs_params(self):
+        domid = self.xend_domain_instance.getDomid()
+        if domid is not None:
+            params_live = {}
+            vcpus_max = self.xend_domain_instance.info['VCPUs_max']
+            for i in range(0, vcpus_max):
+                info = xc.vcpu_getinfo(domid, i)
+                params_live['cpumap%i' % i] = \
+                    ",".join(map(str, info['cpumap']))
+
+            params_live.update(xc.sched_credit_domain_get(domid))
+            
+            return params_live
+        else:
+            return {}
+
+    def get_start_time(self):
+        return self.xend_domain_instance.info.get("start_time", -1)
+    
     def get_record(self):
-        domInfo = self.xend_domain_instance.getDomInfo()
-        if domInfo:
-            return { 'uuid'              : self.uuid,
-                     'memory_actual'     : domInfo["mem_kb"] * 1024,
-                     'vcpus_number'      : domInfo["online_vcpus"],
-                     'vcpus_utilisation' : self.get_vcpus_utilisation()
-                   }
-        else:
-            return { 'uuid'              : self.uuid,
-                     'memory_actual'     : 0,
-                     'vcpus_number'      : 0,
-                     'vcpus_utilisation' : {}
-                   }
+        import xen.xend.XendAPI as XendAPI
+        return { 'uuid'              : self.uuid,
+                 'memory_actual'     : self.get_memory_actual(),
+                 'VCPUs_number'      : self.get_VCPUs_number(),
+                 'VCPUs_utilisation' : self.get_VCPUs_utilisation(),
+                 'VCPUs_CPU'         : self.get_VCPUs_CPU(),
+                 'VCPUs_flags'       : self.get_VCPUs_flags(),
+                 'VCPUs_params'      : self.get_VCPUs_params(),
+                 'start_time'        : self.get_start_time(),
+                 'state'             : self.get_state(),
+                 'last_updated'      : XendAPI.now(),
+               }
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xend/server/SrvDomain.py Mon Mar 26 10:10:31 2007 -0600
@@ -101,10 +101,10 @@ class SrvDomain(SrvDir):
 
     def do_dump(self, _, req):
         fn = FormFn(self.xd.domain_dump,
-                   [['dom',         'int'],
-                    ['file',        'str'],
-                    ['live',        'int'],
-                    ['crash',       'int']])
+                    [['dom',         'int'],
+                     ['file',        'str'],
+                     ['live',        'int'],
+                     ['crash',       'int']])
         return fn(req.args, {'dom': self.dom.domid})
 
     def op_migrate(self, op, req):
@@ -139,9 +139,9 @@ class SrvDomain(SrvDir):
                     [['dom', 'int'],
                      ['period', 'int'],
                      ['slice', 'int'],
-                    ['latency', 'int'],
-                    ['extratime', 'int'],
-                    ['weight', 'int']])
+                     ['latency', 'int'],
+                     ['extratime', 'int'],
+                     ['weight', 'int']])
         val = fn(req.args, {'dom': self.dom.domid})
         return val
     
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xend/server/pciquirk.py
--- a/tools/python/xen/xend/server/pciquirk.py  Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xend/server/pciquirk.py  Mon Mar 26 10:10:31 2007 -0600
@@ -74,7 +74,7 @@ class PCIQuirk:
                 self.pci_quirks_config = pci_quirks_config
             except Exception, ex:
                 raise XendError("Reading config file %s: %s" %
-                               (QUIRK_CONFIG_FILE, str(ex)))
+                                (QUIRK_CONFIG_FILE, str(ex)))
         else:
             log.info("Config file does not exist: %s" % QUIRK_CONFIG_FILE)
             self.pci_quirks_config = ['xend-pci-quirks']
@@ -83,7 +83,7 @@ class PCIQuirk:
         for dev in devices:
             ids = child_at(child(dev,'pci_ids'),0)
             fields = child_at(child(dev,'pci_config_space_fields'),0)
-           if self.__matchPCIdev( ids ):
+            if self.__matchPCIdev( ids ):
                 log.info("Quirks found for PCI device [%s]" % self.devid)
                 return fields
 
@@ -93,11 +93,11 @@ class PCIQuirk:
     def __sendQuirks(self):
         for quirk in self.quirks:
             log.debug("Quirk Info: %04x:%02x:%02x.%1x-%s" % (self.domain,
-                   self.bus, self.slot, self.func, quirk))
+                      self.bus, self.slot, self.func, quirk))
             try:
                 f = file(QUIRK_SYSFS_NODE ,"w")
                 f.write( "%04x:%02x:%02x.%1x-%s" % (self.domain, self.bus,
-                       self.slot, self.func, quirk) )
+                        self.slot, self.func, quirk) )
                 f.close()
             except Exception, e:
                 raise VmError("pci: failed to open/write/close quirks " +
@@ -118,13 +118,13 @@ class PCIQuirk:
                 self.pci_perm_dev_config = pci_perm_dev_config
             except Exception, ex:
                 raise XendError("Reading config file %s: %s" %
-                               (PERMISSIVE_CONFIG_FILE,str(ex)))
+                                (PERMISSIVE_CONFIG_FILE,str(ex)))
         else:
             log.info("Config file does not exist: %s" % PERMISSIVE_CONFIG_FILE)
             self.pci_perm_dev_config = ['xend-pci-perm-devs']
 
         devices = child_at(child(pci_perm_dev_config, 
'unconstrained_dev_ids'),0)
-       if self.__matchPCIdev( devices ):
+        if self.__matchPCIdev( devices ):
             log.debug("Permissive mode enabled for PCI device [%s]" %
                       self.devid)
             return True
@@ -133,7 +133,7 @@ class PCIQuirk:
         return False
 
     def __sendPermDevs(self):
-       if self.__devIsUnconstrained( ):
+        if self.__devIsUnconstrained( ):
             log.debug("Unconstrained device: %04x:%02x:%02x.%1x" %
                       (self.domain, self.bus, self.slot, self.func))
             try:
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xm/main.py       Mon Mar 26 10:10:31 2007 -0600
@@ -502,6 +502,13 @@ def get_default_Network():
     return [network_ref
             for network_ref in server.xenapi.network.get_all()][0]
 
+class XenAPIUnsupportedException(Exception):
+    pass
+
+def xenapi_unsupported():
+    if serverType == SERVER_XEN_API:
+        raise XenAPIUnsupportedException, "This function is not supported by 
Xen-API"
+
 def map2sxp(m):
     return [[k, m[k]] for k in m.keys()]
 
@@ -550,10 +557,13 @@ def err(msg):
 
 
 def get_single_vm(dom):
-    uuids = server.xenapi.VM.get_by_name_label(dom)
-    n = len(uuids)
-    if n == 1:
-        return uuids[0]
+    if serverType == SERVER_XEN_API:
+        uuids = server.xenapi.VM.get_by_name_label(dom)
+        n = len(uuids)
+        if n > 0:
+            return uuids[0]
+        else:
+            raise OptionError("Domain '%s' not found." % dom)
     else:
         dominfo = server.xend.domain(dom, False)
         return dominfo['uuid']
@@ -569,9 +579,12 @@ class Shell(cmd.Cmd):
         cmd.Cmd.__init__(self)
         self.prompt = "xm> "
         if serverType == SERVER_XEN_API:
-            res = server.xenapi._UNSUPPORTED_list_all_methods()
-            for f in res:
-                setattr(Shell, 'do_' + f + ' ', self.default)
+            try:
+                res = server.xenapi._UNSUPPORTED_list_all_methods()
+                for f in res:
+                    setattr(Shell, 'do_' + f + ' ', self.default)
+            except:
+                pass
 
     def preloop(self):
         cmd.Cmd.preloop(self)
@@ -627,14 +640,18 @@ def xm_shell(args):
 #########################################################################
 
 def xm_save(args):
+
     arg_check(args, "save", 2, 3)
-
+    
     try:
         (options, params) = getopt.gnu_getopt(args, 'c', ['checkpoint'])
     except getopt.GetoptError, opterr:
         err(opterr)
         sys.exit(1)
 
+    dom = params[0]
+    savefile = params[1]
+
     checkpoint = False
     for (k, v) in options:
         if k in ['-c', '--checkpoint']:
@@ -645,19 +662,22 @@ def xm_save(args):
         usage('save')
         sys.exit(1)
 
-    try:
-        dominfo = parse_doms_info(server.xend.domain(params[0]))
-    except xmlrpclib.Fault, ex:
-        raise ex
-    
-    domid = dominfo['domid']
-    savefile = os.path.abspath(params[1])
+    savefile = os.path.abspath(savefile)
 
     if not os.access(os.path.dirname(savefile), os.W_OK):
         err("xm save: Unable to create file %s" % savefile)
         sys.exit(1)
-    
-    server.xend.domain.save(domid, savefile, checkpoint)
+        
+    if serverType == SERVER_XEN_API:       
+        server.xenapi.VM.save(get_single_vm(dom), savefile, checkpoint)
+    else:
+        try:
+            dominfo = parse_doms_info(server.xend.domain(dom))
+        except xmlrpclib.Fault, ex:
+            raise ex
+    
+        domid = dominfo['domid']
+        server.xend.domain.save(domid, savefile, checkpoint)
     
 def xm_restore(args):
     arg_check(args, "restore", 1, 2)
@@ -683,7 +703,10 @@ def xm_restore(args):
         err("xm restore: Unable to read file %s" % savefile)
         sys.exit(1)
 
-    server.xend.domain.restore(savefile, paused)
+    if serverType == SERVER_XEN_API:
+        server.xenapi.VM.restore(savefile, paused)
+    else:
+        server.xend.domain.restore(savefile, paused)
 
 
 def getDomains(domain_names, state, full = 0):
@@ -695,12 +718,24 @@ def getDomains(domain_names, state, full
             dom_rec = server.xenapi.VM.get_record(dom_ref)
             dom_metrics_ref = server.xenapi.VM.get_metrics(dom_ref)
             dom_metrics = server.xenapi.VM_metrics.get_record(dom_metrics_ref)
+
+            states = ('running', 'blocked', 'paused', 'shutdown',
+                      'crashed', 'dying')
+            def state_on_off(state):
+                if dom_metrics['state'].find(state) > -1:
+                    return state[0]
+                else:
+                    return "-"
+            state_str = "".join([state_on_off(state)
+                                 for state in states])
+            
             dom_rec.update({'name':     dom_rec['name_label'],
                             'memory_actual': 
int(dom_metrics['memory_actual'])/1024,
-                            'vcpus':    dom_metrics['vcpus_number'],
-                            'state':    '-----',
-                            'cpu_time': dom_metrics['vcpus_utilisation']})
-                       
+                            'vcpus':    dom_metrics['VCPUs_number'],
+                            'state':    state_str,
+                            'cpu_time': dom_metrics['VCPUs_utilisation'],
+                            'start_time': dom_metrics['start_time']})
+
             doms_sxp.append(['domain'] + map2sxp(dom_rec))
             doms_dict.append(dom_rec)
             
@@ -885,11 +920,71 @@ def xm_label_list(doms):
 
 
 def xm_vcpu_list(args):
-    if args:
-        dominfo = map(server.xend.domain.getVCPUInfo, args)
-    else:
-        doms = server.xend.domains(False)
-        dominfo = map(server.xend.domain.getVCPUInfo, doms)
+    if serverType == SERVER_XEN_API:
+        if args:
+            vm_refs = map(get_single_vm, args)
+        else:
+            vm_refs = server.xenapi.VM.get_all()
+            
+        vm_records = dict(map(lambda vm_ref:
+                                  (vm_ref, server.xenapi.VM.get_record(
+                                      vm_ref)),
+                              vm_refs))
+
+        vm_metrics = dict(map(lambda (ref, record):
+                                  (ref,
+                                   server.xenapi.VM_metrics.get_record(
+                                       record['metrics'])),
+                              vm_records.items()))
+
+        dominfo = []
+
+        # vcpu_list doesn't list 'managed' domains
+        # when they are not running, so filter them out
+
+        vm_refs = [vm_ref
+                  for vm_ref in vm_refs
+                  if vm_records[vm_ref]["power_state"] != "Halted"]
+
+        for vm_ref in vm_refs:
+            info = ['domain',
+                    ['domid',      vm_records[vm_ref]['domid']],
+                    ['name',       vm_records[vm_ref]['name_label']],
+                    ['vcpu_count', vm_records[vm_ref]['VCPUs_max']]]
+
+            
+
+            for i in range(int(vm_records[vm_ref]['VCPUs_max'])):
+                def chk_flag(flag):
+                    return vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
+                           .find(flag) > -1 and 1 or 0
+                
+                vcpu_info = ['vcpu',
+                             ['number',
+                                  i],
+                             ['online',
+                                  chk_flag("online")],
+                             ['blocked',
+                                  chk_flag("blocked")],
+                             ['running',
+                                  chk_flag("running")],
+                             ['cpu_time',
+                                  
vm_metrics[vm_ref]['VCPUs_utilisation'][str(i)]],
+                             ['cpu',
+                                  vm_metrics[vm_ref]['VCPUs_CPU'][str(i)]],
+                             ['cpumap',
+                                  vm_metrics[vm_ref]['VCPUs_params']\
+                                  ['cpumap%i' % i].split(",")]]
+                
+                info.append(vcpu_info)
+
+            dominfo.append(info)
+    else:    
+        if args:
+            dominfo = map(server.xend.domain.getVCPUInfo, args)
+        else:
+            doms = server.xend.domains(False)
+            dominfo = map(server.xend.domain.getVCPUInfo, doms)
 
     print '%-32s %3s %5s %5s %5s %9s %s' % \
           ('Name', 'ID', 'VCPU', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
@@ -947,16 +1042,20 @@ def xm_vcpu_list(args):
             cpumap = map(lambda x: int(x), cpumap)
             cpumap.sort()
 
-            for x in server.xend.node.info()[1:]:
-                if len(x) > 1 and x[0] == 'nr_cpus':
-                    nr_cpus = int(x[1])
-                    # normalize cpumap by modulus nr_cpus, and drop duplicates
-                    cpumap = dict.fromkeys(
-                                map(lambda x: x % nr_cpus, cpumap)).keys()
-                    if len(cpumap) == nr_cpus:
-                        return "any cpu"
-                    break
- 
+            if serverType == SERVER_XEN_API:
+                nr_cpus = len(server.xenapi.host.get_host_CPUs(
+                    server.xenapi.session.get_this_host()))
+            else:
+                for x in server.xend.node.info()[1:]:
+                    if len(x) > 1 and x[0] == 'nr_cpus':
+                        nr_cpus = int(x[1])
+
+            # normalize cpumap by modulus nr_cpus, and drop duplicates
+            cpumap = dict.fromkeys(
+                       map(lambda x: x % nr_cpus, cpumap)).keys()
+            if len(cpumap) == nr_cpus:
+                return "any cpu"
+
             return format_pairs(list_to_rangepairs(cpumap))
 
         name  =     get_info('name')
@@ -1154,13 +1253,17 @@ def xm_vcpu_pin(args):
         return cpus
 
     dom  = args[0]
-    vcpu = args[1]
+    vcpu = int(args[1])
     if args[2] == 'all':
         cpumap = cpu_make_map('0-63')
     else:
         cpumap = cpu_make_map(args[2])
-    
-    server.xend.domain.pincpu(dom, vcpu, cpumap)
+
+    if serverType == SERVER_XEN_API:
+        server.xenapi.VM.add_to_VCPUs_params_live(
+            get_single_vm(dom), "cpumap%i" % vcpu, ",".join(cpumap))
+    else:
+        server.xend.domain.pincpu(dom, vcpu, cpumap)
 
 def xm_mem_max(args):
     arg_check(args, "mem-max", 2)
@@ -1181,8 +1284,10 @@ def xm_mem_set(args):
 
     if serverType == SERVER_XEN_API:
         mem_target = int_unit(args[1], 'm') * 1024 * 1024
-        server.xenapi.VM.set_memory_dynamic_max(get_single_vm(dom), mem_target)
-        server.xenapi.VM.set_memory_dynamic_min(get_single_vm(dom), mem_target)
+        server.xenapi.VM.set_memory_dynamic_max_live(get_single_vm(dom),
+                                                     mem_target)
+        server.xenapi.VM.set_memory_dynamic_min_live(get_single_vm(dom),
+                                                     mem_target)
     else:
         mem_target = int_unit(args[1], 'm')
         server.xend.domain.setMemoryTarget(dom, mem_target)
@@ -1194,7 +1299,7 @@ def xm_vcpu_set(args):
     vcpus = int(args[1])
 
     if serverType == SERVER_XEN_API:
-        server.xenapi.VM.set_vcpus_live(get_single_vm(dom), vcpus)
+        server.xenapi.VM.set_VCPUs_number_live(get_single_vm(dom), vcpus)
     else:
         server.xend.domain.setVCpuCount(dom, vcpus)
 
@@ -1231,6 +1336,8 @@ def xm_domname(args):
         print sxp.child_value(dom, 'name')
 
 def xm_sched_sedf(args):
+    xenapi_unsupported()
+    
     def ns_to_ms(val):
         return float(val) * 0.000001
     
@@ -1355,10 +1462,21 @@ def xm_sched_credit(args):
         
         for d in doms:
             try:
-                info = server.xend.domain.sched_credit_get(d['domid'])
+                if serverType == SERVER_XEN_API:
+                    info = server.xenapi.VM_metrics.get_VCPUs_params(
+                        server.xenapi.VM.get_metrics(
+                            get_single_vm(d['name'])))
+                else:
+                    info = server.xend.domain.sched_credit_get(d['domid'])
             except xmlrpclib.Fault:
+                pass
+
+            if 'weight' not in info or 'cap' not in info:
                 # domain does not support sched-credit?
                 info = {'weight': -1, 'cap': -1}
+
+            info['weight'] = int(info['weight'])
+            info['cap']    = int(info['cap'])
             
             info['name']  = d['name']
             info['domid'] = int(d['domid'])
@@ -1368,10 +1486,20 @@ def xm_sched_credit(args):
             # place holder for system-wide scheduler parameters
             err("No domain given.")
             usage('sched-credit')
-        
-        result = server.xend.domain.sched_credit_set(domid, weight, cap)
-        if result != 0:
-            err(str(result))
+
+        if serverType == SERVER_XEN_API:
+            server.xenapi.VM.add_to_VCPUs_params_live(
+                get_single_vm(domid),
+                "weight",
+                weight)
+            server.xenapi.VM.add_to_VCPUs_params_live(
+                get_single_vm(domid),
+                "cap",
+                cap)            
+        else:
+            result = server.xend.domain.sched_credit_set(domid, weight, cap)
+            if result != 0:
+                err(str(result))
 
 def xm_info(args):
     arg_check(args, "info", 0)
@@ -1754,6 +1882,7 @@ def xm_block_list(args):
                    % ni)
 
 def xm_vtpm_list(args):
+    xenapi_unsupported()
     (use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
 
     dom = params[0]
@@ -1883,7 +2012,10 @@ def xm_network_attach(args):
             record = vif_record
             for key in keys[:-1]:
                 record = record[key]
-            record[keys[-1]] = val 
+            record[keys[-1]] = val
+
+        def get_net_from_bridge(bridge):
+            raise "Not supported just yet"
          
         vif_conv = {
             'type':
@@ -1991,6 +2123,7 @@ def xm_network_detach(args):
 
 
 def xm_vnet_list(args):
+    xenapi_unsupported()
     try:
         (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
     except getopt.GetoptError, opterr:
@@ -2019,6 +2152,7 @@ def xm_vnet_list(args):
             print vnet, ex
 
 def xm_vnet_create(args):
+    xenapi_unsupported()
     arg_check(args, "vnet-create", 1)
     conf = args[0]
     if not os.access(conf, os.R_OK):
@@ -2028,6 +2162,7 @@ def xm_vnet_create(args):
     server.xend_vnet_create(conf)
 
 def xm_vnet_delete(args):
+    xenapi_unsupported()
     arg_check(args, "vnet-delete", 1)
     vnet = args[0]
     server.xend_vnet_delete(vnet)
@@ -2044,7 +2179,7 @@ commands = {
     "domid": xm_domid,
     "domname": xm_domname,
     "dump-core": xm_dump_core,
-    "reboot": xm_reboot,    
+    "reboot": xm_reboot,
     "rename": xm_rename,
     "restore": xm_restore,
     "resume": xm_resume,
@@ -2228,6 +2363,8 @@ def _run_cmd(cmd, cmd_name, args):
         err(str(e))
         _usage(cmd_name)
         print e.usage
+    except XenAPIUnsupportedException, e:
+        err(str(e))
     except Exception, e:
         if serverType != SERVER_XEN_API:
            from xen.util import security
diff -r 16198b57f535 -r 56caf0e37e6a tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/python/xen/xm/xenapi_create.py      Mon Mar 26 10:10:31 2007 -0600
@@ -242,9 +242,9 @@ class xenapi_create:
             "user_version":
                 get_text_in_child_node(vm, "version"),
             "is_a_template":
-                vm.attributes["is_a_template"].value,
+                vm.attributes["is_a_template"].value == 'true',
             "auto_power_on":
-                vm.attributes["auto_power_on"].value,
+                vm.attributes["auto_power_on"].value == 'true',
             "memory_static_max":
                 get_child_node_attribute(vm, "memory", "static_max"),
             "memory_static_min":
@@ -253,11 +253,11 @@ class xenapi_create:
                 get_child_node_attribute(vm, "memory", "dynamic_max"),
             "memory_dynamic_min":
                 get_child_node_attribute(vm, "memory", "dynamic_min"),
-            "vcpus_params":
+            "VCPUs_params":
                 get_child_nodes_as_dict(vm, "vcpu_param", "key", "value"),
-            "vcpus_max":
+            "VCPUs_max":
                 vm.attributes["vcpus_max"].value,
-            "vcpus_at_startup":
+            "VCPUs_at_startup":
                 vm.attributes["vcpus_at_startup"].value,
             "actions_after_shutdown":
                 vm.attributes["actions_after_shutdown"].value,
@@ -591,7 +591,6 @@ class sxp2xml:
     def extract_vdi(self, vbd_sxp, document):
         src = get_child_by_name(vbd_sxp, "uname")
         name = "vdi" + str(src.__hash__())
-        path = src[src.find(":")+1:]
 
         vdi = document.createElement("vdi")
 
@@ -599,8 +598,7 @@ class sxp2xml:
         vdi.attributes["read_only"] \
             = (get_child_by_name(vbd_sxp, "mode") != "w") \
                and "true" or "false"
-        vdi.attributes["size"] \
-            = str(os.path.getsize(path))
+        vdi.attributes["size"] = '-1'
         vdi.attributes["type"] = "system"
         vdi.attributes["shareable"] = "false"
         vdi.attributes["name"] = name
@@ -613,7 +611,10 @@ class sxp2xml:
 
         vif = document.createElement("vif")
 
-        dev = get_child_by_name(vif_sxp, "vifname", "eth0")
+        dev = get_child_by_name(vif_sxp, "vifname", None)
+
+        if dev is None:
+            dev = self.getFreshEthDevice()
 
         vif.attributes["name"] \
             = "vif" + str(dev.__hash__())
@@ -630,7 +631,8 @@ class sxp2xml:
         
         return vif
 
-
-
-
-
+    _eths = -1
+
+    def getFreshEthDevice(self):
+        self._eths += 1
+        return "eth%i" % self._eths
diff -r 16198b57f535 -r 56caf0e37e6a tools/xenmon/xenmon.py
--- a/tools/xenmon/xenmon.py    Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/xenmon/xenmon.py    Mon Mar 26 10:10:31 2007 -0600
@@ -166,7 +166,7 @@ class DomainInfo:
 
     def ec_stats(self, passed):
         total = float(self.exec_count/(float(passed)/10**9))
-       return total
+        return total
 
     def io_stats(self, passed):
         total = float(self.iocount_sum)
@@ -235,7 +235,7 @@ def time_scale(ns):
     elif ns < 1000*1000:
         return "%4.2f us" % (float(ns)/10**3)
     elif ns < 10**9:
-           return "%4.2f ms" % (float(ns)/10**6)
+        return "%4.2f ms" % (float(ns)/10**6)
     else:
         return "%4.2f s" % (float(ns)/10**9)
 
@@ -534,20 +534,20 @@ def show_livestats(cpu):
 # write does the file get created
 class Delayed(file):
     def __init__(self, filename, mode):
-       self.filename = filename
-       self.saved_mode = mode
-       self.delay_data = ""
-       self.opened = 0
+        self.filename = filename
+        self.saved_mode = mode
+        self.delay_data = ""
+        self.opened = 0
 
     def delayed_write(self, str):
-       self.delay_data = str
+        self.delay_data = str
 
     def write(self, str):
-       if not self.opened:
-           self.file = open(self.filename, self.saved_mode)
-           self.opened = 1
+        if not self.opened:
+            self.file = open(self.filename, self.saved_mode)
+            self.opened = 1
             self.file.write(self.delay_data)
-       self.file.write(str)
+        self.file.write(str)
 
     def rename(self, name):
         self.filename = name
diff -r 16198b57f535 -r 56caf0e37e6a tools/xm-test/lib/XmTestLib/NetConfig.py
--- a/tools/xm-test/lib/XmTestLib/NetConfig.py  Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/xm-test/lib/XmTestLib/NetConfig.py  Mon Mar 26 10:10:31 2007 -0600
@@ -87,7 +87,7 @@ class NetConfig:
         else:
             self.netmask = NETMASK
             self.network = NETWORK
-           s_ip = ''
+            s_ip = ''
 
             # Get starting ip and max ip from configured ip range
             s_ip = NETWORK_IP_RANGE
diff -r 16198b57f535 -r 56caf0e37e6a tools/xm-test/lib/XmTestLib/XenDevice.py
--- a/tools/xm-test/lib/XmTestLib/XenDevice.py  Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/xm-test/lib/XmTestLib/XenDevice.py  Mon Mar 26 10:10:31 2007 -0600
@@ -98,8 +98,8 @@ class XenDevice:
         self.domain = domain
         self.configNode = None
         # Commands run when domain is started or devices added and removed.
-       self.dom0_cmds = []
-       self.domU_cmds = []
+        self.dom0_cmds = []
+        self.domU_cmds = []
 
     def __str__(self):
         """Convert device config to XenConfig node compatible string"""
@@ -178,7 +178,7 @@ class XenNetDevice(XenDevice):
         self.dom0_alias_ip = None
 
         if domain.getDomainType() == "HVM":
-           self.config["type"] = "ioemu"
+            self.config["type"] = "ioemu"
             if not self.config.has_key('bridge'):
                 self.config["bridge"] = "xenbr0"
 
@@ -252,7 +252,7 @@ class XenNetDevice(XenDevice):
         if (self.ip and not ip) or ((self.ip and ip) and (self.ip != ip)): 
             self.releaseNetDevIP()
 
-       if not self.netmask:
+        if not self.netmask:
             self.netmask = xmtest_netconf.getNetMask()
 
         if not self.network:
diff -r 16198b57f535 -r 56caf0e37e6a tools/xm-test/lib/XmTestLib/arch.py
--- a/tools/xm-test/lib/XmTestLib/arch.py       Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/xm-test/lib/XmTestLib/arch.py       Mon Mar 26 10:10:31 2007 -0600
@@ -94,7 +94,7 @@ def ppc_checkBuffer(buffer):
     for i in range(0, len(checks)):
         check=checks[i]
         if check.get('pattern').search(buffer):
-               FAIL(check.get('message'))
+            FAIL(check.get('message'))
 
     return
 
diff -r 16198b57f535 -r 56caf0e37e6a tools/xm-test/lib/XmTestReport/OSReport.py
--- a/tools/xm-test/lib/XmTestReport/OSReport.py        Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/lib/XmTestReport/OSReport.py        Mon Mar 26 10:10:31 
2007 -0600
@@ -149,16 +149,16 @@ class OperatingSystem:
             return None, None
 
     def __debianStyleRelease(self):
-       if os.access("/etc/debian_version", os.R_OK):
-           rFile = file("/etc/debian_version")
-       else:
-           rFile = None
-
-       if not rFile:
-           return None, None
-
-       line = rFile.readline()
-       return "Debian", line.rstrip("\n");
+        if os.access("/etc/debian_version", os.R_OK):
+            rFile = file("/etc/debian_version")
+        else:
+            rFile = None
+
+        if not rFile:
+            return None, None
+
+        line = rFile.readline()
+        return "Debian", line.rstrip("\n");
 
     def __lsbStyleRelease(self):
         if os.access("/etc/lsb-release", os.R_OK):
diff -r 16198b57f535 -r 56caf0e37e6a tools/xm-test/lib/XmTestReport/Report.py
--- a/tools/xm-test/lib/XmTestReport/Report.py  Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/xm-test/lib/XmTestReport/Report.py  Mon Mar 26 10:10:31 2007 -0600
@@ -86,7 +86,7 @@ def encodeForm(fieldList):
 
 def postResults(report_server, results):
     if not re.match('http://', report_server):
-       report_server = 'http://'+report_server
+        report_server = 'http://'+report_server
     (report_host,report_url) = urlparse(report_server)[1:3]
     conn = httplib.HTTPConnection(report_host)
 
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/create/04_create_conflictname_neg.py
--- a/tools/xm-test/tests/create/04_create_conflictname_neg.py  Mon Mar 26 
09:17:25 2007 -0600
+++ b/tools/xm-test/tests/create/04_create_conflictname_neg.py  Mon Mar 26 
10:10:31 2007 -0600
@@ -34,8 +34,8 @@ except DomainError, e:
 except DomainError, e:
     eyecatcher = "Fail"
     # Stop the domain1 (nice shutdown)
-    domain1.stop()     
+    domain1.stop()
 
 if eyecatcher != "Fail":
-       domain2.stop()
-       FAIL("xm create let me create a duplicate-named domain!") 
+    domain2.stop()
+    FAIL("xm create let me create a duplicate-named domain!") 
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/create/06_create_mem_neg.py
--- a/tools/xm-test/tests/create/06_create_mem_neg.py   Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/create/06_create_mem_neg.py   Mon Mar 26 10:10:31 
2007 -0600
@@ -16,7 +16,7 @@ from XmTestLib import *
 
 rdpath = os.environ.get("RD_PATH")
 if not rdpath:
-       rdpath = "../ramdisk"
+    rdpath = "../ramdisk"
 
 # Test 1: create a domain with mem=0
 config1 = {"memory": 0}
@@ -29,8 +29,8 @@ except DomainError, e:
     eyecatcher1 = "Fail"
 
 if eyecatcher1 != "Fail":
-       domain1.stop()
-        FAIL("xm create let me create a domain with 0 memory")
+    domain1.stop()
+    FAIL("xm create let me create a domain with 0 memory")
 
 
 # Test 2: create a domain with mem>sys_mem
@@ -48,6 +48,6 @@ except DomainError, e:
     eyecatcher2 = "Fail"
 
 if eyecatcher2 != "Fail":
-        domain2.stop()
-        FAIL("xm create let me create a domain with mem > sys_mem")
+    domain2.stop()
+    FAIL("xm create let me create a domain with mem > sys_mem")
 
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/create/07_create_mem64_pos.py
--- a/tools/xm-test/tests/create/07_create_mem64_pos.py Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/create/07_create_mem64_pos.py Mon Mar 26 10:10:31 
2007 -0600
@@ -15,12 +15,12 @@ from XmTestLib import *
 
 rdpath = os.environ.get("RD_PATH")
 if not rdpath:
-        rdpath = "../ramdisk"
+    rdpath = "../ramdisk"
 
 #get current free memory info
 mem = int(getInfo("free_memory"))
 if mem < 64:
-       SKIP("This test needs 64 MB of free memory (%i MB avail)" % mem)
+    SKIP("This test needs 64 MB of free memory (%i MB avail)" % mem)
 
 #create a domain with mem=64
 config = {"memory": 64}
@@ -39,11 +39,11 @@ except DomainError, e:
 
 eyecatcher1 = str(isDomainRunning(domain_mem64.getName()))
 if eyecatcher1 != "True":
-       FAIL("Failed to verify that a 64MB domain started")
+    FAIL("Failed to verify that a 64MB domain started")
 
 eyecatcher2 = getDomMem(domain_mem64.getName())
 if eyecatcher2 not in range(62, 65):
-       FAIL("Started domain with 64MB, but it got %i MB" % eyecatcher2)
+    FAIL("Started domain with 64MB, but it got %i MB" % eyecatcher2)
 
 #stop the domain (nice shutdown)
 domain_mem64.stop()
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/create/08_create_mem128_pos.py
--- a/tools/xm-test/tests/create/08_create_mem128_pos.py        Mon Mar 26 
09:17:25 2007 -0600
+++ b/tools/xm-test/tests/create/08_create_mem128_pos.py        Mon Mar 26 
10:10:31 2007 -0600
@@ -15,12 +15,12 @@ from XmTestLib import *
 
 rdpath = os.environ.get("RD_PATH")
 if not rdpath:
-        rdpath = "../ramdisk"
+    rdpath = "../ramdisk"
 
 #get current free memory info
 mem = int(getInfo("free_memory"))
 if mem < 128:
-        SKIP("This test needs 128 MB of free memory (%i MB avail)" % mem)
+    SKIP("This test needs 128 MB of free memory (%i MB avail)" % mem)
 
 #create a domain with mem=128
 config={"memory": 128}
@@ -39,11 +39,11 @@ except DomainError, e:
 
 eyecatcher1 = str(isDomainRunning(domain_mem128.getName()))
 if eyecatcher1 != "True":
-       FAIL("Failed to verify that a 128MB domain started")
+    FAIL("Failed to verify that a 128MB domain started")
 
 eyecatcher2 = getDomMem(domain_mem128.getName())
 if eyecatcher2 not in range(126, 129):
-       FAIL("Started domain with 128MB, but it got %i MB" % eyecatcher2)
+    FAIL("Started domain with 128MB, but it got %i MB" % eyecatcher2)
 
 #stop the domain (nice shutdown)
 domain_mem128.stop()
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/create/09_create_mem256_pos.py
--- a/tools/xm-test/tests/create/09_create_mem256_pos.py        Mon Mar 26 
09:17:25 2007 -0600
+++ b/tools/xm-test/tests/create/09_create_mem256_pos.py        Mon Mar 26 
10:10:31 2007 -0600
@@ -15,12 +15,12 @@ from XmTestLib import *
 
 rdpath = os.environ.get("RD_PATH")
 if not rdpath:
-        rdpath = "../ramdisk"
+    rdpath = "../ramdisk"
 
 #get current free memory info
 mem = int(getInfo("free_memory"))
 if mem < 256:
-        SKIP("This test needs 256 MB of free memory (%i MB avail)" % mem)
+    SKIP("This test needs 256 MB of free memory (%i MB avail)" % mem)
 
 #create a domain with mem=256
 config = {"memory": 256}
@@ -39,11 +39,11 @@ except DomainError, e:
 
 eyecatcher1 = str(isDomainRunning(domain_mem256.getName()))
 if eyecatcher1 != "True":
-       FAIL("Failed to verify that a 256MB domain started")
+    FAIL("Failed to verify that a 256MB domain started")
 
 eyecatcher2 = getDomMem(domain_mem256.getName())
 if eyecatcher2 not in range(254, 257):
-       FAIL("Started domain with 256MB, but it got %i MB" % eyecatcher2)
+    FAIL("Started domain with 256MB, but it got %i MB" % eyecatcher2)
 
 #stop the domain (nice shutdown)
 domain_mem256.stop()
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/list/02_list_badparm_neg.py
--- a/tools/xm-test/tests/list/02_list_badparm_neg.py   Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/list/02_list_badparm_neg.py   Mon Mar 26 10:10:31 
2007 -0600
@@ -11,6 +11,6 @@ eyecatcher = "Error:"
 eyecatcher = "Error:"
 where = output.find(eyecatcher)
 if status == 0:
-    FAIL("xm list returned invalud %i != 0" % status)
+    FAIL("xm list returned invalid %i != 0" % status)
 elif where == -1:
     FAIL("xm list failed to report error for bad arg")
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/migrate/01_migrate_localhost_pos.py
--- a/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py   Mon Mar 26 
09:17:25 2007 -0600
+++ b/tools/xm-test/tests/migrate/01_migrate_localhost_pos.py   Mon Mar 26 
10:10:31 2007 -0600
@@ -51,12 +51,12 @@ except TimeoutError, e:
     FAIL(str(e))
     
 if status != 0:
-       FAIL("xm migrate returned invalid %i != 0" % status)
+    FAIL("xm migrate returned invalid %i != 0" % status)
 
 new_domid = domid(domain.getName())
 
 if (old_domid == new_domid):
-       FAIL("xm migrate failed, domain id is still %s" % old_domid)
+    FAIL("xm migrate failed, domain id is still %s" % old_domid)
 
 # Attach a console to it
 try:
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py
--- a/tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py     
Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/xm-test/tests/network-attach/04_network_attach_baddomain_neg.py     
Mon Mar 26 10:10:31 2007 -0600
@@ -10,6 +10,6 @@ eyecatcher = "Error"
 eyecatcher = "Error"
 where = output.find(eyecatcher)
 if status == 0:
-       FAIL("xm network-attach returned bad status, expected non 0, status is: 
%i" % status )
+    FAIL("xm network-attach returned bad status, expected non 0, status is: 
%i" % status )
 elif where == -1:
-       FAIL("xm network-attach returned bad output, expected Error, output is: 
%s" % output )
+    FAIL("xm network-attach returned bad output, expected Error, output is: 
%s" % output )
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/network-attach/network_utils.py
--- a/tools/xm-test/tests/network-attach/network_utils.py       Mon Mar 26 
09:17:25 2007 -0600
+++ b/tools/xm-test/tests/network-attach/network_utils.py       Mon Mar 26 
10:10:31 2007 -0600
@@ -51,6 +51,6 @@ def network_detach(domain_name, console,
 
     eths_after = count_eth(console)
     if eths_after != (eths_before-1):
-       return -2, "Network device was not actually disconnected from domU"
+        return -2, "Network device was not actually disconnected from domU"
 
     return 0, None
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/pause/01_pause_basic_pos.py
--- a/tools/xm-test/tests/pause/01_pause_basic_pos.py   Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/pause/01_pause_basic_pos.py   Mon Mar 26 10:10:31 
2007 -0600
@@ -39,7 +39,7 @@ domain.closeConsole()
 # Pause the domain
 status, output = traceCommand("xm pause %s" % domain.getName())
 if status != 0:
-       FAIL("xm pause returned invalid %i != 0", status)
+    FAIL("xm pause returned invalid %i != 0", status)
 
 # Try to attach a console to it
 try:
@@ -56,7 +56,7 @@ domain.closeConsole()
 
 status, output = traceCommand("xm unpause %s" % domain.getName())
 if status != 0:
-       FAIL("xm unpause returned invalid %i != 0", status)
+    FAIL("xm unpause returned invalid %i != 0", status)
 
 # Stop the domain (nice shutdown)
 domain.stop()
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/security-acm/06_security-acm_dom_block_attach.py
--- a/tools/xm-test/tests/security-acm/06_security-acm_dom_block_attach.py      
Mon Mar 26 09:17:25 2007 -0600
+++ b/tools/xm-test/tests/security-acm/06_security-acm_dom_block_attach.py      
Mon Mar 26 10:10:31 2007 -0600
@@ -46,9 +46,9 @@ block_utils.block_attach(domain, resourc
 block_utils.block_attach(domain, resource1, "xvda1")
 
 try:
-       run1 = console.runCmd("cat /proc/partitions")
+    run1 = console.runCmd("cat /proc/partitions")
 except ConsoleError, e:
-       FAIL(str(e))
+    FAIL(str(e))
 
 #Explicitly label the 2nd resource
 ACMLabelResource(resource2, resourcelabel2)
@@ -62,9 +62,9 @@ for i in range(10):
     time.sleep(1)
 
 try:
-       run2 = console.runCmd("cat /proc/partitions")
+    run2 = console.runCmd("cat /proc/partitions")
 except ConsoleError, e:
-       FAIL(str(e))
+    FAIL(str(e))
 
 # Close the console
 domain.closeConsole()
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/unpause/01_unpause_basic_pos.py
--- a/tools/xm-test/tests/unpause/01_unpause_basic_pos.py       Mon Mar 26 
09:17:25 2007 -0600
+++ b/tools/xm-test/tests/unpause/01_unpause_basic_pos.py       Mon Mar 26 
10:10:31 2007 -0600
@@ -46,18 +46,17 @@ for i in range(100):
         # Pause the domain
         status, output = traceCommand("xm pause %s" % domain.getName())
         if status != 0:
-               FAIL("xm pause returned invalid %i != 0", status)
+            FAIL("xm pause returned invalid %i != 0", status)
     else:
         # Unpause the domain
         status, output = traceCommand("xm unpause %s" % domain.getName())
         if status != 0:
-               FAIL("xm unpause returned invalud %i != 0", status)
-       
+            FAIL("xm unpause returned invalid %i != 0", status)
 
 # Make sure the domain is unpaused before we finish up
 status, output = traceCommand("xm unpause %s" % domain.getName())
 if status != 0:
-       FAIL("xm unpause returned invalid %i != 0", status)
+    FAIL("xm unpause returned invalid %i != 0", status)
 
 # Are we still alive after all that?
 try:
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py
--- a/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py      Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py      Mon Mar 26 10:10:31 
2007 -0600
@@ -49,4 +49,4 @@ vtpm_cleanup(domName)
 vtpm_cleanup(domName)
 
 if not re.search("PCR-00:",run["output"]):
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/vtpm/03_vtpm-susp_res.py
--- a/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py      Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py      Mon Mar 26 10:10:31 
2007 -0600
@@ -97,7 +97,7 @@ while loop < 3:
     if not re.search("PCR-00:",run["output"]):
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
 
     loop += 1
 
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py
--- a/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py      Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py      Mon Mar 26 10:10:31 
2007 -0600
@@ -91,7 +91,7 @@ while loop < 3:
     if not re.search("PCR-00:",run["output"]):
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
 
     loop += 1
 
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py
--- a/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py      Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py      Mon Mar 26 10:10:31 
2007 -0600
@@ -91,7 +91,7 @@ while loop < 3:
     if not re.search("PCR-00:",run["output"]):
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
 
     loop += 1
 
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py
--- a/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py Mon Mar 26 10:10:31 
2007 -0600
@@ -122,12 +122,12 @@ while loop < 3:
     if not re.search("PCR-00:",run["output"]):
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
 
     if not re.search("PCR-00: 1E A7 BD",run["output"]):
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-       FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
+        FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
 
     loop += 1
 
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py
--- a/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py      Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py      Mon Mar 26 10:10:31 
2007 -0600
@@ -116,12 +116,12 @@ while loop < 3:
     if not re.search("PCR-00:",run["output"]):
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
 
     if not re.search("PCR-00: 1E A7 BD",run["output"]):
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-       FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
+        FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
 
     loop += 1
 
diff -r 16198b57f535 -r 56caf0e37e6a 
tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py
--- a/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py      Mon Mar 26 09:17:25 
2007 -0600
+++ b/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py      Mon Mar 26 10:10:31 
2007 -0600
@@ -116,12 +116,12 @@ while loop < 3:
     if not re.search("PCR-00:",run["output"]):
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+        FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
 
     if not re.search("PCR-00: 1E A7 BD",run["output"]):
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-       FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
+        FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
 
     loop += 1
 
diff -r 16198b57f535 -r 56caf0e37e6a xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Mon Mar 26 09:17:25 2007 -0600
+++ b/xen/arch/x86/hvm/hvm.c    Mon Mar 26 10:10:31 2007 -0600
@@ -218,6 +218,7 @@ void hvm_domain_destroy(struct domain *d
 {
     pit_deinit(d);
     rtc_deinit(d);
+    pmtimer_deinit(d);
     hpet_deinit(d);
 
     if ( d->arch.hvm_domain.shared_page_va )
@@ -303,7 +304,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
 
     pit_init(v, cpu_khz);
     rtc_init(v, RTC_PORT(0));
-    pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS);
+    pmtimer_init(v);
     hpet_init(v);
  
     /* Init guest TSC to start from zero. */
diff -r 16198b57f535 -r 56caf0e37e6a xen/arch/x86/hvm/pmtimer.c
--- a/xen/arch/x86/hvm/pmtimer.c        Mon Mar 26 09:17:25 2007 -0600
+++ b/xen/arch/x86/hvm/pmtimer.c        Mon Mar 26 10:10:31 2007 -0600
@@ -1,12 +1,172 @@
+/*
+ * hvm/pmtimer.c: emulation of the ACPI PM timer 
+ *
+ * Copyright (c) 2007, XenSource inc.
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
 #include <asm/hvm/vpt.h>
 #include <asm/hvm/io.h>
 #include <asm/hvm/support.h>
 
+/* Slightly more readable port I/O addresses for the registers we intercept */
+#define PM1a_STS_ADDR (ACPI_PM1A_EVT_BLK_ADDRESS)
+#define PM1a_EN_ADDR  (ACPI_PM1A_EVT_BLK_ADDRESS + 2)
+#define TMR_VAL_ADDR  (ACPI_PM_TMR_BLK_ADDRESS)
+
+/* The interesting bit of the PM1a_STS register */
+#define TMR_STS    (1 << 0)
+#define PWRBTN_STS (1 << 5)
+#define GBL_STS    (1 << 8)
+
+/* The same in PM1a_EN */
+#define TMR_EN     (1 << 0)
+#define PWRBTN_EN  (1 << 5)
+#define GBL_EN     (1 << 8)
+
+/* Mask of bits in PM1a_STS that can generate an SCI.  Although the ACPI
+ * spec lists other bits, the PIIX4, which we are emulating, only
+ * supports these three.  For now, we only use TMR_STS; in future we
+ * will let qemu set the other bits */
+#define SCI_MASK (TMR_STS|PWRBTN_STS|GBL_STS) 
+
+/* SCI IRQ number (must match SCI_INT number in ACPI FADT in hvmloader) */
+#define SCI_IRQ 9
+
+/* We provide a 32-bit counter (must match the TMR_VAL_EXT bit in the FADT) */
+#define TMR_VAL_MASK  (0xffffffff)
+#define TMR_VAL_MSB   (0x80000000)
+
+
+/* Dispatch SCIs based on the PM1a_STS and PM1a_EN registers */
+static void pmt_update_sci(PMTState *s)
+{
+    if ( s->pm.pm1a_en & s->pm.pm1a_sts & SCI_MASK )
+        hvm_isa_irq_assert(s->vcpu->domain, SCI_IRQ);
+    else
+        hvm_isa_irq_deassert(s->vcpu->domain, SCI_IRQ);
+}
+
+/* Set the correct value in the timer, accounting for time elapsed
+ * since the last time we did that. */
+static void pmt_update_time(PMTState *s)
+{
+    uint64_t curr_gtime;
+    uint32_t msb = s->pm.tmr_val & TMR_VAL_MSB;
+    
+    /* Update the timer */
+    curr_gtime = hvm_get_guest_time(s->vcpu);
+    s->pm.tmr_val += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
+    s->pm.tmr_val &= TMR_VAL_MASK;
+    s->last_gtime = curr_gtime;
+    
+    /* If the counter's MSB has changed, set the status bit */
+    if ( (s->pm.tmr_val & TMR_VAL_MSB) != msb )
+    {
+        s->pm.pm1a_sts |= TMR_STS;
+        pmt_update_sci(s);
+    }
+}
+
+/* This function should be called soon after each time the MSB of the
+ * pmtimer register rolls over, to make sure we update the status
+ * registers and SCI at least once per rollover */
+static void pmt_timer_callback(void *opaque)
+{
+    PMTState *s = opaque;
+    uint32_t pmt_cycles_until_flip;
+    uint64_t time_until_flip;
+    
+    /* Recalculate the timer and make sure we get an SCI if we need one */
+    pmt_update_time(s);
+    
+    /* How close are we to the next MSB flip? */
+    pmt_cycles_until_flip = TMR_VAL_MSB - (s->pm.tmr_val & (TMR_VAL_MSB - 1));
+    
+    /* Overall time between MSB flips */
+    time_until_flip = (1000000000ULL << 31) / FREQUENCE_PMTIMER;
+    
+    /* Reduced appropriately */
+    time_until_flip = (time_until_flip * pmt_cycles_until_flip) / (1ULL<<31);
+    
+    /* Wake up again near the next bit-flip */
+    set_timer(&s->timer, NOW() + time_until_flip + MILLISECS(1));
+}
+
+
+/* Handle port I/O to the PM1a_STS and PM1a_EN registers */
+static int handle_evt_io(ioreq_t *p)
+{
+    struct vcpu *v = current;
+    PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
+    uint32_t addr, data, byte;
+    int i;
+
+    if ( p->dir == 0 ) /* Write */
+    {
+        /* Handle this I/O one byte at a time */
+        for ( i = p->size, addr = p->addr, data = p->data;
+              i > 0;
+              i--, addr++, data >>= 8 )
+        {
+            byte = data & 0xff;
+            switch(addr) 
+            {
+                /* PM1a_STS register bits are write-to-clear */
+            case PM1a_STS_ADDR:
+                s->pm.pm1a_sts &= ~byte;
+                break;
+            case PM1a_STS_ADDR + 1:
+                s->pm.pm1a_sts &= ~(byte << 8);
+                break;
+                
+            case PM1a_EN_ADDR:
+                s->pm.pm1a_en = (s->pm.pm1a_en & 0xff00) | byte;
+                break;
+            case PM1a_EN_ADDR + 1:
+                s->pm.pm1a_en = (s->pm.pm1a_en & 0xff) | (byte << 8);
+                break;
+                
+            default:
+                gdprintk(XENLOG_WARNING, 
+                         "Bad ACPI PM register write: %"PRIu64
+                         " bytes (%#"PRIx64") at %"PRIx64"\n", 
+                         p->size, p->data, p->addr);
+            }
+        }
+        /* Fix up the SCI state to match the new register state */
+        pmt_update_sci(s);
+    }
+    else /* Read */
+    {
+        data = s->pm.pm1a_sts | (((uint32_t) s->pm.pm1a_en) << 16);
+        data >>= 8 * (p->addr - PM1a_STS_ADDR);
+        if ( p->size == 1 ) data &= 0xff;
+        else if ( p->size == 2 ) data &= 0xffff;
+        p->data = data;
+    }
+    return 1;
+}
+
+
+/* Handle port I/O to the TMR_VAL register */
 static int handle_pmt_io(ioreq_t *p)
 {
     struct vcpu *v = current;
     PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
-    uint64_t curr_gtime;
 
     if (p->size != 4 ||
         p->data_is_ptr ||
@@ -19,12 +179,8 @@ static int handle_pmt_io(ioreq_t *p)
         /* PM_TMR_BLK is read-only */
         return 1;
     } else if (p->dir == 1) { /* read */
-        /* Set the correct value in the timer, accounting for time
-         * elapsed since the last time we did that. */
-        curr_gtime = hvm_get_guest_time(s->vcpu);
-        s->pm.timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
-        p->data = s->pm.timer;
-        s->last_gtime = curr_gtime;
+        pmt_update_time(s);
+        p->data = s->pm.tmr_val;
         return 1;
     }
     return 0;
@@ -33,6 +189,7 @@ static int pmtimer_save(struct domain *d
 static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
 {
     PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+    uint32_t msb = s->pm.tmr_val & TMR_VAL_MSB;
     uint32_t x;
 
     /* Update the counter to the guest's current time.  We always save
@@ -40,7 +197,12 @@ static int pmtimer_save(struct domain *d
      * last_gtime, but just in case, make sure we only go forwards */
     x = ((s->vcpu->arch.hvm_vcpu.guest_time - s->last_gtime) * s->scale) >> 32;
     if ( x < 1UL<<31 )
-        s->pm.timer += x;
+        s->pm.tmr_val += x;
+    if ( (s->pm.tmr_val & TMR_VAL_MSB) != msb )
+        s->pm.pm1a_sts |= TMR_STS;
+    /* No point in setting the SCI here because we'll already have saved the 
+     * IRQ and *PIC state; we'll fix it up when we restore the domain */
+
     return hvm_save_entry(PMTIMER, 0, h, &s->pm);
 }
 
@@ -48,12 +210,15 @@ static int pmtimer_load(struct domain *d
 {
     PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
 
-    /* Reload the counter */
+    /* Reload the registers */
     if ( hvm_load_entry(PMTIMER, h, &s->pm) )
         return -EINVAL;
 
     /* Calculate future counter values from now. */
     s->last_gtime = hvm_get_guest_time(s->vcpu);
+
+    /* Set the SCI state from the registers */ 
+    pmt_update_sci(s);
     
     return 0;
 }
@@ -62,19 +227,30 @@ HVM_REGISTER_SAVE_RESTORE(PMTIMER, pmtim
                           1, HVMSR_PER_DOM);
 
 
-void pmtimer_init(struct vcpu *v, int base)
-{
-    PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
-
-    s->pm.timer = 0;
+void pmtimer_init(struct vcpu *v)
+{
+    PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
+
+    s->pm.tmr_val = 0;
+    s->pm.pm1a_sts = 0;
+    s->pm.pm1a_en = 0;
+
     s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
     s->vcpu = v;
 
-    /* Not implemented: we should set TMR_STS (bit 0 of PM1a_STS) every
-     * time the timer's top bit flips, and generate an SCI if TMR_EN
-     * (bit 0 of PM1a_EN) is set.  For now, those registers are in
-     * qemu-dm, and we just calculate the timer's value on demand. */  
-
-    register_portio_handler(v->domain, base, 4, handle_pmt_io);
-}
-
+    /* Intercept port I/O (need two handlers because PM1a_CNT is between
+     * PM1a_EN and TMR_VAL and is handled by qemu) */
+    register_portio_handler(v->domain, TMR_VAL_ADDR, 4, handle_pmt_io);
+    register_portio_handler(v->domain, PM1a_STS_ADDR, 4, handle_evt_io);
+
+    /* Set up callback to fire SCIs when the MSB of TMR_VAL changes */
+    init_timer(&s->timer, pmt_timer_callback, s, v->processor);
+    pmt_timer_callback(s);
+}
+
+
+void pmtimer_deinit(struct domain *d)
+{
+    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+    kill_timer(&s->timer);
+}
diff -r 16198b57f535 -r 56caf0e37e6a xen/common/schedule.c
--- a/xen/common/schedule.c     Mon Mar 26 09:17:25 2007 -0600
+++ b/xen/common/schedule.c     Mon Mar 26 10:10:31 2007 -0600
@@ -524,6 +524,7 @@ long sched_adjust(struct domain *d, stru
 long sched_adjust(struct domain *d, struct xen_domctl_scheduler_op *op)
 {
     struct vcpu *v;
+    long ret;
     
     if ( (op->sched_id != ops.sched_id) ||
          ((op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) &&
@@ -552,8 +553,8 @@ long sched_adjust(struct domain *d, stru
     if ( d == current->domain )
         vcpu_schedule_lock_irq(current);
 
-    SCHED_OP(adjust, d, op);
-    TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
+    if ( (ret = SCHED_OP(adjust, d, op)) == 0 )
+        TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
 
     if ( d == current->domain )
         vcpu_schedule_unlock_irq(current);
@@ -564,7 +565,7 @@ long sched_adjust(struct domain *d, stru
             vcpu_unpause(v);
     }
 
-    return 0;
+    return ret;
 }
 
 static void vcpu_periodic_timer_work(struct vcpu *v)
diff -r 16198b57f535 -r 56caf0e37e6a xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h      Mon Mar 26 09:17:25 2007 -0600
+++ b/xen/include/asm-x86/hvm/io.h      Mon Mar 26 10:10:31 2007 -0600
@@ -80,7 +80,7 @@ struct hvm_io_op {
     struct cpu_user_regs    io_context; /* current context */
 };
 
-#define MAX_IO_HANDLER              8
+#define MAX_IO_HANDLER              9
 
 #define HVM_PORTIO                  0
 #define HVM_MMIO                    1
diff -r 16198b57f535 -r 56caf0e37e6a xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Mon Mar 26 09:17:25 2007 -0600
+++ b/xen/include/asm-x86/hvm/vpt.h     Mon Mar 26 10:10:31 2007 -0600
@@ -101,6 +101,7 @@ typedef struct PMTState {
     struct vcpu *vcpu;          /* Keeps sync with this vcpu's guest-time */
     uint64_t last_gtime;        /* Last (guest) time we updated the timer */
     uint64_t scale;             /* Multiplier to get from tsc to timer ticks */
+    struct timer timer;         /* To make sure we send SCIs */
 } PMTState;
 
 struct pl_time {    /* platform time */
@@ -132,7 +133,8 @@ void rtc_migrate_timers(struct vcpu *v);
 void rtc_migrate_timers(struct vcpu *v);
 void rtc_deinit(struct domain *d);
 int is_rtc_periodic_irq(void *opaque);
-void pmtimer_init(struct vcpu *v, int base);
+void pmtimer_init(struct vcpu *v);
+void pmtimer_deinit(struct domain *d);
 
 void hpet_migrate_timers(struct vcpu *v);
 void hpet_init(struct vcpu *v);
diff -r 16198b57f535 -r 56caf0e37e6a xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h     Mon Mar 26 09:17:25 2007 -0600
+++ b/xen/include/public/hvm/save.h     Mon Mar 26 10:10:31 2007 -0600
@@ -392,7 +392,9 @@ DECLARE_HVM_SAVE_TYPE(HPET, 12, struct h
  */
 
 struct hvm_hw_pmtimer {
-    uint32_t timer;
+    uint32_t tmr_val;   /* PM_TMR_BLK.TMR_VAL: 24bit free-running counter */
+    uint16_t pm1a_sts;  /* PM1a_EVT_BLK.PM1a_STS: status register */
+    uint16_t pm1a_en;   /* PM1a_EVT_BLK.PM1a_EN: enable register */
 };
 
 DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.