WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 28 Mar 2007 10:10:22 -0700
Delivery-date: Wed, 28 Mar 2007 10:10:59 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>