aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>2007-02-04 12:24:53 -0700
committerawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>2007-02-04 12:24:53 -0700
commita6e547a2371e9ceeb2aeb6cf9733f73edb411684 (patch)
treed2d7cd9d69b8ff5fbbf7f3489ddb82755882c68e
parentc4c9842abd9d1a40956ee11433244ff4f73055c1 (diff)
parentec48ab815b556a8f0a2ba9c5287b13fd4cf39607 (diff)
downloadxen-a6e547a2371e9ceeb2aeb6cf9733f73edb411684.tar.gz
xen-a6e547a2371e9ceeb2aeb6cf9733f73edb411684.tar.bz2
xen-a6e547a2371e9ceeb2aeb6cf9733f73edb411684.zip
merge with xen-unstable.hg
-rw-r--r--buildconfigs/linux-defconfig_xen_x86_321
-rw-r--r--docs/xen-api/xenapi-datamodel.tex209
-rw-r--r--extras/mini-os/arch/x86/x86_32.S9
-rw-r--r--extras/mini-os/xenbus/xenbus.c2
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c5
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c5
-rw-r--r--linux-2.6-xen-sparse/include/xen/xenbus.h2
-rw-r--r--patches/linux-2.6.18/xenoprof-generic.patch8
-rw-r--r--tools/Rules.mk2
-rw-r--r--tools/libxc/xc_dom_boot.c39
-rw-r--r--tools/libxc/xc_dom_core.c3
-rw-r--r--tools/libxc/xc_dom_ia64.c6
-rw-r--r--tools/libxc/xc_dom_x86.c4
-rw-r--r--tools/libxc/xc_domain.c36
-rw-r--r--tools/libxc/xc_hvm_restore.c21
-rw-r--r--tools/libxc/xc_hvm_save.c40
-rw-r--r--tools/libxc/xc_linux_save.c2
-rw-r--r--tools/libxc/xenctrl.h12
-rw-r--r--tools/libxen/Makefile3
-rw-r--r--tools/libxen/include/xen_host.h7
-rw-r--r--tools/libxen/include/xen_vdi.h1
-rw-r--r--tools/libxen/include/xen_vm.h53
-rw-r--r--tools/libxen/include/xen_vm_power_state.h5
-rw-r--r--tools/libxen/src/xen_common.c144
-rw-r--r--tools/libxen/src/xen_host.c17
-rw-r--r--tools/libxen/src/xen_int_float_map.c6
-rw-r--r--tools/libxen/src/xen_string_string_map.c6
-rw-r--r--tools/libxen/src/xen_vdi.c3
-rw-r--r--tools/libxen/src/xen_vm.c87
-rw-r--r--tools/libxen/src/xen_vm_power_state.c1
-rw-r--r--tools/libxen/test/test_bindings.c106
-rw-r--r--tools/libxen/test/test_hvm_bindings.c445
-rw-r--r--tools/misc/Makefile2
-rw-r--r--tools/misc/xen-python-path41
-rw-r--r--tools/misc/xend22
-rw-r--r--tools/pygrub/src/pygrub5
-rw-r--r--tools/python/scripts/test_hvm_create.py9
-rw-r--r--tools/python/scripts/test_vm_create.py11
-rw-r--r--tools/python/xen/xend/XendAPI.py64
-rw-r--r--tools/python/xen/xend/XendAPIConstants.py12
-rw-r--r--tools/python/xen/xend/XendBootloader.py4
-rw-r--r--tools/python/xen/xend/XendConfig.py104
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py11
-rw-r--r--tools/python/xen/xend/XendVDI.py15
-rw-r--r--tools/python/xen/xend/image.py76
-rw-r--r--tools/python/xen/xend/server/vfbif.py14
-rw-r--r--tools/python/xen/xm/messages/en/xen-xm.po5
-rw-r--r--tools/xcutils/readnotes.c4
-rw-r--r--tools/xm-test/configure.ac4
-rw-r--r--tools/xm-test/lib/XmTestLib/XenDomain.py3
-rw-r--r--tools/xm-test/lib/XmTestLib/__init__.py20
-rw-r--r--tools/xm-test/tests/vtpm/09_vtpm-xapi.py3
-rw-r--r--xen/arch/x86/dmi_scan.c2
-rw-r--r--xen/arch/x86/domctl.c62
-rw-r--r--xen/arch/x86/hvm/hpet.c42
-rw-r--r--xen/arch/x86/hvm/intercept.c6
-rw-r--r--xen/arch/x86/hvm/svm/svm.c10
-rw-r--r--xen/arch/x86/hvm/vlapic.c1
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c7
-rw-r--r--xen/arch/x86/traps.c5
-rw-r--r--xen/arch/x86/x86_64/compat/entry.S7
-rw-r--r--xen/common/kexec.c23
-rw-r--r--xen/common/perfc.c17
-rw-r--r--xen/include/asm-x86/cpufeature.h1
-rw-r--r--xen/include/asm-x86/hvm/domain.h2
-rw-r--r--xen/include/asm-x86/hvm/hvm.h11
-rw-r--r--xen/include/asm-x86/hvm/support.h7
-rw-r--r--xen/include/asm-x86/hvm/vpt.h25
-rw-r--r--xen/include/public/arch-x86/xen-x86_32.h2
-rw-r--r--xen/include/public/domctl.h11
-rw-r--r--xen/include/public/foreign/Makefile10
-rw-r--r--xen/include/public/hvm/save.h32
-rw-r--r--xen/include/xen/string.h12
-rw-r--r--xen/tools/get-fields.sh4
74 files changed, 1561 insertions, 457 deletions
diff --git a/buildconfigs/linux-defconfig_xen_x86_32 b/buildconfigs/linux-defconfig_xen_x86_32
index 328b86d938..8a793de380 100644
--- a/buildconfigs/linux-defconfig_xen_x86_32
+++ b/buildconfigs/linux-defconfig_xen_x86_32
@@ -1268,6 +1268,7 @@ CONFIG_IEEE1394_RAWIO=m
CONFIG_I2O=m
CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
CONFIG_I2O_CONFIG=m
CONFIG_I2O_CONFIG_OLD_IOCTL=y
CONFIG_I2O_BUS=m
diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex
index edfb8890bd..ee34fc7160 100644
--- a/docs/xen-api/xenapi-datamodel.tex
+++ b/docs/xen-api/xenapi-datamodel.tex
@@ -142,7 +142,6 @@ The following enumeration types are used:
\hspace{0.5cm}{\tt Paused} & Paused \\
\hspace{0.5cm}{\tt Running} & Running \\
\hspace{0.5cm}{\tt Suspended} & Suspended \\
-\hspace{0.5cm}{\tt ShuttingDown} & Shutting Down \\
\hspace{0.5cm}{\tt Unknown} & Some other unknown state \\
\hline
\end{longtable}
@@ -1026,9 +1025,9 @@ references to objects with match names
virtual machine (or 'guest').
VM booting is controlled by setting one of the two mutually exclusive
-groups: "PV", and "HVM". If HVM.boot is the empty string, then paravirtual
-domain building and booting will be used; otherwise the VM will be loaded
-as an HVM domain, and booted using an emulated BIOS.
+groups: "PV", and "HVM". If HVM.boot\_policy is the empty string, then
+paravirtual domain building and booting will be used; otherwise the VM will
+be loaded as an HVM domain, and booted using an emulated BIOS.
When paravirtual booting is in use, the PV/bootloader field indicates the
bootloader to use. It may be "pygrub", in which case the platform's
@@ -1053,7 +1052,10 @@ ramdisk values will be treated as paths within the control domain. If both
PV/bootloader and PV/kernel are empty, then the behaviour is as if
PV/bootloader was specified as "pygrub".
-When using HVM booting, HVM/boot specifies the order of the boot devices.}} \\
+When using HVM booting, HVM/boot\_policy and HVM/boot\_params specify the
+boot handling. Only one policy is currently defined: "BIOS order". In
+this case, HVM/boot\_params should contain one key-value pair "order" = "N"
+where N is the string that will be passed to QEMU.}} \\
\hline
Quals & Field & Type & Description \\
\hline
@@ -1089,7 +1091,8 @@ $\mathit{RW}$ & {\tt PV/kernel} & string & path to the kernel \\
$\mathit{RW}$ & {\tt PV/ramdisk} & string & path to the initrd \\
$\mathit{RW}$ & {\tt PV/args} & string & kernel command-line arguments \\
$\mathit{RW}$ & {\tt PV/bootloader\_args} & string & miscellaneous arguments for the bootloader \\
-$\mathit{RW}$ & {\tt HVM/boot} & string & device boot order \\
+$\mathit{RW}$ & {\tt HVM/boot\_policy} & string & HVM boot policy \\
+$\mathit{RW}$ & {\tt HVM/boot\_params} & (string $\rightarrow$ string) Map & HVM boot params \\
$\mathit{RW}$ & {\tt platform/std\_VGA} & bool & emulate standard VGA instead of cirrus logic \\
$\mathit{RW}$ & {\tt platform/serial} & string & redirect serial port to pty \\
$\mathit{RW}$ & {\tt platform/localtime} & bool & set RTC to local time \\
@@ -3297,13 +3300,13 @@ void
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~get\_HVM\_boot}
+\subsubsection{RPC name:~get\_HVM\_boot\_policy}
{\bf Overview:}
-Get the HVM/boot field of the given VM.
+Get the HVM/boot\_policy field of the given VM.
\noindent {\bf Signature:}
-\begin{verbatim} string get_HVM_boot (session_id s, VM ref self)\end{verbatim}
+\begin{verbatim} string get_HVM_boot_policy (session_id s, VM ref self)\end{verbatim}
\noindent{\bf Arguments:}
@@ -3329,13 +3332,13 @@ value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~set\_HVM\_boot}
+\subsubsection{RPC name:~set\_HVM\_boot\_policy}
{\bf Overview:}
-Set the HVM/boot field of the given VM.
+Set the HVM/boot\_policy field of the given VM.
\noindent {\bf Signature:}
-\begin{verbatim} void set_HVM_boot (session_id s, VM ref self, string value)\end{verbatim}
+\begin{verbatim} void set_HVM_boot_policy (session_id s, VM ref self, string value)\end{verbatim}
\noindent{\bf Arguments:}
@@ -3363,6 +3366,143 @@ void
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
+\subsubsection{RPC name:~get\_HVM\_boot\_params}
+
+{\bf Overview:}
+Get the HVM/boot\_params field of the given VM.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} ((string -> string) Map) get_HVM_boot_params (session_id s, VM 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 ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \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:~set\_HVM\_boot\_params}
+
+{\bf Overview:}
+Set the HVM/boot\_params field of the given VM.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_HVM_boot_params (session_id s, VM ref self, (string -> string) Map value)\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 & reference to the object \\ \hline
+
+{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~add\_to\_HVM\_boot\_params}
+
+{\bf Overview:}
+Add the given key-value pair to the HVM/boot\_params field of the given VM.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void add_to_HVM_boot_params (session_id s, VM ref self, string key, string value)\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 & reference to the object \\ \hline
+
+{\tt string } & key & Key to add \\ \hline
+
+{\tt string } & value & Value to add \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~remove\_from\_HVM\_boot\_params}
+
+{\bf Overview:}
+Remove the given key and its corresponding value from the HVM/boot\_params
+field of the given VM. If the key is not in that Map, then do nothing.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void remove_from_HVM_boot_params (session_id s, VM ref self, string key)\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 & reference to the object \\ \hline
+
+{\tt string } & key & Key to remove \\ \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\_platform\_std\_VGA}
{\bf Overview:}
@@ -4524,10 +4664,42 @@ void
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
+\subsubsection{RPC name:~dmesg}
+
+{\bf Overview:}
+Get the host xen dmesg.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string dmesg (session_id s, host ref host)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt host ref } & host & The Host to query \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+string
+}
+
+
+dmesg string
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
\subsubsection{RPC name:~get\_all}
{\bf Overview:}
-Return a list of all the hosts known to the system
+Return a list of all the hosts known to the system.
\noindent {\bf Signature:}
\begin{verbatim} ((host ref) Set) get_all (session_id s)\end{verbatim}
@@ -11758,6 +11930,17 @@ The handle parameter echoes the bad value given.
\begin{verbatim}TASK_HANDLE_INVALID(handle)\end{verbatim}
\begin{center}\rule{10em}{0.1pt}\end{center}
+\subsubsection{VALUE\_NOT\_SUPPORTED}
+
+You attempted to set a value that is not supported by this implementation.
+The fully-qualified field name and the value that you tried to set are
+returned. Also returned is a developer-only diagnostic reason.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}VALUE_NOT_SUPPORTED(field, value, reason)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
\subsubsection{VBD\_HANDLE\_INVALID}
You gave an invalid VBD handle. The VBD may have recently been deleted.
diff --git a/extras/mini-os/arch/x86/x86_32.S b/extras/mini-os/arch/x86/x86_32.S
index 46fce169ca..b10bc23401 100644
--- a/extras/mini-os/arch/x86/x86_32.S
+++ b/extras/mini-os/arch/x86/x86_32.S
@@ -69,7 +69,7 @@ CS = 0x2C
popl %ds; \
popl %es; \
addl $4,%esp; \
- iret; \
+ iret;
ENTRY(divide_error)
pushl $0 # no error code
@@ -101,10 +101,9 @@ do_exception:
jmp ret_from_exception
ret_from_exception:
- movb CS(%esp),%cl
- test $2,%cl # slow return to ring 2 or 3
- jne safesti
- RESTORE_ALL
+ movb CS(%esp),%cl
+ addl $8,%esp
+ RESTORE_ALL
# A note on the "critical region" in our callback handler.
# We want to avoid stacking callback handlers due to events occurring
diff --git a/extras/mini-os/xenbus/xenbus.c b/extras/mini-os/xenbus/xenbus.c
index 1a0f0e048f..f2428c12fa 100644
--- a/extras/mini-os/xenbus/xenbus.c
+++ b/extras/mini-os/xenbus/xenbus.c
@@ -178,6 +178,7 @@ static void release_xenbus_id(int id)
BUG_ON(!req_info[id].in_use);
spin_lock(&req_lock);
nr_live_reqs--;
+ req_info[id].in_use = 0;
if (nr_live_reqs == NR_REQS - 1)
wake_up(&req_wq);
spin_unlock(&req_lock);
@@ -212,6 +213,7 @@ static int allocate_xenbus_id(void)
probe = o_probe + 1;
spin_unlock(&req_lock);
init_waitqueue_head(&req_info[o_probe].waitq);
+
return o_probe;
}
diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
index f54cc84b89..bd86948fed 100644
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
@@ -1935,8 +1935,6 @@ static struct net_device * __devinit create_netdev(struct xenbus_device *dev)
np = netdev_priv(netdev);
np->xbdev = dev;
- netif_carrier_off(netdev);
-
spin_lock_init(&np->tx_lock);
spin_lock_init(&np->rx_lock);
@@ -1991,6 +1989,9 @@ static struct net_device * __devinit create_netdev(struct xenbus_device *dev)
SET_NETDEV_DEV(netdev, &dev->dev);
np->netdev = netdev;
+
+ netif_carrier_off(netdev);
+
return netdev;
exit_free_tx:
diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
index f294ec1cc9..49878d17e0 100644
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
@@ -42,9 +42,9 @@
#define DPRINTK(fmt, args...) \
pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-char *xenbus_strstate(enum xenbus_state state)
+const char *xenbus_strstate(enum xenbus_state state)
{
- static char *name[] = {
+ static const char *const name[] = {
[ XenbusStateUnknown ] = "Unknown",
[ XenbusStateInitialising ] = "Initialising",
[ XenbusStateInitWait ] = "InitWait",
@@ -55,6 +55,7 @@ char *xenbus_strstate(enum xenbus_state state)
};
return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
}
+EXPORT_SYMBOL_GPL(xenbus_strstate);
int xenbus_watch_path(struct xenbus_device *dev, const char *path,
struct xenbus_watch *watch,
diff --git a/linux-2.6-xen-sparse/include/xen/xenbus.h b/linux-2.6-xen-sparse/include/xen/xenbus.h
index a26ca12820..cbf6fe351d 100644
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h
@@ -295,7 +295,7 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
int __init xenbus_dev_init(void);
-char *xenbus_strstate(enum xenbus_state state);
+const char *xenbus_strstate(enum xenbus_state state);
int xenbus_dev_is_online(struct xenbus_device *dev);
int xenbus_frontend_closed(struct xenbus_device *dev);
diff --git a/patches/linux-2.6.18/xenoprof-generic.patch b/patches/linux-2.6.18/xenoprof-generic.patch
index 0e05586df1..d2542b2d13 100644
--- a/patches/linux-2.6.18/xenoprof-generic.patch
+++ b/patches/linux-2.6.18/xenoprof-generic.patch
@@ -363,9 +363,9 @@ diff -pruN ../orig-linux-2.6.18/drivers/oprofile/oprof.c ./drivers/oprofile/opro
+ if (!oprofile_ops.set_active)
+ return -EINVAL;
+
-+ down(&start_sem);
++ mutex_lock(&start_mutex);
+ err = oprofile_ops.set_active(active_domains, adomains);
-+ up(&start_sem);
++ mutex_unlock(&start_mutex);
+ return err;
+}
+
@@ -376,9 +376,9 @@ diff -pruN ../orig-linux-2.6.18/drivers/oprofile/oprof.c ./drivers/oprofile/opro
+ if (!oprofile_ops.set_passive)
+ return -EINVAL;
+
-+ down(&start_sem);
++ mutex_lock(&start_mutex);
+ err = oprofile_ops.set_passive(passive_domains, pdomains);
-+ up(&start_sem);
++ mutex_unlock(&start_mutex);
+ return err;
+}
+
diff --git a/tools/Rules.mk b/tools/Rules.mk
index af530ac65d..df3b231a1a 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -56,6 +56,6 @@ mk-symlinks-xen:
( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/Makefile . )
( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/reference.size . )
( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/*.py . )
- make -C xen/foreign
+ $(MAKE) -C xen/foreign
mk-symlinks: mk-symlinks-xen mk-symlinks-$(XEN_OS)
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index d8bfe485d8..83b1abe1eb 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -144,7 +144,7 @@ static int x86_shadow(int xc, domid_t domid)
return rc;
}
-static int arch_setup_early(struct xc_dom_image *dom)
+static int arch_setup_meminit(struct xc_dom_image *dom)
{
int rc = 0;
@@ -157,13 +157,13 @@ static int arch_setup_early(struct xc_dom_image *dom)
return rc;
}
-static int arch_setup_middle(struct xc_dom_image *dom)
+static int arch_setup_bootearly(struct xc_dom_image *dom)
{
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
return 0;
}
-static int arch_setup_late(struct xc_dom_image *dom)
+static int arch_setup_bootlate(struct xc_dom_image *dom)
{
static const struct {
char *guest;
@@ -263,13 +263,13 @@ static int arch_setup_late(struct xc_dom_image *dom)
#elif defined(__ia64__)
-static int arch_setup_early(struct xc_dom_image *dom)
+static int arch_setup_meminit(struct xc_dom_image *dom)
{
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
return 0;
}
-static int arch_setup_middle(struct xc_dom_image *dom)
+static int arch_setup_bootearly(struct xc_dom_image *dom)
{
DECLARE_DOMCTL;
int rc;
@@ -281,10 +281,6 @@ static int arch_setup_middle(struct xc_dom_image *dom)
domctl.domain = dom->guest_domid;
domctl.u.arch_setup.flags = 0;
- /* dom->start_info_pfn should be initialized by alloc_magic_pages().
- * However it is called later. So we initialize here.
- */
- dom->start_info_pfn = dom->total_pages - 3;
domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT)
+ sizeof(start_info_t);
/* 3 = start info page, xenstore page and console page */
@@ -293,7 +289,7 @@ static int arch_setup_middle(struct xc_dom_image *dom)
return rc;
}
-static int arch_setup_late(struct xc_dom_image *dom)
+static int arch_setup_bootlate(struct xc_dom_image *dom)
{
unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
shared_info_t *shared_info;
@@ -317,19 +313,19 @@ static int arch_setup_late(struct xc_dom_image *dom)
#elif defined(__powerpc64__)
-static int arch_setup_early(struct xc_dom_image *dom)
+static int arch_setup_meminit(struct xc_dom_image *dom)
{
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
return 0;
}
-static int arch_setup_middle(struct xc_dom_image *dom)
+static int arch_setup_bootearly(struct xc_dom_image *dom)
{
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
return 0;
}
-static int arch_setup_late(struct xc_dom_image *dom)
+static int arch_setup_bootlate(struct xc_dom_image *dom)
{
start_info_t *si =
xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1);
@@ -355,19 +351,19 @@ static int arch_setup_late(struct xc_dom_image *dom)
#else
-static int arch_setup_early(struct xc_dom_image *dom)
+static int arch_setup_meminit(struct xc_dom_image *dom)
{
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
return 0;
}
-static int arch_setup_middle(struct xc_dom_image *dom)
+static int arch_setup_bootearly(struct xc_dom_image *dom)
{
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
return 0;
}
-static int arch_setup_late(struct xc_dom_image *dom)
+static int arch_setup_bootlate(struct xc_dom_image *dom)
{
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
return 0;
@@ -423,7 +419,7 @@ int xc_dom_boot_mem_init(struct xc_dom_image *dom)
xc_dom_printf("%s: called\n", __FUNCTION__);
- if (0 != (rc = arch_setup_early(dom)))
+ if (0 != (rc = arch_setup_meminit(dom)))
return rc;
/* allocate guest memory */
@@ -438,9 +434,6 @@ int xc_dom_boot_mem_init(struct xc_dom_image *dom)
return rc;
}
- if (0 != (rc = arch_setup_middle(dom)))
- return rc;
-
return 0;
}
@@ -497,6 +490,10 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
xc_dom_printf("%s: called\n", __FUNCTION__);
+ /* misc ia64 stuff*/
+ if (0 != (rc = arch_setup_bootearly(dom)))
+ return rc;
+
/* collect some info */
domctl.cmd = XEN_DOMCTL_getdomaininfo;
domctl.domain = dom->guest_domid;
@@ -542,7 +539,7 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
xc_dom_log_memory_footprint(dom);
/* misc x86 stuff */
- if (0 != (rc = arch_setup_late(dom)))
+ if (0 != (rc = arch_setup_bootlate(dom)))
return rc;
/* let the vm run */
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
index 8d329ae74f..ae64972ed5 100644
--- a/tools/libxc/xc_dom_core.c
+++ b/tools/libxc/xc_dom_core.c
@@ -717,6 +717,9 @@ int xc_dom_build_image(struct xc_dom_image *dom)
}
page_size = XC_DOM_PAGE_SIZE(dom);
+ /* 4MB align virtual base address */
+ dom->parms.virt_base &= ~(((uint64_t)1<<22)-1);
+
/* load kernel */
if (0 != xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel",
dom->kernel_seg.vstart,
diff --git a/tools/libxc/xc_dom_ia64.c b/tools/libxc/xc_dom_ia64.c
index c6e4424515..2ffce5a4d7 100644
--- a/tools/libxc/xc_dom_ia64.c
+++ b/tools/libxc/xc_dom_ia64.c
@@ -26,11 +26,7 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
/* allocate special pages */
dom->console_pfn = dom->total_pages -1;
dom->xenstore_pfn = dom->total_pages -2;
-
- /*
- * this is initialized by arch_setup_middle().
- * dom->start_info_pfn = dom->total_pages -3;
- */
+ dom->start_info_pfn = dom->total_pages -3;
return 0;
}
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index 9e489c320d..fdc3d4ba5e 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -66,11 +66,12 @@ static int count_pgtables(struct xc_dom_image *dom, int pae,
extra_pages = dom->alloc_bootstack ? 1 : 0;
extra_pages += dom->extra_pages;
+ extra_pages += 128; /* 512kB padding */
pages = extra_pages;
for (;;)
{
try_virt_end = round_up(dom->virt_alloc_end + pages * PAGE_SIZE_X86,
- bits_to_mask(l1_bits));
+ bits_to_mask(22)); /* 4MB alignment */
dom->pg_l4 =
nr_page_tables(dom->parms.virt_base, try_virt_end, l4_bits);
dom->pg_l3 =
@@ -313,6 +314,7 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
if (xc_dom_feature_translated(dom))
dom->shared_info_pfn = xc_dom_alloc_page(dom, "shared info");
dom->alloc_bootstack = 1;
+
return 0;
}
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 6b67450261..e557f43f13 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -241,45 +241,49 @@ int xc_domain_getinfolist(int xc_handle,
/* get info from hvm guest for save */
int xc_domain_hvm_getcontext(int xc_handle,
uint32_t domid,
- hvm_domain_context_t *hvm_ctxt)
+ uint8_t *ctxt_buf,
+ uint32_t size)
{
- int rc;
+ int ret;
DECLARE_DOMCTL;
domctl.cmd = XEN_DOMCTL_gethvmcontext;
domctl.domain = (domid_t)domid;
- set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt);
+ domctl.u.hvmcontext.size = size;
+ set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
- if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 )
- return rc;
+ if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
+ return ret;
- rc = do_domctl(xc_handle, &domctl);
+ ret = do_domctl(xc_handle, &domctl);
- safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt));
+ unlock_pages(ctxt_buf, size);
- return rc;
+ return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
}
/* set info to hvm guest for restore */
int xc_domain_hvm_setcontext(int xc_handle,
uint32_t domid,
- hvm_domain_context_t *hvm_ctxt)
+ uint8_t *ctxt_buf,
+ uint32_t size)
{
- int rc;
+ int ret;
DECLARE_DOMCTL;
domctl.cmd = XEN_DOMCTL_sethvmcontext;
domctl.domain = domid;
- set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt);
+ domctl.u.hvmcontext.size = size;
+ set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
- if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 )
- return rc;
+ if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
+ return ret;
- rc = do_domctl(xc_handle, &domctl);
+ ret = do_domctl(xc_handle, &domctl);
- safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt));
+ unlock_pages(ctxt_buf, size);
- return rc;
+ return ret;
}
int xc_vcpu_getcontext(int xc_handle,
diff --git a/tools/libxc/xc_hvm_restore.c b/tools/libxc/xc_hvm_restore.c
index b2b9999fea..6622b49f79 100644
--- a/tools/libxc/xc_hvm_restore.c
+++ b/tools/libxc/xc_hvm_restore.c
@@ -87,7 +87,7 @@ int xc_hvm_restore(int xc_handle, int io_fd,
xc_dominfo_t info;
unsigned int rc = 1, n, i;
uint32_t rec_len, nr_vcpus;
- hvm_domain_context_t hvm_ctxt;
+ uint8_t *hvm_buf = NULL;
unsigned long long v_end, memsize;
unsigned long shared_page_nr;
@@ -128,8 +128,7 @@ int xc_hvm_restore(int xc_handle, int io_fd,
}
- p2m = malloc(max_pfn * sizeof(xen_pfn_t));
-
+ p2m = malloc(max_pfn * sizeof(xen_pfn_t));
if (p2m == NULL) {
ERROR("memory alloc failed");
errno = ENOMEM;
@@ -297,18 +296,21 @@ int xc_hvm_restore(int xc_handle, int io_fd,
ERROR("error read hvm context size!\n");
goto out;
}
- if (rec_len != sizeof(hvm_ctxt)) {
- ERROR("hvm context size dismatch!\n");
+
+ hvm_buf = malloc(rec_len);
+ if (hvm_buf == NULL) {
+ ERROR("memory alloc for hvm context buffer failed");
+ errno = ENOMEM;
goto out;
}
- if (!read_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt))) {
- ERROR("error read hvm context!\n");
+ if (!read_exact(io_fd, hvm_buf, rec_len)) {
+ ERROR("error read hvm buffer!\n");
goto out;
}
- if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, &hvm_ctxt))) {
- ERROR("error set hvm context!\n");
+ if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_len))) {
+ ERROR("error set hvm buffer!\n");
goto out;
}
@@ -361,6 +363,7 @@ int xc_hvm_restore(int xc_handle, int io_fd,
if ( (rc != 0) && (dom != 0) )
xc_domain_destroy(xc_handle, dom);
free(p2m);
+ free(hvm_buf);
DPRINTF("Restore exit with rc=%d\n", rc);
diff --git a/tools/libxc/xc_hvm_save.c b/tools/libxc/xc_hvm_save.c
index 3d08a509d9..d9cca58d07 100644
--- a/tools/libxc/xc_hvm_save.c
+++ b/tools/libxc/xc_hvm_save.c
@@ -33,6 +33,12 @@
#include "xg_save_restore.h"
/*
+ * Size of a buffer big enough to take the HVM state of a domain.
+ * Ought to calculate this a bit more carefully, or maybe ask Xen.
+ */
+#define HVM_CTXT_SIZE 8192
+
+/*
** Default values for important tuning parameters. Can override by passing
** non-zero replacement values to xc_hvm_save().
**
@@ -279,8 +285,8 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
unsigned long *pfn_type = NULL;
unsigned long *pfn_batch = NULL;
- /* A copy of hvm domain context */
- hvm_domain_context_t hvm_ctxt;
+ /* A copy of hvm domain context buffer*/
+ uint8_t *hvm_buf = NULL;
/* Live mapping of shared info structure */
shared_info_t *live_shinfo = NULL;
@@ -423,8 +429,12 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
to_send = malloc(BITMAP_SIZE);
to_skip = malloc(BITMAP_SIZE);
- if (!to_send ||!to_skip) {
- ERROR("Couldn't allocate to_send array");
+ page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn);
+
+ hvm_buf = malloc(HVM_CTXT_SIZE);
+
+ if (!to_send ||!to_skip ||!page_array ||!hvm_buf ) {
+ ERROR("Couldn't allocate memory");
goto out;
}
@@ -444,11 +454,6 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
analysis_phase(xc_handle, dom, max_pfn, to_skip, 0);
/* get all the HVM domain pfns */
- if ( (page_array = (unsigned long *) malloc (sizeof(unsigned long) * max_pfn)) == NULL) {
- ERROR("HVM:malloc fail!\n");
- goto out;
- }
-
for ( i = 0; i < max_pfn; i++)
page_array[i] = i;
@@ -655,24 +660,18 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
goto out;
}
- /* save hvm hypervisor state including pic/pit/shpage */
- if (mlock(&hvm_ctxt, sizeof(hvm_ctxt))) {
- ERROR("Unable to mlock ctxt");
- return 1;
- }
-
- if (xc_domain_hvm_getcontext(xc_handle, dom, &hvm_ctxt)){
- ERROR("HVM:Could not get hvm context");
+ if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf,
+ HVM_CTXT_SIZE)) == -1) {
+ ERROR("HVM:Could not get hvm buffer");
goto out;
}
- rec_size = sizeof(hvm_ctxt);
if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) {
- ERROR("error write hvm ctxt size");
+ ERROR("error write hvm buffer size");
goto out;
}
- if ( !write_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt)) ) {
+ if ( !write_exact(io_fd, hvm_buf, rec_size) ) {
ERROR("write HVM info failed!\n");
}
@@ -722,6 +721,7 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
}
}
+ free(hvm_buf);
free(page_array);
free(pfn_type);
diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c
index de1c605002..0d8f045951 100644
--- a/tools/libxc/xc_linux_save.c
+++ b/tools/libxc/xc_linux_save.c
@@ -536,8 +536,6 @@ static int canonicalize_pagetable(unsigned long type, unsigned long pfn,
if (!MFN_IS_IN_PSEUDOPHYS_MAP(mfn)) {
/* This will happen if the type info is stale which
is quite feasible under live migration */
- DPRINTF("PT Race: [%08lx,%d] pte=%llx, mfn=%08lx\n",
- type, i, (unsigned long long)pte, mfn);
pfn = 0; /* zap it - we'll retransmit this page later */
race = 1; /* inform the caller of race; fatal if !live */
} else
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 26cd638db5..14704e2e92 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -328,13 +328,15 @@ int xc_domain_getinfolist(int xc_handle,
* This function returns information about the context of a hvm domain
* @parm xc_handle a handle to an open hypervisor interface
* @parm domid the domain to get information from
- * @parm hvm_ctxt a pointer to a structure to store the execution context of the
- * hvm domain
+ * @parm ctxt_buf a pointer to a structure to store the execution context of
+ * the hvm domain
+ * @parm size the size of ctxt_buf in bytes
* @return 0 on success, -1 on failure
*/
int xc_domain_hvm_getcontext(int xc_handle,
uint32_t domid,
- hvm_domain_context_t *hvm_ctxt);
+ uint8_t *ctxt_buf,
+ uint32_t size);
/**
* This function will set the context for hvm domain
@@ -342,11 +344,13 @@ int xc_domain_hvm_getcontext(int xc_handle,
* @parm xc_handle a handle to an open hypervisor interface
* @parm domid the domain to set the hvm domain context for
* @parm hvm_ctxt pointer to the the hvm context with the values to set
+ * @parm size the size of hvm_ctxt in bytes
* @return 0 on success, -1 on failure
*/
int xc_domain_hvm_setcontext(int xc_handle,
uint32_t domid,
- hvm_domain_context_t *hvm_ctxt);
+ uint8_t *hvm_ctxt,
+ uint32_t size);
/**
* This function returns information about the execution context of a
diff --git a/tools/libxen/Makefile b/tools/libxen/Makefile
index c72206442a..e2eeda74d8 100644
--- a/tools/libxen/Makefile
+++ b/tools/libxen/Makefile
@@ -51,6 +51,9 @@ libxenapi.a: $(LIBXENAPI_OBJS)
test/test_bindings: test/test_bindings.o libxenapi.so
$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
+test/test_hvm_bindings: test/test_hvm_bindings.o libxenapi.so
+ $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
+
.PHONY: install
install: all
diff --git a/tools/libxen/include/xen_host.h b/tools/libxen/include/xen_host.h
index e64390b89f..26ca29d592 100644
--- a/tools/libxen/include/xen_host.h
+++ b/tools/libxen/include/xen_host.h
@@ -394,6 +394,13 @@ xen_host_reboot(xen_session *session, xen_host host);
/**
+ * Get the host xen dmesg.
+ */
+extern bool
+xen_host_dmesg(xen_session *session, char **result, xen_host host);
+
+
+/**
* Return a list of all the hosts known to the system.
*/
extern bool
diff --git a/tools/libxen/include/xen_vdi.h b/tools/libxen/include/xen_vdi.h
index d72eceb001..8533df31a8 100644
--- a/tools/libxen/include/xen_vdi.h
+++ b/tools/libxen/include/xen_vdi.h
@@ -74,6 +74,7 @@ typedef struct xen_vdi_record
int64_t virtual_size;
int64_t physical_utilisation;
int64_t sector_size;
+ char *location;
enum xen_vdi_type type;
bool sharable;
bool read_only;
diff --git a/tools/libxen/include/xen_vm.h b/tools/libxen/include/xen_vm.h
index 7a56ba482e..3c23784cf5 100644
--- a/tools/libxen/include/xen_vm.h
+++ b/tools/libxen/include/xen_vm.h
@@ -42,9 +42,9 @@
* A virtual machine (or 'guest').
*
* VM booting is controlled by setting one of the two mutually exclusive
- * groups: "PV", and "HVM". If HVM.boot is the empty string, then paravirtual
- * domain building and booting will be used; otherwise the VM will be loaded
- * as an HVM domain, and booted using an emulated BIOS.
+ * groups: "PV", and "HVM". If HVM.boot_policy is the empty string, then
+ * paravirtual domain building and booting will be used; otherwise the VM will
+ * be loaded as an HVM domain, and booted using an emulated BIOS.
*
* When paravirtual booting is in use, the PV/bootloader field indicates the
* bootloader to use. It may be "pygrub", in which case the platform's
@@ -69,7 +69,10 @@
* PV/bootloader and PV/kernel are empty, then the behaviour is as if
* PV/bootloader was specified as "pygrub".
*
- * When using HVM booting, HVM/boot specifies the order of the boot devices.
+ * When using HVM booting, HVM/boot_policy and HVM/boot_params specify the
+ * boot handling. Only one policy is currently defined: "BIOS order". In
+ * this case, HVM/boot_params should contain one key-value pair "order" = "N"
+ * where N is the string that will be passed to QEMU..
*/
@@ -136,7 +139,8 @@ typedef struct xen_vm_record
char *pv_ramdisk;
char *pv_args;
char *pv_bootloader_args;
- char *hvm_boot;
+ char *hvm_boot_policy;
+ xen_string_string_map *hvm_boot_params;
bool platform_std_vga;
char *platform_serial;
bool platform_localtime;
@@ -490,10 +494,17 @@ xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm);
/**
- * Get the HVM/boot field of the given VM.
+ * Get the HVM/boot_policy field of the given VM.
*/
extern bool
-xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm);
+xen_vm_get_hvm_boot_policy(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the HVM/boot_params field of the given VM.
+ */
+extern bool
+xen_vm_get_hvm_boot_params(xen_session *session, xen_string_string_map **result, xen_vm vm);
/**
@@ -731,10 +742,34 @@ xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char *bootloader_
/**
- * Set the HVM/boot field of the given VM.
+ * Set the HVM/boot_policy field of the given VM.
+ */
+extern bool
+xen_vm_set_hvm_boot_policy(xen_session *session, xen_vm vm, char *boot_policy);
+
+
+/**
+ * Set the HVM/boot_params field of the given VM.
+ */
+extern bool
+xen_vm_set_hvm_boot_params(xen_session *session, xen_vm vm, xen_string_string_map *boot_params);
+
+
+/**
+ * Add the given key-value pair to the HVM/boot_params field of the
+ * given VM.
+ */
+extern bool
+xen_vm_add_to_hvm_boot_params(xen_session *session, xen_vm vm, char *key, char *value);
+
+
+/**
+ * Remove the given key and its corresponding value from the
+ * HVM/boot_params field of the given VM. If the key is not in that Map, then
+ * do nothing.
*/
extern bool
-xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot);
+xen_vm_remove_from_hvm_boot_params(xen_session *session, xen_vm vm, char *key);
/**
diff --git a/tools/libxen/include/xen_vm_power_state.h b/tools/libxen/include/xen_vm_power_state.h
index 3e805ed671..c5404b89cf 100644
--- a/tools/libxen/include/xen_vm_power_state.h
+++ b/tools/libxen/include/xen_vm_power_state.h
@@ -46,11 +46,6 @@ enum xen_vm_power_state
XEN_VM_POWER_STATE_SUSPENDED,
/**
- * Shutting Down
- */
- XEN_VM_POWER_STATE_SHUTTINGDOWN,
-
- /**
* Some other unknown state
*/
XEN_VM_POWER_STATE_UNKNOWN
diff --git a/tools/libxen/src/xen_common.c b/tools/libxen/src/xen_common.c
index 9834565ff0..8c5feeb33f 100644
--- a/tools/libxen/src/xen_common.c
+++ b/tools/libxen/src/xen_common.c
@@ -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
@@ -86,6 +86,8 @@ static xmlNode *
add_param_struct(xmlNode *);
static xmlNode *
add_struct_array(xmlNode *, const char *);
+static xmlNode *
+add_nested_struct(xmlNode *, const char *);
static void
add_struct_member(xmlNode *, const char *, const char *, const char *);
static void
@@ -107,6 +109,9 @@ parse_structmap_value(xen_session *, xmlNode *, const abstract_type *,
static size_t size_of_member(const abstract_type *);
+static const char *
+get_val_as_string(const struct abstract_type *, void *, char *);
+
void
xen_init(void)
@@ -1174,37 +1179,12 @@ add_struct_value(const struct abstract_type *type, void *value,
switch (type->typename)
{
case REF:
- {
- arbitrary_record_opt *val = *(arbitrary_record_opt **)value;
- if (val != NULL)
- {
- if (val->is_record)
- {
- adder(node, key, "string", val->u.record->handle);
- }
- else
- {
- adder(node, key, "string", val->u.handle);
- }
- }
- }
- break;
-
case STRING:
- {
- char *val = *(char **)value;
- if (val != NULL)
- {
- adder(node, key, "string", val);
- }
- }
- break;
-
case INT:
+ case ENUM:
{
- int64_t val = *(int64_t *)value;
- snprintf(buf, sizeof(buf), "%"PRId64, val);
- adder(node, key, "string", buf);
+ const char *val_as_string = get_val_as_string(type, value, buf);
+ adder(node, key, "string", val_as_string);
}
break;
@@ -1223,13 +1203,6 @@ add_struct_value(const struct abstract_type *type, void *value,
}
break;
- case ENUM:
- {
- int val = *(int *)value;
- adder(node, key, "string", type->enum_marshaller(val));
- }
- break;
-
case SET:
{
const struct abstract_type *member_type = type->child;
@@ -1251,12 +1224,95 @@ add_struct_value(const struct abstract_type *type, void *value,
break;
case STRUCT:
- case MAP:
{
+ assert(false);
/* XXX Nested structures aren't supported yet, but
fortunately we don't need them, because we don't have
any "deep create" calls. This will need to be
- fixed. We don't need maps either. */
+ fixed. */
+ }
+ break;
+
+ case MAP:
+ {
+ size_t member_size = type->struct_size;
+ const struct abstract_type *l_type = type->members[0].type;
+ const struct abstract_type *r_type = type->members[1].type;
+ int l_offset = type->members[0].offset;
+ int r_offset = type->members[1].offset;
+
+ arbitrary_map *map_val = *(arbitrary_map **)value;
+
+ if (map_val != NULL)
+ {
+ xmlNode *struct_node = add_nested_struct(node, key);
+
+ for (size_t i = 0; i < map_val->size; i++)
+ {
+ void *contents = (void *)map_val->contents;
+ void *l_value = contents + (i * member_size) + l_offset;
+ void *r_value = contents + (i * member_size) + r_offset;
+
+ const char *l_value_as_string =
+ get_val_as_string(l_type, l_value, buf);
+
+ add_struct_value(r_type, r_value, add_struct_member,
+ l_value_as_string, struct_node);
+ }
+ }
+ }
+ break;
+
+ default:
+ assert(false);
+ }
+}
+
+
+static const char *
+get_val_as_string(const struct abstract_type *type, void *value, char *buf)
+{
+ switch (type->typename)
+ {
+ case REF:
+ {
+ arbitrary_record_opt *val = *(arbitrary_record_opt **)value;
+ if (val != NULL)
+ {
+ if (val->is_record)
+ {
+ return val->u.record->handle;
+ }
+ else
+ {
+ return val->u.handle;
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+ break;
+
+ case STRING:
+ {
+ return *(char **)value;
+ }
+ break;
+
+ case INT:
+ {
+ int64_t val = *(int64_t *)value;
+ snprintf(buf, sizeof(buf), "%"PRId64, val);
+ return buf;
+ }
+ break;
+
+ case ENUM:
+ {
+ int val = *(int *)value;
+ return type->enum_marshaller(val);
}
break;
@@ -1331,7 +1387,19 @@ add_struct_array(xmlNode *struct_node, const char *name)
xmlNode *array_node = add_container(value_node, "array");
return add_container(array_node, "data");
+}
+
+
+static xmlNode *
+add_nested_struct(xmlNode *struct_node, const char *name)
+{
+ xmlNode *member_node = add_container(struct_node, "member");
+
+ xmlNewChild(member_node, NULL, BAD_CAST "name", BAD_CAST name);
+
+ xmlNode *value_node = add_container(member_node, "value");
+ return add_container(value_node, "struct");
}
diff --git a/tools/libxen/src/xen_host.c b/tools/libxen/src/xen_host.c
index 7968b96994..4a79daa90f 100644
--- a/tools/libxen/src/xen_host.c
+++ b/tools/libxen/src/xen_host.c
@@ -632,6 +632,23 @@ xen_host_reboot(xen_session *session, xen_host host)
bool
+xen_host_dmesg(xen_session *session, char **result, xen_host host)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = host }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("host.dmesg");
+ return session->ok;
+}
+
+
+bool
xen_host_get_all(xen_session *session, struct xen_host_set **result)
{
diff --git a/tools/libxen/src/xen_int_float_map.c b/tools/libxen/src/xen_int_float_map.c
index edfcb21ac2..33ff29de62 100644
--- a/tools/libxen/src/xen_int_float_map.c
+++ b/tools/libxen/src/xen_int_float_map.c
@@ -25,8 +25,10 @@
xen_int_float_map *
xen_int_float_map_alloc(size_t size)
{
- return calloc(1, sizeof(xen_int_float_map) +
- size * sizeof(struct xen_int_float_map_contents));
+ xen_int_float_map *result = calloc(1, sizeof(xen_int_float_map) +
+ size * sizeof(struct xen_int_float_map_contents));
+ result->size = size;
+ return result;
}
diff --git a/tools/libxen/src/xen_string_string_map.c b/tools/libxen/src/xen_string_string_map.c
index 34f5ec4d70..b07acfbf7c 100644
--- a/tools/libxen/src/xen_string_string_map.c
+++ b/tools/libxen/src/xen_string_string_map.c
@@ -25,8 +25,10 @@
xen_string_string_map *
xen_string_string_map_alloc(size_t size)
{
- return calloc(1, sizeof(xen_string_string_map) +
- size * sizeof(struct xen_string_string_map_contents));
+ xen_string_string_map *result = calloc(1, sizeof(xen_string_string_map) +
+ size * sizeof(struct xen_string_string_map_contents));
+ result->size = size;
+ return result;
}
diff --git a/tools/libxen/src/xen_vdi.c b/tools/libxen/src/xen_vdi.c
index b2eddbcafb..005425ebc1 100644
--- a/tools/libxen/src/xen_vdi.c
+++ b/tools/libxen/src/xen_vdi.c
@@ -67,6 +67,9 @@ static const struct_member xen_vdi_record_struct_members[] =
{ .key = "sector_size",
.type = &abstract_type_int,
.offset = offsetof(xen_vdi_record, sector_size) },
+ { .key = "location",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vdi_record, location) },
{ .key = "type",
.type = &xen_vdi_type_abstract_type_,
.offset = offsetof(xen_vdi_record, type) },
diff --git a/tools/libxen/src/xen_vm.c b/tools/libxen/src/xen_vm.c
index 6cbc3670b0..e3f82575bd 100644
--- a/tools/libxen/src/xen_vm.c
+++ b/tools/libxen/src/xen_vm.c
@@ -145,9 +145,12 @@ static const struct_member xen_vm_record_struct_members[] =
{ .key = "PV_bootloader_args",
.type = &abstract_type_string,
.offset = offsetof(xen_vm_record, pv_bootloader_args) },
- { .key = "HVM_boot",
+ { .key = "HVM_boot_policy",
.type = &abstract_type_string,
- .offset = offsetof(xen_vm_record, hvm_boot) },
+ .offset = offsetof(xen_vm_record, hvm_boot_policy) },
+ { .key = "HVM_boot_params",
+ .type = &abstract_type_string_string_map,
+ .offset = offsetof(xen_vm_record, hvm_boot_params) },
{ .key = "platform_std_VGA",
.type = &abstract_type_bool,
.offset = offsetof(xen_vm_record, platform_std_vga) },
@@ -216,7 +219,8 @@ xen_vm_record_free(xen_vm_record *record)
free(record->pv_ramdisk);
free(record->pv_args);
free(record->pv_bootloader_args);
- free(record->hvm_boot);
+ free(record->hvm_boot_policy);
+ xen_string_string_map_free(record->hvm_boot_params);
free(record->platform_serial);
free(record->pci_bus);
xen_string_string_map_free(record->tools_version);
@@ -824,7 +828,7 @@ xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm)
bool
-xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_hvm_boot_policy(xen_session *session, char **result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -835,7 +839,24 @@ xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm)
abstract_type result_type = abstract_type_string;
*result = NULL;
- XEN_CALL_("VM.get_HVM_boot");
+ XEN_CALL_("VM.get_HVM_boot_policy");
+ return session->ok;
+}
+
+
+bool
+xen_vm_get_hvm_boot_params(xen_session *session, xen_string_string_map **result, xen_vm vm)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm }
+ };
+
+ abstract_type result_type = abstract_type_string_string_map;
+
+ *result = NULL;
+ XEN_CALL_("VM.get_HVM_boot_params");
return session->ok;
}
@@ -1376,17 +1397,67 @@ xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char *bootloader_
bool
-xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot)
+xen_vm_set_hvm_boot_policy(xen_session *session, xen_vm vm, char *boot_policy)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm },
{ .type = &abstract_type_string,
- .u.string_val = boot }
+ .u.string_val = boot_policy }
+ };
+
+ xen_call_(session, "VM.set_HVM_boot_policy", param_values, 2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_set_hvm_boot_params(xen_session *session, xen_vm vm, xen_string_string_map *boot_params)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_string_string_map,
+ .u.set_val = (arbitrary_set *)boot_params }
+ };
+
+ xen_call_(session, "VM.set_HVM_boot_params", param_values, 2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_add_to_hvm_boot_params(xen_session *session, xen_vm vm, char *key, char *value)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_string,
+ .u.string_val = key },
+ { .type = &abstract_type_string,
+ .u.string_val = value }
+ };
+
+ xen_call_(session, "VM.add_to_HVM_boot_params", param_values, 3, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_remove_from_hvm_boot_params(xen_session *session, xen_vm vm, char *key)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_string,
+ .u.string_val = key }
};
- xen_call_(session, "VM.set_HVM_boot", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.remove_from_HVM_boot_params", param_values, 2, NULL, NULL);
return session->ok;
}
diff --git a/tools/libxen/src/xen_vm_power_state.c b/tools/libxen/src/xen_vm_power_state.c
index a9e2545c47..9f96f34f9b 100644
--- a/tools/libxen/src/xen_vm_power_state.c
+++ b/tools/libxen/src/xen_vm_power_state.c
@@ -32,7 +32,6 @@ static const char *lookup_table[] =
"Paused",
"Running",
"Suspended",
- "ShuttingDown",
"Unknown"
};
diff --git a/tools/libxen/test/test_bindings.c b/tools/libxen/test/test_bindings.c
index 88fce8b35b..c1df98dcea 100644
--- a/tools/libxen/test/test_bindings.c
+++ b/tools/libxen/test/test_bindings.c
@@ -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
@@ -29,6 +29,7 @@
#include "xen_sr.h"
#include "xen_vbd.h"
#include "xen_vdi.h"
+#include "xen_console.h"
#include "xen_vm.h"
@@ -58,7 +59,7 @@ typedef struct
} xen_comms;
-static xen_vm create_new_vm(xen_session *session);
+static xen_vm create_new_vm(xen_session *session, bool hvm);
static void print_vm_power_state(xen_session *session, xen_vm vm);
@@ -205,6 +206,20 @@ int main(int argc, char **argv)
return 1;
}
+ char *dmesg;
+ if (!xen_host_dmesg(session, &dmesg, host))
+ {
+ print_error(session);
+ xen_string_string_map_free(versions);
+ xen_host_free(host);
+ xen_vm_record_free(vm_record);
+ xen_uuid_bytes_free(vm_uuid_bytes);
+ xen_uuid_free(vm_uuid);
+ xen_vm_free(vm);
+ CLEANUP;
+ return 1;
+ }
+
printf("%s.\n", vm_uuid);
fprintf(stderr, "In bytes, the VM UUID is ");
@@ -222,6 +237,8 @@ int main(int argc, char **argv)
versions->contents[i].val);
}
+ printf("Host dmesg follows:\n%s\n\n", dmesg);
+
printf("%s.\n", vm_record->uuid);
printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
@@ -243,9 +260,10 @@ int main(int argc, char **argv)
xen_host_free(host);
xen_string_string_map_free(versions);
+ free(dmesg);
- xen_vm new_vm = create_new_vm(session);
+ xen_vm new_vm = create_new_vm(session, true);
if (!session->ok)
{
/* Error has been logged, just clean up. */
@@ -275,13 +293,28 @@ int main(int argc, char **argv)
* allocation patterns can be used, as long as the allocation and free are
* paired correctly.
*/
-static xen_vm create_new_vm(xen_session *session)
+static xen_vm create_new_vm(xen_session *session, bool hvm)
{
xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1);
+ vcpus_params->contents[0].key = strdup("weight");
+ vcpus_params->contents[0].val = strdup("300");
+
+ xen_string_string_map *hvm_boot_params;
+ if (hvm)
+ {
+ hvm_boot_params = xen_string_string_map_alloc(1);
+ hvm_boot_params->contents[0].key = strdup("order");
+ hvm_boot_params->contents[0].val = strdup("cd");
+ }
+ else
+ {
+ hvm_boot_params = NULL;
+ }
+
xen_vm_record vm_record =
{
- .name_label = "NewVM",
- .name_description = "New VM Description",
+ .name_label = hvm ? "NewHVM" : "NewPV",
+ .name_description = hvm ? "New HVM VM" : "New PV VM",
.user_version = 1,
.is_a_template = false,
.memory_static_max = 256,
@@ -294,18 +327,18 @@ static xen_vm create_new_vm(xen_session *session)
.actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
.actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
.actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
- .hvm_boot = "",
- .pv_bootloader = "pygrub",
- .pv_kernel = "/boot/vmlinuz-2.6.16.33-xen",
- .pv_ramdisk = "",
- .pv_args = "",
- .pv_bootloader_args = ""
+ .hvm_boot_policy = hvm ? "BIOS order" : NULL,
+ .hvm_boot_params = hvm ? hvm_boot_params : NULL,
+ .pv_bootloader = hvm ? NULL : "pygrub",
+ .pv_kernel = hvm ? NULL : "/boot/vmlinuz-2.6.16.33-xen",
};
-
xen_vm vm;
xen_vm_create(session, &vm, &vm_record);
+ xen_string_string_map_free(vcpus_params);
+ xen_string_string_map_free(hvm_boot_params);
+
if (!session->ok)
{
fprintf(stderr, "VM creation failed.\n");
@@ -368,7 +401,8 @@ static xen_vm create_new_vm(xen_session *session)
.vm = &vm_record_opt,
.vdi = &vdi0_record_opt,
.device = "xvda1",
- .mode = XEN_VBD_MODE_RW
+ .mode = XEN_VBD_MODE_RW,
+ .bootable = 1,
};
xen_vbd vbd0;
@@ -383,13 +417,38 @@ static xen_vm create_new_vm(xen_session *session)
return NULL;
}
+ xen_console vnc_console = NULL;
+ if (hvm) {
+ xen_console_record vnc_console_record =
+ {
+ .protocol = XEN_CONSOLE_PROTOCOL_RFB,
+ .vm = &vm_record_opt,
+ };
+
+ if (!xen_console_create(session, &vnc_console, &vnc_console_record))
+ {
+ fprintf(stderr, "VNC console creation failed.\n");
+ print_error(session);
+
+ xen_vbd_free(vbd0);
+ xen_vdi_free(vdi0);
+ xen_sr_set_free(srs);
+ xen_vm_free(vm);
+ return NULL;
+ }
+ }
+
char *vm_uuid;
char *vdi0_uuid;
char *vbd0_uuid;
+ char *vnc_uuid = NULL;
xen_vm_get_uuid(session, &vm_uuid, vm);
xen_vdi_get_uuid(session, &vdi0_uuid, vdi0);
xen_vbd_get_uuid(session, &vbd0_uuid, vbd0);
+ if (hvm) {
+ xen_console_get_uuid(session, &vnc_uuid, vnc_console);
+ }
if (!session->ok)
{
@@ -399,22 +458,35 @@ static xen_vm create_new_vm(xen_session *session)
xen_uuid_free(vm_uuid);
xen_uuid_free(vdi0_uuid);
xen_uuid_free(vbd0_uuid);
+ xen_uuid_free(vnc_uuid);
xen_vbd_free(vbd0);
xen_vdi_free(vdi0);
+ xen_console_free(vnc_console);
xen_sr_set_free(srs);
xen_vm_free(vm);
return NULL;
}
- fprintf(stderr,
- "Created a new VM, with UUID %s, VDI UUID %s, and VBD UUID %s.\n",
- vm_uuid, vdi0_uuid, vbd0_uuid);
+ 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);
+ }
+ 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);
+ }
xen_uuid_free(vm_uuid);
xen_uuid_free(vdi0_uuid);
xen_uuid_free(vbd0_uuid);
+ xen_uuid_free(vnc_uuid);
xen_vbd_free(vbd0);
xen_vdi_free(vdi0);
+ xen_console_free(vnc_console);
xen_sr_set_free(srs);
return vm;
diff --git a/tools/libxen/test/test_hvm_bindings.c b/tools/libxen/test/test_hvm_bindings.c
new file mode 100644
index 0000000000..8bc8e7c347
--- /dev/null
+++ b/tools/libxen/test/test_hvm_bindings.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 2006 XenSource, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _GNU_SOURCE
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libxml/parser.h>
+#include <curl/curl.h>
+
+#include "xen_host.h"
+#include "xen_sr.h"
+#include "xen_vbd.h"
+#include "xen_vdi.h"
+#include "xen_vm.h"
+
+
+static void usage()
+{
+ fprintf(stderr,
+"Usage:\n"
+"\n"
+" test_bindings <url> <username> <password>\n"
+"\n"
+"where\n"
+" <url> is a fragment of the server's URL, e.g. localhost:8005/RPC2;\n"
+" <username> is the username to use at the server; and\n"
+" <password> is the password.\n");
+
+ exit(EXIT_FAILURE);
+}
+
+
+static char *url;
+
+
+typedef struct
+{
+ xen_result_func func;
+ void *handle;
+} xen_comms;
+
+
+static xen_vm create_new_vm(xen_session *session);
+static void print_vm_power_state(xen_session *session, xen_vm vm);
+
+
+static size_t
+write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
+{
+ size_t n = size * nmemb;
+ return comms->func(ptr, n, comms->handle) ? n : 0;
+}
+
+
+static int
+call_func(const void *data, size_t len, void *user_handle,
+ void *result_handle, xen_result_func result_func)
+{
+ (void)user_handle;
+
+ CURL *curl = curl_easy_init();
+ if (!curl) {
+ return -1;
+ }
+
+ xen_comms comms = {
+ .func = result_func,
+ .handle = result_handle
+ };
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+ curl_easy_setopt(curl, CURLOPT_MUTE, 1);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
+ curl_easy_setopt(curl, CURLOPT_POST, 1);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
+
+ CURLcode result = curl_easy_perform(curl);
+
+ curl_easy_cleanup(curl);
+
+ return result;
+}
+
+
+static void print_error(xen_session *session)
+{
+ fprintf(stderr, "Error: %d", session->error_description_count);
+ for (int i = 0; i < session->error_description_count; i++)
+ {
+ fprintf(stderr, "%s ", session->error_description[i]);
+ }
+ fprintf(stderr, "\n");
+}
+
+
+int main(int argc, char **argv)
+{
+ if (argc != 4)
+ {
+ usage();
+ }
+
+ url = argv[1];
+ char *username = argv[2];
+ char *password = argv[3];
+
+ xmlInitParser();
+ xen_init();
+ curl_global_init(CURL_GLOBAL_ALL);
+
+#define CLEANUP \
+ do { \
+ xen_session_logout(session); \
+ curl_global_cleanup(); \
+ xen_fini(); \
+ xmlCleanupParser(); \
+ } while(0) \
+
+
+ xen_session *session =
+ xen_session_login_with_password(call_func, NULL, username, password);
+
+ xen_vm vm;
+ if (!xen_vm_get_by_uuid(session, &vm,
+ "00000000-0000-0000-0000-000000000000"))
+ {
+ print_error(session);
+ CLEANUP;
+ return 1;
+ }
+
+ char *vm_uuid;
+ if (!xen_vm_get_uuid(session, &vm_uuid, vm))
+ {
+ print_error(session);
+ xen_vm_free(vm);
+ CLEANUP;
+ return 1;
+ }
+
+ char *vm_uuid_bytes;
+ if (!xen_uuid_string_to_bytes(vm_uuid, &vm_uuid_bytes))
+ {
+ fprintf(stderr, "xen_uuid_string_to_bytes failed.\n");
+ xen_uuid_free(vm_uuid);
+ xen_vm_free(vm);
+ CLEANUP;
+ return 1;
+ }
+
+ xen_vm_record *vm_record;
+ if (!xen_vm_get_record(session, &vm_record, vm))
+ {
+ print_error(session);
+ xen_uuid_bytes_free(vm_uuid_bytes);
+ xen_uuid_free(vm_uuid);
+ xen_vm_free(vm);
+ CLEANUP;
+ return 1;
+ }
+
+ xen_host host;
+ if (!xen_session_get_this_host(session, &host))
+ {
+ print_error(session);
+ xen_vm_record_free(vm_record);
+ xen_uuid_bytes_free(vm_uuid_bytes);
+ xen_uuid_free(vm_uuid);
+ xen_vm_free(vm);
+ CLEANUP;
+ return 1;
+ }
+
+ xen_string_string_map *versions;
+ if (!xen_host_get_software_version(session, &versions, host))
+ {
+ print_error(session);
+ xen_host_free(host);
+ xen_vm_record_free(vm_record);
+ xen_uuid_bytes_free(vm_uuid_bytes);
+ xen_uuid_free(vm_uuid);
+ xen_vm_free(vm);
+ CLEANUP;
+ return 1;
+ }
+
+ printf("%s.\n", vm_uuid);
+
+ fprintf(stderr, "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("%zd.\n", versions->size);
+
+ for (size_t i = 0; i < versions->size; i++)
+ {
+ printf("%s -> %s.\n", versions->contents[i].key,
+ versions->contents[i].val);
+ }
+
+ printf("%s.\n", vm_record->uuid);
+
+ printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
+
+ printf("%s.\n", xen_vm_power_state_to_string(vm_record->power_state));
+
+ for (size_t i = 0; i < vm_record->vcpus_utilisation->size; i++)
+ {
+ printf("%"PRId64" -> %lf.\n",
+ vm_record->vcpus_utilisation->contents[i].key,
+ vm_record->vcpus_utilisation->contents[i].val);
+ }
+
+ xen_uuid_bytes_free(vm_uuid_bytes);
+ xen_uuid_free(vm_uuid);
+ xen_vm_free(vm);
+
+ xen_vm_record_free(vm_record);
+
+ xen_host_free(host);
+ xen_string_string_map_free(versions);
+
+
+ xen_vm new_vm = create_new_vm(session);
+ if (!session->ok)
+ {
+ /* Error has been logged, just clean up. */
+ CLEANUP;
+ return 1;
+ }
+
+ print_vm_power_state(session, new_vm);
+ if (!session->ok)
+ {
+ /* Error has been logged, just clean up. */
+ xen_vm_free(new_vm);
+ CLEANUP;
+ return 1;
+ }
+
+ xen_vm_free(new_vm);
+ CLEANUP;
+
+ return 0;
+}
+
+
+/**
+ * Creation of a new VM, using the Named Parameters idiom. Allocate the
+ * xen_vm_record here, but the sets through the library. Either
+ * allocation patterns can be used, as long as the allocation and free are
+ * paired correctly.
+ */
+static xen_vm create_new_vm(xen_session *session)
+{
+ xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1);
+ xen_vm_record vm_record =
+ {
+ .name_label = "NewHVM",
+ .name_description = "New HVM Description",
+ .user_version = 1,
+ .is_a_template = false,
+ .memory_static_max = 256,
+ .memory_dynamic_max = 256,
+ .memory_dynamic_min = 128,
+ .memory_static_min = 128,
+ .vcpus_policy = "credit",
+ .vcpus_params = vcpus_params,
+ .vcpus_number = 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,
+ .hvm_boot = "cda",
+ };
+
+
+ xen_vm vm;
+ xen_vm_create(session, &vm, &vm_record);
+
+ if (!session->ok)
+ {
+ fprintf(stderr, "VM creation failed.\n");
+ print_error(session);
+ return NULL;
+ }
+
+
+ /*
+ * Create a new disk for the new VM.
+ */
+ xen_sr_set *srs;
+ if (!xen_sr_get_by_name_label(session, &srs, "Local") ||
+ srs->size < 1)
+ {
+ fprintf(stderr, "SR lookup failed.\n");
+ print_error(session);
+ xen_vm_free(vm);
+ return NULL;
+ }
+
+ xen_sr_record_opt sr_record =
+ {
+ .u.handle = srs->contents[0]
+ };
+ xen_vdi_record vdi0_record =
+ {
+ .name_label = "MyRootFS",
+ .name_description = "MyRootFS description",
+ .sr = &sr_record,
+ .virtual_size = (1 << 21), // 1GiB / 512 bytes/sector
+ .sector_size = 512,
+ .location = "file:/root/gentoo.amd64.hvm.img",
+ .type = XEN_VDI_TYPE_SYSTEM,
+ .sharable = false,
+ .read_only = false
+ };
+
+ xen_vdi vdi0;
+ if (!xen_vdi_create(session, &vdi0, &vdi0_record))
+ {
+ fprintf(stderr, "VDI creation failed.\n");
+ print_error(session);
+
+ xen_sr_set_free(srs);
+ xen_vm_free(vm);
+ return NULL;
+ }
+
+
+ xen_vm_record_opt vm_record_opt =
+ {
+ .u.handle = vm
+ };
+ xen_vdi_record_opt vdi0_record_opt =
+ {
+ .u.handle = vdi0
+ };
+ xen_vbd_record vbd0_record =
+ {
+ .vm = &vm_record_opt,
+ .vdi = &vdi0_record_opt,
+ .device = "xvda1",
+ .mode = XEN_VBD_MODE_RW
+ };
+
+ xen_vbd vbd0;
+ if (!xen_vbd_create(session, &vbd0, &vbd0_record))
+ {
+ fprintf(stderr, "VBD creation failed.\n");
+ print_error(session);
+
+ xen_vdi_free(vdi0);
+ xen_sr_set_free(srs);
+ xen_vm_free(vm);
+ return NULL;
+ }
+
+ char *vm_uuid;
+ char *vdi0_uuid;
+ char *vbd0_uuid;
+
+ xen_vm_get_uuid(session, &vm_uuid, vm);
+ xen_vdi_get_uuid(session, &vdi0_uuid, vdi0);
+ xen_vbd_get_uuid(session, &vbd0_uuid, vbd0);
+
+ if (!session->ok)
+ {
+ fprintf(stderr, "get_uuid call failed.\n");
+ print_error(session);
+
+ xen_uuid_free(vm_uuid);
+ xen_uuid_free(vdi0_uuid);
+ xen_uuid_free(vbd0_uuid);
+ xen_vbd_free(vbd0);
+ xen_vdi_free(vdi0);
+ xen_sr_set_free(srs);
+ xen_vm_free(vm);
+ return NULL;
+ }
+
+ fprintf(stderr,
+ "Created a new VM, with UUID %s, VDI UUID %s, and VBD UUID %s.\n",
+ vm_uuid, vdi0_uuid, vbd0_uuid);
+
+ xen_uuid_free(vm_uuid);
+ xen_uuid_free(vdi0_uuid);
+ xen_uuid_free(vbd0_uuid);
+ xen_vbd_free(vbd0);
+ xen_vdi_free(vdi0);
+ xen_sr_set_free(srs);
+
+ return vm;
+}
+
+
+/**
+ * Print the power state for the given VM.
+ */
+static void print_vm_power_state(xen_session *session, xen_vm vm)
+{
+ char *vm_uuid;
+ enum xen_vm_power_state power_state;
+
+ if (!xen_vm_get_uuid(session, &vm_uuid, vm))
+ {
+ print_error(session);
+ return;
+ }
+
+ if (!xen_vm_get_power_state(session, &power_state, vm))
+ {
+ xen_uuid_free(vm_uuid);
+ print_error(session);
+ return;
+ }
+
+ printf("VM %s power state is %s.\n", vm_uuid,
+ xen_vm_power_state_to_string(power_state));
+
+ xen_uuid_free(vm_uuid);
+}
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index 13c95b56f7..80b52c0063 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -12,7 +12,7 @@ HDRS = $(wildcard *.h)
TARGETS = xenperf xc_shadow
INSTALL_BIN = $(TARGETS) xencons
-INSTALL_SBIN = netfix xm xen-bugtool xend xenperf
+INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf
.PHONY: all
all: build
diff --git a/tools/misc/xen-python-path b/tools/misc/xen-python-path
new file mode 100644
index 0000000000..03c572b8ef
--- /dev/null
+++ b/tools/misc/xen-python-path
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+# -*- mode: python; -*-
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (C) 2007 XenSource Inc.
+#============================================================================
+
+
+# Use the auxbin module in Xend to determine the correct Python path. We
+# take the first installed instance of auxbin that we find, and then run it
+# to determine the correct path, appending that to sys.path.
+
+AUXBIN = 'xen/util/auxbin.py'
+
+import os
+import os.path
+import sys
+
+for p in ['python%s' % sys.version[:3], 'python']:
+ for l in ['/usr/lib64', '/usr/lib']:
+ d = os.path.join(l, p)
+ if os.path.exists(os.path.join(d, AUXBIN)):
+ sys.path.append(d)
+ import xen.util.auxbin
+ print os.path.join(xen.util.auxbin.libpath(), p)
+ sys.exit(0)
+
+print >>sys.stderr, "Cannot find Xen Python modules."
+sys.exit(1)
diff --git a/tools/misc/xend b/tools/misc/xend
index 0832f84010..860dcbcd25 100644
--- a/tools/misc/xend
+++ b/tools/misc/xend
@@ -31,23 +31,13 @@ import signal
import time
import commands
+result = commands.getstatusoutput(os.path.join(os.path.dirname(sys.argv[0]),
+ 'xen-python-path'))
+if result[0] != 0:
+ print >>sys.stderr, result[1]
+ sys.exit(1)
-# Use the auxbin module in Xend to determine the correct Python path. We
-# take the first installed instance of auxbin that we find, and then run it
-# to determine the correct path, appending that to sys.path.
-
-AUXBIN = 'xen/util/auxbin.py'
-
-for p in ['python%s' % sys.version[:3], 'python']:
- for l in ['/usr/lib64', '/usr/lib']:
- d = os.path.join(l, p)
- if os.path.exists(os.path.join(d, AUXBIN)):
- sys.path.append(d)
- import xen.util.auxbin
- libpath = os.path.join(xen.util.auxbin.libpath(), p)
- sys.path = sys.path[:-1]
- sys.path.append(libpath)
- break
+sys.path.append(result[1])
from xen.xend.server import SrvDaemon
diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
index cf0efcb185..9b3d15f675 100644
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -197,7 +197,10 @@ class Grub:
self.screen = curses.initscr()
self.screen.timeout(1000)
if hasattr(curses, 'use_default_colors'):
- curses.use_default_colors()
+ try:
+ curses.use_default_colors()
+ except:
+ pass # Not important if we can't use colour
enable_cursor(False)
self.entry_win = curses.newwin(10, 74, 2, 1)
self.text_win = curses.newwin(10, 70, 12, 5)
diff --git a/tools/python/scripts/test_hvm_create.py b/tools/python/scripts/test_hvm_create.py
index 8effd42db9..7cae70539a 100644
--- a/tools/python/scripts/test_hvm_create.py
+++ b/tools/python/scripts/test_hvm_create.py
@@ -13,16 +13,11 @@ vm_cfg = {
'VCPUs_policy': 'credit',
- 'VCPUs_params': '',
+ 'VCPUs_params': {},
'VCPUs_number': 2,
- 'VCPUs_features_required': '',
- 'VCPUs_features_can_use': '',
- 'VCPUs_features_force_on': '',
- 'VCPUs_features_force_off': '',
'actions_after_shutdown': 'destroy',
'actions_after_reboot': 'restart',
- 'actions_after_suspend': 'destroy',
'actions_after_crash': 'destroy',
'PV_bootloader': '',
@@ -44,7 +39,7 @@ vm_cfg = {
local_vdi_cfg = {
'name_label': 'gentoo.hvm',
'name_description': '',
- 'uri': 'file:/root/gentoo.amd64.hvm.img',
+ 'location': 'file:/root/gentoo.amd64.hvm.img',
'virtual_size': 0,
'sector_size': 0,
'type': 'system',
diff --git a/tools/python/scripts/test_vm_create.py b/tools/python/scripts/test_vm_create.py
index 0d702aae69..84959c3e0d 100644
--- a/tools/python/scripts/test_vm_create.py
+++ b/tools/python/scripts/test_vm_create.py
@@ -15,14 +15,9 @@ vm_cfg = {
'VCPUs_policy': 'credit',
'VCPUs_params': '',
'VCPUs_number': 2,
- 'VCPUs_features_required': '',
- 'VCPUs_features_can_use': '',
- 'VCPUs_features_force_on': '',
- 'VCPUs_features_force_off': '',
'actions_after_shutdown': 'destroy',
'actions_after_reboot': 'restart',
- 'actions_after_suspend': 'destroy',
'actions_after_crash': 'destroy',
'PV_bootloader': '',
@@ -65,7 +60,7 @@ vbd_cfg = {
local_vdi_cfg = {
'name_label': 'gentoo.amd64.img',
'name_description': '',
- 'uri': 'file:/root/gentoo.amd64.img',
+ 'location': 'file:/root/gentoo.amd64.img',
'virtual_size': 0,
'sector_size': 0,
'type': 'system',
@@ -183,13 +178,13 @@ def test_vm_create():
execute(server, 'VM.resume', (session, vm_uuid, False))
print 'Resumed VM.'
+ finally:
# Wait for user to say we're good to shut it down
while True:
destroy = raw_input('destroy VM? ')
if destroy[0] in ('y', 'Y'):
break
-
- finally:
+
# Clean up
if vif_uuid:
execute(server, 'VIF.destroy', (session, vif_uuid))
diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py
index 0b249f9449..49f2082893 100644
--- a/tools/python/xen/xend/XendAPI.py
+++ b/tools/python/xen/xend/XendAPI.py
@@ -22,7 +22,7 @@ import sys
import traceback
import threading
-from xen.xend import XendDomain, XendDomainInfo, XendNode
+from xen.xend import XendDomain, XendDomainInfo, XendNode, XendDmesg
from xen.xend import XendLogging, XendTaskManager
from xen.xend.XendAuthSessions import instance as auth_manager
@@ -615,7 +615,8 @@ class XendAPI(object):
('reboot', None),
('shutdown', None),
('add_to_other_config', None),
- ('remove_from_other_config', None)]
+ ('remove_from_other_config', None),
+ ('dmesg', 'String')]
host_funcs = [('get_by_name_label', 'Set(host)')]
@@ -674,6 +675,9 @@ class XendAPI(object):
return xen_api_error(XEND_ERROR_HOST_RUNNING)
return xen_api_error(XEND_ERROR_UNSUPPORTED)
+ def host_dmesg(self, session, host_ref):
+ return xen_api_success(XendDmesg.instance().info())
+
def host_get_record(self, session, host_ref):
node = XendNode.instance()
dom = XendDomain.instance()
@@ -737,7 +741,7 @@ class XendAPI(object):
'memory_free',
'host']
host_metrics_attr_rw = []
- host_methods = []
+ host_metrics_methods = []
def _host_metrics_get(self, ref, f):
return xen_api_success(getattr(node, f)())
@@ -974,7 +978,8 @@ class XendAPI(object):
'PV_ramdisk',
'PV_args',
'PV_bootloader_args',
- 'HVM_boot',
+ 'HVM_boot_policy',
+ 'HVM_boot_params',
'platform_std_VGA',
'platform_serial',
'platform_localtime',
@@ -1020,7 +1025,8 @@ class XendAPI(object):
'PV_ramdisk',
'PV_args',
'PV_bootloader_args',
- 'HVM_boot',
+ 'HVM_boot_policy',
+ 'HVM_boot_params',
'platform_std_VGA',
'platform_serial',
'platform_localtime',
@@ -1121,11 +1127,11 @@ class XendAPI(object):
def VM_get_VCPUs_policy(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return dom.get_vcpus_policy()
+ return xen_api_success(dom.get_vcpus_policy())
def VM_get_VCPUs_params(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo() # need access to scheduler
+ return xen_api_success(dom.get_vcpus_params())
def VM_get_actions_after_shutdown(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -1158,8 +1164,11 @@ class XendAPI(object):
def VM_get_PV_bootloader_args(self, session, vm_ref):
return self.VM_get('PV_bootloader_args', session, vm_ref)
- def VM_get_HVM_boot(self, session, vm_ref):
- return self.VM_get('HVM_boot', session, vm_ref)
+ def VM_get_HVM_boot_policy(self, session, vm_ref):
+ return self.VM_get('HVM_boot_policy', session, vm_ref)
+
+ def VM_get_HVM_boot_params(self, session, vm_ref):
+ return self.VM_get('HVM_boot_params', session, vm_ref)
def VM_get_platform_std_VGA(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -1186,7 +1195,7 @@ class XendAPI(object):
return xen_api_success(dom.get_platform_keymap())
def VM_get_other_config(self, session, vm_ref):
- return self.VM_get('otherconfig', session, vm_ref)
+ return self.VM_get('other_config', session, vm_ref)
def VM_get_is_control_domain(self, session, vm_ref):
xd = XendDomain.instance()
@@ -1246,8 +1255,30 @@ class XendAPI(object):
return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref])
return self.VM_set('actions_after_crash', session, vm_ref, action)
- def VM_set_HVM_boot(self, session, vm_ref, value):
- return self.VM_set('HVM_boot', session, vm_ref, value)
+ def VM_set_HVM_boot_policy(self, session, vm_ref, value):
+ if value != "" and value != "BIOS order":
+ return xen_api_error(
+ ['VALUE_NOT_SUPPORTED', 'VM.HVM_boot_policy', value,
+ 'Xend supports only the "BIOS order" boot policy.'])
+ else:
+ return self.VM_set('HVM_boot_policy', session, vm_ref, value)
+
+ def VM_set_HVM_boot_params(self, session, vm_ref, value):
+ return self.VM_set('HVM_boot_params', session, vm_ref, value)
+
+ def VM_add_to_HVM_boot_params(self, session, vm_ref, key, value):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ if 'HVM_boot_params' not in dom.info:
+ dom.info['HVM_boot_params'] = {}
+ dom.info['HVM_boot_params'][key] = value
+ return xen_api_success_void()
+
+ def VM_remove_from_HVM_boot_params(self, session, vm_ref, key):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ if 'HVM_boot_params' in dom.info \
+ and key in dom.info['HVM_boot_params']:
+ del dom.info['HVM_boot_params'][key]
+ return xen_api_success_void()
def VM_set_PV_bootloader(self, session, vm_ref, value):
return self.VM_set('PV_bootloader', session, vm_ref, value)
@@ -1354,7 +1385,8 @@ class XendAPI(object):
'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
'PV_args': xeninfo.info.get('PV_args'),
'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
- 'HVM_boot': xeninfo.info.get('HVM_boot'),
+ 'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'),
+ 'HVM_boot_params': xeninfo.info.get('HVM_boot_params'),
'platform_std_VGA': xeninfo.get_platform_std_vga(),
'platform_serial': xeninfo.get_platform_serial(),
'platform_localtime': xeninfo.get_platform_localtime(),
@@ -1363,7 +1395,7 @@ class XendAPI(object):
'platform_keymap': xeninfo.get_platform_keymap(),
'PCI_bus': xeninfo.get_pci_bus(),
'tools_version': xeninfo.get_tools_version(),
- 'other_config': xeninfo.info.get('otherconfig'),
+ 'other_config': xeninfo.info.get('other_config', {}),
'is_control_domain': xeninfo == xendom.privilegedDomain(),
}
return xen_api_success(record)
@@ -1469,7 +1501,7 @@ class XendAPI(object):
vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
if not vdi:
return xen_api_error(['VDI_HANDLE_INVALID', vdi_ref])
- vdi_image = vdi.get_image_uri()
+ vdi_image = vdi.get_location()
vbd_ref = XendTask.log_progress(0, 100,
dom.create_vbd,
vbd_struct, vdi_image)
@@ -1622,7 +1654,7 @@ class XendAPI(object):
xendom = XendDomain.instance()
return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
'io_write_kbs'))
-
+
def VIF_get_all(self, session):
xendom = XendDomain.instance()
vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
diff --git a/tools/python/xen/xend/XendAPIConstants.py b/tools/python/xen/xend/XendAPIConstants.py
index 9805cf02a7..41e212d495 100644
--- a/tools/python/xen/xend/XendAPIConstants.py
+++ b/tools/python/xen/xend/XendAPIConstants.py
@@ -12,7 +12,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
-# Copyright (C) 2006 XenSource Ltd.
+# Copyright (C) 2006-2007 XenSource Ltd.
#============================================================================
#
@@ -24,7 +24,7 @@ XEN_API_VM_POWER_STATE = [
'Paused',
'Running',
'Suspended',
- 'ShuttingDown',
+ 'Halted',
'Unknown'
]
@@ -49,16 +49,8 @@ XEN_API_ON_CRASH_BEHAVIOUR = [
'rename_restart'
]
-XEN_API_BOOT_TYPE = [
- 'bios',
- 'grub',
- 'kernel_external',
- 'kernel_internal'
-]
-
XEN_API_VBD_MODE = ['RO', 'RW']
XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral']
-XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised']
XEN_API_VBD_TYPE = ['CD', 'Disk']
XEN_API_TASK_STATUS_TYPE = ['pending', 'success', 'failure']
XEN_API_CONSOLE_PROTOCOL = ['vt100', 'rfb', 'rdp']
diff --git a/tools/python/xen/xend/XendBootloader.py b/tools/python/xen/xend/XendBootloader.py
index 29644c5004..4220cde6eb 100644
--- a/tools/python/xen/xend/XendBootloader.py
+++ b/tools/python/xen/xend/XendBootloader.py
@@ -97,7 +97,9 @@ def bootloader(blexec, disk, dom, quiet = False, blargs = '', kernel = '',
try:
log.debug("Launching bootloader as %s." % str(args))
- os.execvp(args[0], args)
+ env = os.environ.copy()
+ env['TERM'] = 'vt100'
+ os.execvpe(args[0], args, env)
except OSError, e:
print e
pass
diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py
index f17a5a2295..223a90cf6e 100644
--- a/tools/python/xen/xend/XendConfig.py
+++ b/tools/python/xen/xend/XendConfig.py
@@ -28,7 +28,7 @@ from xen.xend.PrettyPrint import prettyprintstring
from xen.xend.XendConstants import DOM_STATE_HALTED
log = logging.getLogger("xend.XendConfig")
-log.setLevel(logging.WARN)
+log.setLevel(logging.DEBUG)
"""
@@ -125,8 +125,7 @@ XENAPI_HVM_CFG = {
'platform_std_vga': 'stdvga',
'platform_serial' : 'serial',
'platform_localtime': 'localtime',
- 'platform_keymap' : 'keymap',
- 'HVM_boot': 'boot',
+ 'platform_keymap' : 'keymap'
}
# List of XendConfig configuration keys that have no direct equivalent
@@ -147,24 +146,19 @@ XENAPI_CFG_TYPES = {
'memory_actual': int,
'cpus': list,
'vcpus_policy': str,
- 'vcpus_params': str,
+ 'vcpus_params': dict,
'vcpus_number': int,
- 'vcpus_features_required': list,
- 'vcpus_features_can_use': list,
- 'vcpus_features_force_on': list,
- 'vcpus_features_force_off': list,
'actions_after_shutdown': str,
'actions_after_reboot': str,
- 'actions_after_suspend': str,
'actions_after_crash': str,
- 'tpm_instance': int,
'tpm_backend': int,
'PV_bootloader': str,
'PV_kernel': str,
'PV_ramdisk': str,
'PV_args': str,
'PV_bootloader_args': str,
- 'HVM_boot': str,
+ 'HVM_boot_policy': str,
+ 'HVM_boot_params': dict,
'platform_std_vga': bool0,
'platform_serial': str,
'platform_localtime': bool0,
@@ -349,7 +343,6 @@ class XendConfig(dict):
def _defaults(self):
defaults = {
- 'uuid': uuid.createString(),
'name_label': 'Domain-Unnamed',
'actions_after_shutdown': 'destroy',
'actions_after_reboot': 'restart',
@@ -361,7 +354,8 @@ class XendConfig(dict):
'PV_ramdisk': '',
'PV_args': '',
'PV_bootloader_args': '',
- 'HVM_boot': '',
+ 'HVM_boot_policy': '',
+ 'HVM_boot_params': {},
'memory_static_min': 0,
'memory_dynamic_min': 0,
'shadow_memory': 0,
@@ -377,6 +371,7 @@ class XendConfig(dict):
'cpu_weight': 256,
'cpu_cap': 0,
'vcpus_number': 1,
+ 'vcpus_params': {},
'console_refs': [],
'vif_refs': [],
'vbd_refs': [],
@@ -384,7 +379,6 @@ class XendConfig(dict):
'other_config': {},
}
- defaults['name_label'] = 'Domain-' + defaults['uuid']
return defaults
def _memory_sanity_check(self):
@@ -414,13 +408,21 @@ class XendConfig(dict):
def _uuid_sanity_check(self):
"""Make sure UUID is in proper string format with hyphens."""
- self['uuid'] = uuid.toString(uuid.fromString(self['uuid']))
+ if 'uuid' not in self or not self['uuid']:
+ self['uuid'] = uuid.createString()
+ else:
+ self['uuid'] = uuid.toString(uuid.fromString(self['uuid']))
+
+ def _name_sanity_check(self):
+ if 'name_label' not in self:
+ self['name_label'] = 'Domain-' + self['uuid']
def validate(self):
+ self._uuid_sanity_check()
+ self._name_sanity_check()
self._memory_sanity_check()
self._actions_sanity_check()
self._vcpus_sanity_check()
- self._uuid_sanity_check()
def _dominfo_to_xapi(self, dominfo):
self['domid'] = dominfo['domid']
@@ -496,6 +498,12 @@ class XendConfig(dict):
log.warn("Unable to parse key %s: %s: %s" %
(key, str(val), e))
+ # Compatibility hack -- can go soon.
+ boot_order = sxp.child_value(sxp_cfg, 'HVM_boot')
+ if boot_order:
+ cfg['HVM_boot_policy'] = 'BIOS order'
+ cfg['HVM_boot_params'] = { 'order' : boot_order }
+
# Parsing the device SXP's. In most cases, the SXP looks
# like this:
#
@@ -671,6 +679,9 @@ class XendConfig(dict):
if self['devices'][console_uuid][1].get('protocol') == 'rfb':
has_rfb = True
break
+ if self['devices'][console_uuid][0] == 'vfb':
+ has_rfb = True
+ break
if not has_rfb:
dev_config = ['vfb']
@@ -724,6 +735,7 @@ class XendConfig(dict):
val = sxp.child_value(image_sxp, imgkey, None)
if val != None:
self[apikey] = val
+ self._hvm_boot_params_from_sxp(image_sxp)
# extract backend value
@@ -768,7 +780,7 @@ class XendConfig(dict):
if 'image' in xapi_dict:
self['image'].update(xapi_dict['image'])
else:
- hvm = self['HVM_boot'] != ''
+ hvm = self['HVM_boot_policy'] != ''
self['image']['type'] = hvm and 'hvm' or 'linux'
if hvm:
self['image']['hvm'] = {'devices': {}}
@@ -829,8 +841,6 @@ class XendConfig(dict):
else:
self[key] = val
- self.validate()
-
def to_sxp(self, domain = None, ignore_devices = False, ignore = [],
legacy_only = True):
""" Get SXP representation of this config object.
@@ -854,9 +864,13 @@ class XendConfig(dict):
sxpr.append(['domid', domain.getDomid()])
if not legacy_only:
- for name in XENAPI_CFG_TYPES.keys():
+ for name, typ in XENAPI_CFG_TYPES.items():
if name in self and self[name] not in (None, []):
- sxpr.append([name, str(self[name])])
+ if typ == dict:
+ s = self[name].items()
+ else:
+ s = str(self[name])
+ sxpr.append([name, s])
for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
if self.has_key(xenapi) and self[xenapi] not in (None, []):
@@ -905,7 +919,7 @@ class XendConfig(dict):
# store as part of the device config.
dev_uuid = sxp.child_value(config, 'uuid')
dev_type, dev_cfg = self['devices'][dev_uuid]
- is_bootable = dev_cfg.get('bootable', False)
+ is_bootable = dev_cfg.get('bootable', 0)
config.append(['bootable', int(is_bootable)])
sxpr.append(['device', config])
@@ -978,14 +992,16 @@ class XendConfig(dict):
pass
if dev_type == 'vbd':
- dev_info['bootable'] = False
+ dev_info['bootable'] = 0
if dev_info.get('dev', '').startswith('ioemu:'):
dev_info['driver'] = 'ioemu'
else:
dev_info['driver'] = 'paravirtualised'
# create uuid if it doesn't exist
- dev_uuid = dev_info.get('uuid', uuid.createString())
+ dev_uuid = dev_info.get('uuid', None)
+ if not dev_uuid:
+ dev_uuid = uuid.createString()
dev_info['uuid'] = dev_uuid
# store dev references by uuid for certain device types
@@ -998,7 +1014,7 @@ class XendConfig(dict):
if dev_type == 'vbd' and not target[param]:
# Compat hack -- this is the first disk, so mark it
# bootable.
- dev_info['bootable'] = True
+ dev_info['bootable'] = 1
target[param].append(dev_uuid)
elif dev_type == 'tap':
if 'vbd_refs' not in target:
@@ -1007,7 +1023,7 @@ class XendConfig(dict):
if not target['vbd_refs']:
# Compat hack -- this is the first disk, so mark it
# bootable.
- dev_info['bootable'] = True
+ dev_info['bootable'] = 1
target['vbd_refs'].append(dev_uuid)
elif dev_type == 'vfb':
@@ -1055,7 +1071,9 @@ class XendConfig(dict):
if cfg_xenapi.get('name'):
dev_info['name'] = cfg_xenapi.get('name')
- dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
+ dev_uuid = cfg_xenapi.get('uuid', None)
+ if not dev_uuid:
+ dev_uuid = uuid.createString()
dev_info['uuid'] = dev_uuid
target['devices'][dev_uuid] = (dev_type, dev_info)
target['vif_refs'].append(dev_uuid)
@@ -1070,8 +1088,8 @@ class XendConfig(dict):
dev_info['uname'] = cfg_xenapi.get('image', '')
dev_info['dev'] = '%s:%s' % (cfg_xenapi.get('device'),
old_vbd_type)
- dev_info['bootable'] = cfg_xenapi.get('bootable', False)
- dev_info['driver'] = cfg_xenapi.get('driver')
+ dev_info['bootable'] = int(cfg_xenapi.get('bootable', 0))
+ dev_info['driver'] = cfg_xenapi.get('driver', '')
dev_info['VDI'] = cfg_xenapi.get('VDI', '')
if cfg_xenapi.get('mode') == 'RW':
@@ -1079,7 +1097,9 @@ class XendConfig(dict):
else:
dev_info['mode'] = 'r'
- dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
+ dev_uuid = cfg_xenapi.get('uuid', None)
+ if not dev_uuid:
+ dev_uuid = uuid.createString()
dev_info['uuid'] = dev_uuid
target['devices'][dev_uuid] = (dev_type, dev_info)
target['vbd_refs'].append(dev_uuid)
@@ -1088,13 +1108,17 @@ class XendConfig(dict):
if cfg_xenapi.get('type'):
dev_info['type'] = cfg_xenapi.get('type')
- dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
+ dev_uuid = cfg_xenapi.get('uuid', None)
+ if not dev_uuid:
+ dev_uuid = uuid.createString()
dev_info['uuid'] = dev_uuid
target['devices'][dev_uuid] = (dev_type, dev_info)
target['vtpm_refs'].append(dev_uuid)
elif dev_type == 'console':
- dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
+ dev_uuid = cfg_xenapi.get('uuid', None)
+ if not dev_uuid:
+ dev_uuid = uuid.createString()
dev_info['uuid'] = dev_uuid
dev_info['protocol'] = cfg_xenapi.get('protocol', 'rfb')
dev_info['other_config'] = cfg_xenapi.get('other_config', {})
@@ -1223,7 +1247,12 @@ class XendConfig(dict):
"configuration dictionary.")
sxpr.append(dev_type)
- config = [(opt, val) for opt, val in dev_info.items()]
+ if dev_type in ('console', 'vfb'):
+ config = [(opt, val) for opt, val in dev_info.items()
+ if opt != 'other_config']
+ else:
+ config = [(opt, val) for opt, val in dev_info.items()]
+
sxpr += config
return sxpr
@@ -1356,11 +1385,18 @@ class XendConfig(dict):
val = sxp.child_value(image_sxp, imgkey, None)
if val != None:
type_conv = XENAPI_CFG_TYPES[apikey]
- if callable(conv):
+ if callable(type_conv):
self[apikey] = type_conv(val)
else:
self[apikey] = val
+ self._hvm_boot_params_from_sxp(image_sxp)
+
+ def _hvm_boot_params_from_sxp(self, image_sxp):
+ boot = sxp.child_value(image_sxp, 'boot', None)
+ if boot is not None:
+ self['HVM_boot_policy'] = 'BIOS order'
+ self['HVM_boot_params'] = { 'order' : boot }
#
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index d657d4a1f1..ddc240b96b 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -1648,14 +1648,15 @@ class XendDomainInfo:
kernel = self.info['PV_kernel']
ramdisk = self.info['PV_ramdisk']
args = self.info['PV_args']
- boot = self.info['HVM_boot']
+ boot = self.info['HVM_boot_policy']
if boot:
# HVM booting.
self.info['image']['type'] = 'hvm'
if not 'devices' in self.info['image']:
self.info['image']['devices'] = {}
- self.info['image']['devices']['boot'] = boot
+ self.info['image']['devices']['boot'] = \
+ self.info['HVM_boot_params'].get('order', 'dc')
elif not blexec and kernel:
# Boot from dom0. Nothing left to do -- the kernel and ramdisk
# will be picked up by image.py.
@@ -1976,7 +1977,11 @@ class XendDomainInfo:
else:
return 'unknown'
def get_vcpus_params(self):
- return '' # TODO
+ if self.getDomid() is None:
+ return self.info['vcpus_params']
+
+ retval = xc.sched_credit_domain_get(self.getDomid())
+ return retval
def get_power_state(self):
return XEN_API_VM_POWER_STATE[self.state]
def get_platform_std_vga(self):
diff --git a/tools/python/xen/xend/XendVDI.py b/tools/python/xen/xend/XendVDI.py
index 0868814c8f..f0dda203a8 100644
--- a/tools/python/xen/xend/XendVDI.py
+++ b/tools/python/xen/xend/XendVDI.py
@@ -73,6 +73,7 @@ class XendVDI(AutoSaveObject):
self.sharable = False
self.read_only = False
self.type = "system"
+ self.location = ''
def load_config_dict(self, cfg):
"""Loads configuration into the object from a dict.
@@ -147,9 +148,10 @@ class XendVDI(AutoSaveObject):
'sharable': False,
'readonly': False,
'SR': self.sr_uuid,
+ 'location': self.get_location(),
'VBDs': []}
- def get_image_uri(self):
+ def get_location(self):
raise NotImplementedError()
@@ -163,9 +165,10 @@ class XendQCoWVDI(XendVDI):
self.virtual_size = vsize
self.sector_size = 512
self.auto_save = True
+ self.location = 'tap:qcow:%s' % self.qcow_path
- def get_image_uri(self):
- return 'tap:qcow:%s' % self.qcow_path
+ def get_location(self):
+ return self.location
class XendLocalVDI(XendVDI):
def __init__(self, vdi_struct):
@@ -183,7 +186,7 @@ class XendLocalVDI(XendVDI):
self.type = vdi_struct.get('type', '')
self.sharable = vdi_struct.get('sharable', False)
self.read_only = vdi_struct.get('read_only', False)
- self.image_uri = vdi_struct.get('uri', 'file:/dev/null')
+ self.location = vdi_struct.get('location', 'file:/dev/null')
- def get_image_uri(self):
- return self.image_uri
+ def get_location(self):
+ return self.location
diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py
index eeb8bd0ebd..7a20eae3c8 100644
--- a/tools/python/xen/xend/image.py
+++ b/tools/python/xen/xend/image.py
@@ -449,48 +449,50 @@ class HVMImageHandler(ImageHandler):
return ret
vnc_config = {}
- has_vfb = False
- has_vnc = int(vmConfig['image'].get('vnc')) != 0
+ has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0
+ has_sdl = int(vmConfig['image'].get('sdl', 0)) != 0
for dev_uuid in vmConfig['console_refs']:
- dev_type, dev_info = vmConfig['devices'][devuuid]
- if dev_type == 'rfb':
+ dev_type, dev_info = vmConfig['devices'][dev_uuid]
+ if dev_type == 'vfb':
vnc_config = dev_info.get('other_config', {})
- has_vfb = True
+ has_vnc = True
break
- if not vnc_config:
- for key in ('vncunused', 'vnclisten', 'vncdisplay', 'vncpasswd'):
- if key in vmConfig['image']:
- vnc_config[key] = vmConfig['image'][key]
-
- if not has_vfb and not has_vnc:
- ret.append('-nographic')
- return ret
-
-
- if not vnc_config.get('vncunused', 0) and \
- vnc_config.get('vncdisplay', 0):
- ret.append('-vnc')
- ret.append(str(vncdisplay))
+ if has_vnc:
+ if not vnc_config:
+ for key in ('vncunused', 'vnclisten', 'vncdisplay',
+ 'vncpasswd'):
+ if key in vmConfig['image']:
+ vnc_config[key] = vmConfig['image'][key]
+
+ if not vnc_config.get('vncunused', 0) and \
+ vnc_config.get('vncdisplay', 0):
+ ret.append('-vnc')
+ ret.append(str(vncdisplay))
+ else:
+ ret.append('-vncunused')
+
+ vnclisten = vnc_config.get('vnclisten',
+ xenopts().get_vnclisten_address())
+ ret.append('-vnclisten')
+ ret.append(str(vnclisten))
+
+ # Store vncpassword in xenstore
+ vncpasswd = vnc_config.get('vncpasswd')
+ if not vncpasswd:
+ vncpasswd = xenopts().get_vncpasswd_default()
+
+ if vncpasswd is None:
+ raise VmError('vncpasswd is not setup in vmconfig or '
+ 'xend-config.sxp')
+
+ if vncpasswd != '':
+ self.vm.storeVm('vncpasswd', vncpasswd)
+ elif has_sdl:
+ # SDL is default in QEMU.
+ pass
else:
- ret.append('-vncunused')
-
- vnclisten = vnc_config.get('vnclisten',
- xenopts().get_vnclisten_address())
- ret.append('-vnclisten')
- ret.append(str(vnclisten))
-
- # Store vncpassword in xenstore
- vncpasswd = vnc_config.get('vncpasswd')
- if not vncpasswd:
- vncpasswd = xenopts().get_vncpasswd_default()
-
- if vncpasswd is None:
- raise VmError('vncpasswd is not setup in vmconfig or '
- 'xend-config.sxp')
-
- if vncpasswd != '':
- self.vm.storeVm('vncpasswd', vncpasswd)
+ ret.append('-nographic')
return ret
diff --git a/tools/python/xen/xend/server/vfbif.py b/tools/python/xen/xend/server/vfbif.py
index 0bd1b92bf3..fb510de25f 100644
--- a/tools/python/xen/xend/server/vfbif.py
+++ b/tools/python/xen/xend/server/vfbif.py
@@ -46,7 +46,7 @@ class VfbifController(DevController):
def createDevice(self, config):
DevController.createDevice(self, config)
- if self.vm.info.get('HVM_boot'):
+ if self.vm.info.get('HVM_boot_policy'):
# is HVM, so qemu-dm will handle the vfb.
return
@@ -90,7 +90,7 @@ class VfbifController(DevController):
def waitForDevice(self, devid):
- if self.vm.info.get('HVM_boot'):
+ if self.vm.info.get('HVM_boot_policy'):
log.debug('skip waiting for HVM vfb')
# is a qemu-dm managed device, don't wait for hotplug for these.
return
@@ -110,7 +110,7 @@ class VfbifController(DevController):
raise VmError('Refusing to reconfigure device vfb:%d' % devid)
def destroyDevice(self, devid, force):
- if self.vm.info.get('HVM_boot'):
+ if self.vm.info.get('HVM_boot_policy'):
# remove the backend xenstore entries for HVM guests no matter
# what
DevController.destroyDevice(self, devid, True)
@@ -119,7 +119,7 @@ class VfbifController(DevController):
def migrate(self, deviceConfig, network, dst, step, domName):
- if self.vm.info.get('HVM_boot'):
+ if self.vm.info.get('HVM_boot_policy'):
return 0
return DevController.migrate(self, deviceConfig, network, dst, step,
domName)
@@ -136,14 +136,14 @@ class VkbdifController(DevController):
return (devid, back, front)
def waitForDevice(self, config):
- if self.vm.info.get('HVM_boot'):
+ if self.vm.info.get('HVM_boot_policy'):
# is a qemu-dm managed device, don't wait for hotplug for these.
return
DevController.waitForDevice(self, config)
def destroyDevice(self, devid, force):
- if self.vm.info.get('HVM_boot'):
+ if self.vm.info.get('HVM_boot_policy'):
# remove the backend xenstore entries for HVM guests no matter
# what
DevController.destroyDevice(self, devid, True)
@@ -151,7 +151,7 @@ class VkbdifController(DevController):
DevController.destroyDevice(self, devid, force)
def migrate(self, deviceConfig, network, dst, step, domName):
- if self.vm.info.get('HVM_boot'):
+ if self.vm.info.get('HVM_boot_policy'):
return 0
return DevController.migrate(self, deviceConfig, network, dst, step,
domName)
diff --git a/tools/python/xen/xm/messages/en/xen-xm.po b/tools/python/xen/xm/messages/en/xen-xm.po
index d422b2e6b8..aca4aceafe 100644
--- a/tools/python/xen/xm/messages/en/xen-xm.po
+++ b/tools/python/xen/xm/messages/en/xen-xm.po
@@ -19,7 +19,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Xen-xm 3.0\n"
-"PO-Revision-Date: 2007-01-30 17:15+0000\n"
+"PO-Revision-Date: 2007-01-31 12:34+0000\n"
"Last-Translator: Ewan Mellor <ewan@xensource.com>\n"
"Language-Team: xen-devel <xen-devel@lists.xensource.com>\n"
"MIME-Version: 1.0\n"
@@ -41,6 +41,9 @@ msgstr "The method %(1)s takes %(2)s argument(s) (%(3)s given)."
msgid "SESSION_AUTHENTICATION_FAILED"
msgstr "Permission denied."
+msgid "VALUE_NOT_SUPPORTED"
+msgstr "Value \"%(2)s\" for %(1)s is not supported by this server. The server said \"%(3)s\"."
+
msgid "HOST_CPU_HANDLE_INVALID"
msgstr "The host_cpu handle %(1)s is invalid."
diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
index fac684014a..f3e412da4e 100644
--- a/tools/xcutils/readnotes.c
+++ b/tools/xcutils/readnotes.c
@@ -72,8 +72,8 @@ int main(int argc, char **argv)
usize = xc_dom_check_gzip(image, st.st_size);
if (usize)
{
- tmp = malloc(size);
- xc_dom_do_gunzip(image, st.st_size, tmp, size);
+ tmp = malloc(usize);
+ xc_dom_do_gunzip(image, st.st_size, tmp, usize);
image = tmp;
size = usize;
}
diff --git a/tools/xm-test/configure.ac b/tools/xm-test/configure.ac
index ffbf146f34..d3c651a250 100644
--- a/tools/xm-test/configure.ac
+++ b/tools/xm-test/configure.ac
@@ -11,10 +11,12 @@ AC_PROG_CC
#AC_PROG_INSTALL
AC_CHECK_PROG([LILO], lilo, lilo, "no", [$PATH])
+XEN_PYTHON_PATH=$(/usr/sbin/xen-python-path)
+
# Right now, we can assume that the lib/ directory
# is two levels above the tests
TESTLIB=../../lib
-TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB"
+TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB:$XEN_PYTHON_PATH"
AC_ARG_ENABLE(hvm-support,
[[ --enable-hvm-support enable hardware virtual machine assist]],
diff --git a/tools/xm-test/lib/XmTestLib/XenDomain.py b/tools/xm-test/lib/XmTestLib/XenDomain.py
index 3fcfcea4f1..09d6f4c764 100644
--- a/tools/xm-test/lib/XmTestLib/XenDomain.py
+++ b/tools/xm-test/lib/XmTestLib/XenDomain.py
@@ -33,6 +33,9 @@ from DomainTracking import *
from acm import *
+DOM0_UUID = "00000000-0000-0000-0000-000000000000"
+
+
def getDefaultKernel():
return arch.getDefaultKernel()
diff --git a/tools/xm-test/lib/XmTestLib/__init__.py b/tools/xm-test/lib/XmTestLib/__init__.py
index f638003b08..40aacf7ecd 100644
--- a/tools/xm-test/lib/XmTestLib/__init__.py
+++ b/tools/xm-test/lib/XmTestLib/__init__.py
@@ -3,26 +3,6 @@
# Author: Dan Smith <danms@us.ibm.com>
#
-import os.path
-import sys
-
-# Use the auxbin module in Xend to determine the correct Python path. We
-# take the first installed instance of auxbin that we find, and then run it
-# to determine the correct path, appending that to sys.path.
-
-AUXBIN = 'xen/util/auxbin.py'
-
-for p in ['python%s' % sys.version[:3], 'python']:
- for l in ['/usr/lib64', '/usr/lib']:
- d = os.path.join(l, p)
- if os.path.exists(os.path.join(d, AUXBIN)):
- sys.path.append(d)
- import xen.util.auxbin
- libpath = xen.util.auxbin.libpath()
- sys.path = sys.path[:-1]
- sys.path.append(libpath)
- break
-
from Console import *
from Test import *
from Xm import *
diff --git a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py
index 4798dc13c6..6a17c51045 100644
--- a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py
+++ b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py
@@ -13,7 +13,6 @@
from XmTestLib import xapi
from XmTestLib.XenAPIDomain import XmTestAPIDomain
from XmTestLib import *
-from xen.xend import XendDomain
from vtpm_utils import *
import commands
import os
@@ -28,7 +27,7 @@ except Exception, e:
vm_uuid = domain.get_uuid()
vtpmcfg = {}
-vtpmcfg['backend'] = XendDomain.DOM0_UUID
+vtpmcfg['backend'] = DOM0_UUID
vtpmcfg['VM'] = vm_uuid
session = xapi.connect()
diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index 2d49d412fc..b867febc1e 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -159,7 +159,7 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
return;
dmi_ident[slot] = alloc_bootmem(strlen(p)+1);
if(dmi_ident[slot])
- safe_strcpy(dmi_ident[slot], p);
+ strlcpy(dmi_ident[slot], p, strlen(p)+1);
else
printk(KERN_ERR "dmi_save_ident: out of memory.\n");
}
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index db18c7cecf..d73ae65bd5 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -288,71 +288,73 @@ long arch_do_domctl(
case XEN_DOMCTL_sethvmcontext:
{
- struct hvm_domain_context *c;
+ struct hvm_domain_context c;
struct domain *d;
+ c.cur = 0;
+ c.size = domctl->u.hvmcontext.size;
+ c.data = NULL;
+
ret = -ESRCH;
if ( (d = get_domain_by_id(domctl->domain)) == NULL )
break;
- ret = -ENOMEM;
- if ( (c = xmalloc(struct hvm_domain_context)) == NULL )
- goto sethvmcontext_out;
-
- ret = -EFAULT;
- if ( copy_from_guest(c, domctl->u.hvmcontext.ctxt, 1) != 0 )
- goto sethvmcontext_out;
- c->size = sizeof (c->data);
- c->cur = 0;
-
ret = -EINVAL;
if ( !is_hvm_domain(d) )
goto sethvmcontext_out;
- ret = hvm_load(d, c);
+ ret = -ENOMEM;
+ if ( (c.data = xmalloc_bytes(c.size)) == NULL )
+ goto sethvmcontext_out;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(c.data, domctl->u.hvmcontext.buffer, c.size) != 0)
+ goto sethvmcontext_out;
- xfree(c);
+ ret = hvm_load(d, &c);
sethvmcontext_out:
- put_domain(d);
+ if ( c.data != NULL )
+ xfree(c.data);
+ put_domain(d);
}
break;
case XEN_DOMCTL_gethvmcontext:
{
- struct hvm_domain_context *c;
+ struct hvm_domain_context c;
struct domain *d;
+ c.cur = 0;
+ c.size = domctl->u.hvmcontext.size;
+ c.data = NULL;
+
ret = -ESRCH;
if ( (d = get_domain_by_id(domctl->domain)) == NULL )
break;
- ret = -ENOMEM;
- if ( (c = xmalloc(struct hvm_domain_context)) == NULL )
- goto gethvmcontext_out;
- memset(c, 0, sizeof(*c));
- c->size = sizeof (c->data);
-
- ret = -ENODATA;
+ ret = -EINVAL;
if ( !is_hvm_domain(d) )
goto gethvmcontext_out;
-
- ret = 0;
- if (hvm_save(d, c) != 0)
- ret = -EFAULT;
- if ( copy_to_guest(domctl->u.hvmcontext.ctxt, c, 1) )
- ret = -EFAULT;
+ ret = -ENOMEM;
+ if ( (c.data = xmalloc_bytes(c.size)) == NULL )
+ goto gethvmcontext_out;
- xfree(c);
+ ret = hvm_save(d, &c);
+
+ if ( copy_to_guest(domctl->u.hvmcontext.buffer, c.data, c.size) != 0 )
+ ret = -EFAULT;
if ( copy_to_guest(u_domctl, domctl, 1) )
ret = -EFAULT;
gethvmcontext_out:
- put_domain(d);
+ if ( c.data != NULL )
+ xfree(c.data);
+ put_domain(d);
}
break;
diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c
index b0f6413669..dcc6ca3a4d 100644
--- a/xen/arch/x86/hvm/hpet.c
+++ b/xen/arch/x86/hvm/hpet.c
@@ -279,7 +279,7 @@ static void hpet_write(
(h->hpet.timers[tn].config & HPET_TN_SETVAL) )
h->hpet.timers[tn].cmp = new_val;
else
- h->period[tn] = new_val;
+ h->hpet.period[tn] = new_val;
h->hpet.timers[tn].config &= ~HPET_TN_SETVAL;
if ( hpet_enabled(h) && timer_enabled(h, tn) )
hpet_set_timer(h, tn);
@@ -289,7 +289,7 @@ static void hpet_write(
case HPET_T1_ROUTE:
case HPET_T2_ROUTE:
tn = (addr - HPET_T0_ROUTE) >> 5;
- h->hpet.timers[tn].hpet_fsb[0] = new_val;
+ h->hpet.timers[tn].fsb = new_val;
break;
default:
@@ -351,21 +351,22 @@ static void hpet_timer_fn(void *opaque)
hpet_route_interrupt(h, tn);
- if ( timer_is_periodic(h, tn) && (h->period[tn] != 0) )
+ if ( timer_is_periodic(h, tn) && (h->hpet.period[tn] != 0) )
{
uint64_t mc = hpet_read_maincounter(h);
if ( timer_is_32bit(h, tn) )
{
while ( hpet_time_after(mc, h->hpet.timers[tn].cmp) )
h->hpet.timers[tn].cmp = (uint32_t)(
- h->hpet.timers[tn].cmp + h->period[tn]);
+ h->hpet.timers[tn].cmp + h->hpet.period[tn]);
}
else
{
while ( hpet_time_after64(mc, h->hpet.timers[tn].cmp) )
- h->hpet.timers[tn].cmp += h->period[tn];
+ h->hpet.timers[tn].cmp += h->hpet.period[tn];
}
- set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, h->period[tn]));
+ set_timer(&h->timers[tn],
+ NOW() + hpet_tick_to_ns(h, h->hpet.period[tn]));
}
}
@@ -378,6 +379,35 @@ void hpet_migrate_timers(struct vcpu *v)
migrate_timer(&h->timers[i], v->processor);
}
+static int hpet_save(struct domain *d, hvm_domain_context_t *h)
+{
+ HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
+
+ /* Save the HPET registers */
+ return hvm_save_entry(HPET, 0, h, &hp->hpet);
+}
+
+static int hpet_load(struct domain *d, hvm_domain_context_t *h)
+{
+ HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
+ int i;
+
+ /* Reload the HPET registers */
+ if ( hvm_load_entry(HPET, h, &hp->hpet) )
+ return -EINVAL;
+
+ /* Recalculate the offset between the main counter and guest time */
+ hp->mc_offset = hp->hpet.mc64 - hvm_get_guest_time(hp->vcpu);
+
+ /* Restart the timers */
+ for ( i = 0; i < HPET_TIMER_NUM; i++ )
+ hpet_set_timer(hp, i);
+
+ return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(HPET, hpet_save, hpet_load);
+
void hpet_init(struct vcpu *v)
{
HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet;
diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c
index 802f67e077..f130a252ab 100644
--- a/xen/arch/x86/hvm/intercept.c
+++ b/xen/arch/x86/hvm/intercept.c
@@ -205,7 +205,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h)
if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
{
gdprintk(XENLOG_ERR, "HVM save: failed to write header\n");
- return -1;
+ return -EFAULT;
}
/* Save all available kinds of state */
@@ -219,7 +219,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h)
{
gdprintk(XENLOG_ERR,
"HVM save: failed to save type %"PRIu16"\n", i);
- return -1;
+ return -EFAULT;
}
}
}
@@ -229,7 +229,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h)
{
/* Run out of data */
gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n");
- return -1;
+ return -EFAULT;
}
/* Save macros should not have let us overrun */
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index b2637a7807..a35b84848d 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -660,6 +660,13 @@ void svm_update_guest_cr3(struct vcpu *v)
v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
}
+static void svm_update_vtpr(struct vcpu *v, unsigned long value)
+{
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
+ vmcb->vintr.fields.tpr = value & 0x0f;
+}
+
unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num)
{
switch ( num )
@@ -1048,6 +1055,8 @@ int start_svm(void)
hvm_funcs.update_host_cr3 = svm_update_host_cr3;
hvm_funcs.update_guest_cr3 = svm_update_guest_cr3;
+ hvm_funcs.update_vtpr = svm_update_vtpr;
+
hvm_funcs.stts = svm_stts;
hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
@@ -1939,6 +1948,7 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
case 8:
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
+ vmcb->vintr.fields.tpr = value & 0x0F;
break;
default:
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index 4ac13ba9c4..b38dee2e85 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -593,6 +593,7 @@ static void vlapic_write(struct vcpu *v, unsigned long address,
{
case APIC_TASKPRI:
vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
+ hvm_update_vtpr(v, (val >> 4) & 0x0f);
break;
case APIC_EOI:
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index c3a2ed4585..8a8691c383 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -986,6 +986,11 @@ static void vmx_inject_exception(
v->arch.hvm_vmx.cpu_cr2 = cr2;
}
+static void vmx_update_vtpr(struct vcpu *v, unsigned long value)
+{
+ /* VMX doesn't have a V_TPR field */
+}
+
/* Setup HVM interfaces */
static void vmx_setup_hvm_funcs(void)
{
@@ -1011,6 +1016,8 @@ static void vmx_setup_hvm_funcs(void)
hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3;
+ hvm_funcs.update_vtpr = vmx_update_vtpr;
+
hvm_funcs.stts = vmx_stts;
hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 16b1e48ca8..dfa22bce04 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -597,6 +597,11 @@ static int emulate_forced_invalid_op(struct cpu_user_regs *regs)
if ( !IS_PRIV(current->domain) )
clear_bit(X86_FEATURE_MTRR, &d);
}
+ else if ( regs->eax == 0x80000001 )
+ {
+ /* Modify Feature Information. */
+ clear_bit(X86_FEATURE_RDTSCP % 32, &d);
+ }
else
{
(void)cpuid_hypervisor_leaves(regs->eax, &a, &b, &c, &d);
diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
index dadd1abe65..070deec3d1 100644
--- a/xen/arch/x86/x86_64/compat/entry.S
+++ b/xen/arch/x86/x86_64/compat/entry.S
@@ -281,9 +281,6 @@ CFIX14:
.quad CFLT14,CFIX14
.previous
-compat_domctl:
-compat_sysctl:
-
.section .rodata, "a", @progbits
ENTRY(compat_hypercall_table)
@@ -365,8 +362,8 @@ ENTRY(compat_hypercall_args_table)
.byte 2 /* compat_event_channel_op */
.byte 2 /* compat_physdev_op */
.byte 2 /* do_hvm_op */
- .byte 1 /* compat_sysctl */ /* 35 */
- .byte 1 /* compat_domctl */
+ .byte 1 /* do_sysctl */ /* 35 */
+ .byte 1 /* do_domctl */
.byte 2 /* compat_kexec_op */
.rept NR_hypercalls-(.-compat_hypercall_args_table)
.byte 0 /* compat_ni_hypercall */
diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 04a1468d3a..a9e85cad7f 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -131,12 +131,20 @@ __initcall(register_crashdump_trigger);
static void setup_note(Elf_Note *n, const char *name, int type, int descsz)
{
- safe_strcpy(ELFNOTE_NAME(n), name);
- n->namesz = strlen(name);
+ int l = strlen(name) + 1;
+ strlcpy(ELFNOTE_NAME(n), name, l);
+ n->namesz = l;
n->descsz = descsz;
n->type = type;
}
+static int sizeof_note(const char *name, int descsz)
+{
+ return (sizeof(Elf_Note) +
+ ELFNOTE_ALIGN(strlen(name)+1) +
+ ELFNOTE_ALIGN(descsz));
+}
+
#define kexec_get(x) kexec_get_##x
#endif
@@ -155,23 +163,24 @@ static int kexec_get(reserve)(xen_kexec_range_t *range)
static int kexec_get(xen)(xen_kexec_range_t *range)
{
range->start = virt_to_maddr(_start);
- range->size = (unsigned long)_end - (unsigned long)_start;
+ range->size = (unsigned long)xenheap_phys_end - (unsigned long)range->start;
return 0;
}
static int kexec_get(cpu)(xen_kexec_range_t *range)
{
int nr = range->nr;
- int nr_bytes = sizeof(Elf_Note) * 2
- + ELFNOTE_ALIGN(sizeof(ELF_Prstatus))
- + ELFNOTE_ALIGN(sizeof(crash_xen_core_t));
+ int nr_bytes = 0;
if ( nr < 0 || nr >= num_present_cpus() )
return -EINVAL;
+ nr_bytes += sizeof_note("CORE", sizeof(ELF_Prstatus));
+ nr_bytes += sizeof_note("Xen", sizeof(crash_xen_core_t));
+
/* The Xen info note is included in CPU0's range. */
if ( nr == 0 )
- nr_bytes += sizeof(Elf_Note) + ELFNOTE_ALIGN(sizeof(crash_xen_info_t));
+ nr_bytes += sizeof_note("Xen", sizeof(crash_xen_info_t));
if ( per_cpu(crash_notes, nr) == NULL )
{
diff --git a/xen/common/perfc.c b/xen/common/perfc.c
index bbff5d7b5c..d5bcd9b2e1 100644
--- a/xen/common/perfc.c
+++ b/xen/common/perfc.c
@@ -136,8 +136,8 @@ static xen_sysctl_perfc_desc_t perfc_d[NR_PERFCTRS];
static xen_sysctl_perfc_val_t *perfc_vals;
static int perfc_nbr_vals;
static int perfc_init = 0;
-static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
- XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val)
+static int perfc_copy_info(XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc,
+ XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val)
{
unsigned int i, j;
unsigned int v = 0;
@@ -217,20 +217,29 @@ static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
int perfc_control(xen_sysctl_perfc_op_t *pc)
{
static DEFINE_SPINLOCK(lock);
+ XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc;
+ XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val;
int rc;
+ /*
+ * 64 bit guest handles cannot be passed as parameters to
+ * functions so cast to a regular guest handle.
+ */
+ desc = guest_handle_cast(pc->desc, xen_sysctl_perfc_desc_t);
+ val = guest_handle_cast(pc->val, xen_sysctl_perfc_val_t);
+
spin_lock(&lock);
switch ( pc->cmd )
{
case XEN_SYSCTL_PERFCOP_reset:
- perfc_copy_info(pc->desc, pc->val);
+ perfc_copy_info(desc, val);
perfc_reset(0);
rc = 0;
break;
case XEN_SYSCTL_PERFCOP_query:
- perfc_copy_info(pc->desc, pc->val);
+ perfc_copy_info(desc, val);
rc = 0;
break;
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index a092a83ad5..a6f2f757bc 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -49,6 +49,7 @@
#define X86_FEATURE_MP (1*32+19) /* MP Capable. */
#define X86_FEATURE_NX (1*32+20) /* Execute Disable */
#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */
+#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */
#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */
#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */
#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index f0b818462b..8c5c5f2748 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -49,8 +49,6 @@ struct hvm_domain {
spinlock_t pbuf_lock;
uint64_t params[HVM_NR_PARAMS];
-
- struct hvm_domain_context *hvm_ctxt;
};
#endif /* __ASM_X86_HVM_DOMAIN_H__ */
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index 953cc60b3c..1e8093dafa 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -115,6 +115,11 @@ struct hvm_function_table {
void (*update_guest_cr3)(struct vcpu *v);
/*
+ * Reflect the virtual APIC's value in the guest's V_TPR register
+ */
+ void (*update_vtpr)(struct vcpu *v, unsigned long value);
+
+ /*
* Update specifics of the guest state:
* 1) TS bit in guest cr0
* 2) TSC offset in guest
@@ -203,6 +208,12 @@ hvm_update_host_cr3(struct vcpu *v)
hvm_funcs.update_host_cr3(v);
}
+static inline void
+hvm_update_vtpr(struct vcpu *v, unsigned long value)
+{
+ hvm_funcs.update_vtpr(v, value);
+}
+
void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3);
void hvm_hypercall_page_initialise(struct domain *d,
diff --git a/xen/include/asm-x86/hvm/support.h b/xen/include/asm-x86/hvm/support.h
index 066fba87d0..6d57140fae 100644
--- a/xen/include/asm-x86/hvm/support.h
+++ b/xen/include/asm-x86/hvm/support.h
@@ -123,6 +123,13 @@ extern unsigned int opt_hvm_debug_level;
* Save/restore support
*/
+/* Marshalling and unmarshalling uses a buffer with size and cursor. */
+typedef struct hvm_domain_context {
+ uint32_t cur;
+ uint32_t size;
+ uint8_t *data;
+} hvm_domain_context_t;
+
/* Marshalling an entry: check space and fill in the header */
static inline int _hvm_init_entry(struct hvm_domain_context *h,
uint16_t tc, uint16_t inst, uint32_t len)
diff --git a/xen/include/asm-x86/hvm/vpt.h b/xen/include/asm-x86/hvm/vpt.h
index f51e16948a..7868404426 100644
--- a/xen/include/asm-x86/hvm/vpt.h
+++ b/xen/include/asm-x86/hvm/vpt.h
@@ -31,22 +31,6 @@
#include <asm/hvm/vpic.h>
#include <public/hvm/save.h>
-#define HPET_TIMER_NUM 3 /* 3 timers supported now */
-struct HPET {
- uint64_t capability; /* capabilities */
- uint64_t res0; /* reserved */
- uint64_t config; /* configuration */
- uint64_t res1; /* reserved */
- uint64_t isr; /* interrupt status reg */
- uint64_t res2[25]; /* reserved */
- uint64_t mc64; /* main counter */
- uint64_t res3; /* reserved */
- struct { /* timers */
- uint64_t config; /* configuration/cap */
- uint64_t cmp; /* comparator */
- uint64_t hpet_fsb[2]; /* FSB route, not supported now */
- } timers[HPET_TIMER_NUM];
-};
struct HPETState;
struct HPET_timer_fn_info {
@@ -55,11 +39,10 @@ struct HPET_timer_fn_info {
};
typedef struct HPETState {
- struct HPET hpet;
- struct vcpu *vcpu;
- uint64_t tsc_freq;
- uint64_t mc_offset;
- uint64_t period[HPET_TIMER_NUM];
+ struct hvm_hw_hpet hpet;
+ struct vcpu *vcpu;
+ uint64_t tsc_freq;
+ uint64_t mc_offset;
struct timer timers[HPET_TIMER_NUM];
struct HPET_timer_fn_info timer_fn_info[HPET_TIMER_NUM];
} HPETState;
diff --git a/xen/include/public/arch-x86/xen-x86_32.h b/xen/include/public/arch-x86/xen-x86_32.h
index 6728b818cd..2633ff082f 100644
--- a/xen/include/public/arch-x86/xen-x86_32.h
+++ b/xen/include/public/arch-x86/xen-x86_32.h
@@ -103,7 +103,7 @@
(hnd).p = val; \
} while ( 0 )
#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
-#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name
+#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name __attribute__((aligned(8)))
#endif
#ifndef __ASSEMBLY__
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index ad255f24d1..93f44f3ba5 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -386,18 +386,11 @@ struct xen_domctl_settimeoffset {
typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
-#define HVM_CTXT_SIZE 8192
-typedef struct hvm_domain_context {
- uint32_t cur;
- uint32_t size;
- uint8_t data[HVM_CTXT_SIZE];
-} hvm_domain_context_t;
-DEFINE_XEN_GUEST_HANDLE(hvm_domain_context_t);
-
#define XEN_DOMCTL_gethvmcontext 33
#define XEN_DOMCTL_sethvmcontext 34
typedef struct xen_domctl_hvmcontext {
- XEN_GUEST_HANDLE_64(hvm_domain_context_t) ctxt; /* IN/OUT */
+ uint32_t size; /* IN/OUT: size of buffer / bytes filled */
+ XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT */
} xen_domctl_hvmcontext_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t);
diff --git a/xen/include/public/foreign/Makefile b/xen/include/public/foreign/Makefile
index 7f91dd87b9..7bf028e72a 100644
--- a/xen/include/public/foreign/Makefile
+++ b/xen/include/public/foreign/Makefile
@@ -13,9 +13,16 @@ clean:
rm -f checker checker.c $(XEN_TARGET_ARCH).size
rm -f *.pyc *.o *~
+ifeq ($(CROSS_COMPILE),)
check-headers: checker
./checker > $(XEN_TARGET_ARCH).size
diff -u reference.size $(XEN_TARGET_ARCH).size
+checker: checker.c $(headers)
+ $(HOSTCC) $(CFLAGS) -o $@ $<
+else
+check-headers:
+ @echo "cross build: skipping check"
+endif
x86_32.h: ../arch-x86/xen-x86_32.h ../arch-x86/xen.h ../xen.h $(scripts)
python mkheader.py $* $@ $(filter %.h,$^)
@@ -26,8 +33,5 @@ x86_64.h: ../arch-x86/xen-x86_64.h ../arch-x86/xen.h ../xen.h $(scripts)
ia64.h: ../arch-ia64.h ../xen.h $(scripts)
python mkheader.py $* $@ $(filter %.h,$^)
-checker: checker.c $(headers)
- $(HOSTCC) $(CFLAGS) -o $@ $<
-
checker.c: $(scripts)
python mkchecker.py $(XEN_TARGET_ARCH) $@ $(architectures)
diff --git a/xen/include/public/hvm/save.h b/xen/include/public/hvm/save.h
index fbf160b8ef..48dfc187f0 100644
--- a/xen/include/public/hvm/save.h
+++ b/xen/include/public/hvm/save.h
@@ -381,10 +381,40 @@ struct hvm_hw_rtc {
DECLARE_HVM_SAVE_TYPE(RTC, 9, struct hvm_hw_rtc);
+/*
+ * HPET
+ */
+
+#define HPET_TIMER_NUM 3 /* 3 timers supported now */
+struct hvm_hw_hpet {
+ /* Memory-mapped, software visible registers */
+ uint64_t capability; /* capabilities */
+ uint64_t res0; /* reserved */
+ uint64_t config; /* configuration */
+ uint64_t res1; /* reserved */
+ uint64_t isr; /* interrupt status reg */
+ uint64_t res2[25]; /* reserved */
+ uint64_t mc64; /* main counter */
+ uint64_t res3; /* reserved */
+ struct { /* timers */
+ uint64_t config; /* configuration/cap */
+ uint64_t cmp; /* comparator */
+ uint64_t fsb; /* FSB route, not supported now */
+ uint64_t res4; /* reserved */
+ } timers[HPET_TIMER_NUM];
+ uint64_t res5[4*(24-HPET_TIMER_NUM)]; /* reserved, up to 0x3ff */
+
+ /* Hidden register state */
+ uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
+};
+
+DECLARE_HVM_SAVE_TYPE(HPET, 10, struct hvm_hw_hpet);
+
+
/*
* Largest type-code in use
*/
-#define HVM_SAVE_CODE_MAX 9
+#define HVM_SAVE_CODE_MAX 10
/*
diff --git a/xen/include/xen/string.h b/xen/include/xen/string.h
index d0c23a1411..f26b9949b2 100644
--- a/xen/include/xen/string.h
+++ b/xen/include/xen/string.h
@@ -82,8 +82,16 @@ extern void * memchr(const void *,int,__kernel_size_t);
}
#endif
+#define is_char_array(x) __builtin_types_compatible_p(typeof(x), char[])
+
/* safe_xxx always NUL-terminates and returns !=0 if result is truncated. */
-#define safe_strcpy(d, s) (strlcpy(d, s, sizeof(d)) >= sizeof(d))
-#define safe_strcat(d, s) (strlcat(d, s, sizeof(d)) >= sizeof(d))
+#define safe_strcpy(d, s) ({ \
+ BUILD_BUG_ON(!is_char_array(d)); \
+ (strlcpy(d, s, sizeof(d)) >= sizeof(d)); \
+})
+#define safe_strcat(d, s) ({ \
+ BUILD_BUG_ON(!is_char_array(d)); \
+ (strlcat(d, s, sizeof(d)) >= sizeof(d)); \
+})
#endif /* _LINUX_STRING_H_ */
diff --git a/xen/tools/get-fields.sh b/xen/tools/get-fields.sh
index ccf5675c02..0936bb8fe3 100644
--- a/xen/tools/get-fields.sh
+++ b/xen/tools/get-fields.sh
@@ -227,7 +227,7 @@ handle_array() {
build_body() {
echo
- echo -n "#define XLAT_$1(_d_, _s_)"
+ echo -n "#define XLAT_$1(_d_, _s_) do {"
local level=1 fields= id= array= arrlvl=1 array_type= type= token
for token in $2
do
@@ -303,6 +303,8 @@ build_body() {
esac
test -z "$fields" || fields="$fields $token"
done
+ echo " \\"
+ echo "} while (0)"
echo ""
}