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