[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User awilliam@xxxxxxxxxxxx # Date 1170617093 25200 # Node ID fbc128aafdeb9c3726495211e0b017951672912a # Parent 976dd90c2fdb4ecb86b0c14a95fb0591abe23249 # Parent 01ec7dba9ff805a5c74a0318997b747d3e3e3327 merge with xen-unstable.hg --- buildconfigs/linux-defconfig_xen_x86_32 | 1 docs/xen-api/xenapi-datamodel.tex | 225 +++++++- extras/mini-os/arch/x86/x86_32.S | 9 extras/mini-os/xenbus/xenbus.c | 2 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 5 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c | 7 linux-2.6-xen-sparse/include/xen/xenbus.h | 2 patches/linux-2.6.18/xenoprof-generic.patch | 4 tools/Rules.mk | 2 tools/libxc/xc_dom_boot.c | 99 +-- tools/libxc/xc_dom_core.c | 3 tools/libxc/xc_dom_ia64.c | 6 tools/libxc/xc_dom_x86.c | 4 tools/libxc/xc_domain.c | 56 +- tools/libxc/xc_hvm_restore.c | 33 - tools/libxc/xc_hvm_save.c | 52 - tools/libxc/xc_linux_save.c | 2 tools/libxc/xenctrl.h | 12 tools/libxen/Makefile | 3 tools/libxen/include/xen_host.h | 7 tools/libxen/include/xen_vdi.h | 1 tools/libxen/include/xen_vm.h | 61 +- tools/libxen/include/xen_vm_power_state.h | 5 tools/libxen/src/xen_common.c | 150 +++-- tools/libxen/src/xen_host.c | 17 tools/libxen/src/xen_int_float_map.c | 6 tools/libxen/src/xen_string_string_map.c | 6 tools/libxen/src/xen_vdi.c | 3 tools/libxen/src/xen_vm.c | 103 +++ tools/libxen/src/xen_vm_power_state.c | 1 tools/libxen/test/test_bindings.c | 112 +++- tools/libxen/test/test_hvm_bindings.c | 445 ++++++++++++++++ tools/misc/Makefile | 2 tools/misc/xen-python-path | 41 + tools/misc/xend | 22 tools/pygrub/src/pygrub | 5 tools/python/scripts/test_hvm_create.py | 9 tools/python/scripts/test_vm_create.py | 11 tools/python/xen/xend/XendAPI.py | 64 +- tools/python/xen/xend/XendAPIConstants.py | 12 tools/python/xen/xend/XendBootloader.py | 4 tools/python/xen/xend/XendConfig.py | 106 ++- tools/python/xen/xend/XendDomainInfo.py | 11 tools/python/xen/xend/XendVDI.py | 15 tools/python/xen/xend/image.py | 76 +- tools/python/xen/xend/server/vfbif.py | 14 tools/python/xen/xm/messages/en/xen-xm.po | 5 tools/xcutils/readnotes.c | 4 tools/xm-test/configure.ac | 4 tools/xm-test/lib/XmTestLib/XenDomain.py | 3 tools/xm-test/lib/XmTestLib/__init__.py | 20 tools/xm-test/tests/vtpm/09_vtpm-xapi.py | 3 xen/arch/x86/dmi_scan.c | 2 xen/arch/x86/domctl.c | 70 +- xen/arch/x86/hvm/hpet.c | 44 + xen/arch/x86/hvm/intercept.c | 6 xen/arch/x86/hvm/svm/svm.c | 10 xen/arch/x86/hvm/vlapic.c | 1 xen/arch/x86/hvm/vmx/vmx.c | 7 xen/arch/x86/traps.c | 5 xen/arch/x86/x86_64/compat/entry.S | 7 xen/common/kexec.c | 23 xen/common/perfc.c | 17 xen/include/asm-x86/cpufeature.h | 1 xen/include/asm-x86/hvm/domain.h | 2 xen/include/asm-x86/hvm/hvm.h | 11 xen/include/asm-x86/hvm/support.h | 7 xen/include/asm-x86/hvm/vpt.h | 25 xen/include/public/arch-x86/xen-x86_32.h | 2 xen/include/public/domctl.h | 11 xen/include/public/foreign/Makefile | 10 xen/include/public/hvm/save.h | 32 + xen/include/xen/string.h | 12 xen/tools/get-fields.sh | 4 74 files changed, 1642 insertions(+), 542 deletions(-) diff -r 976dd90c2fdb -r fbc128aafdeb buildconfigs/linux-defconfig_xen_x86_32 --- a/buildconfigs/linux-defconfig_xen_x86_32 Sun Feb 04 12:18:48 2007 -0700 +++ b/buildconfigs/linux-defconfig_xen_x86_32 Sun Feb 04 12:24:53 2007 -0700 @@ -1268,6 +1268,7 @@ CONFIG_I2O=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 -r 976dd90c2fdb -r fbc128aafdeb docs/xen-api/xenapi-datamodel.tex --- a/docs/xen-api/xenapi-datamodel.tex Sun Feb 04 12:18:48 2007 -0700 +++ b/docs/xen-api/xenapi-datamodel.tex Sun Feb 04 12:24:53 2007 -0700 @@ -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 @@ virtual machine (or 'guest'). 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 @@ PV/bootloader and PV/kernel are empty, t 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 @@ Quals & Field & Type & Description \\ $\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} - -{\bf Overview:} -Get the HVM/boot field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} string get_HVM_boot (session_id s, VM ref self)\end{verbatim} +\subsubsection{RPC name:~get\_HVM\_boot\_policy} + +{\bf Overview:} +Get the HVM/boot\_policy field of the given VM. + + \noindent {\bf Signature:} +\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} - -{\bf Overview:} -Set the HVM/boot field of the given VM. - - \noindent {\bf Signature:} -\begin{verbatim} void set_HVM_boot (session_id s, VM ref self, string value)\end{verbatim} +\subsubsection{RPC name:~set\_HVM\_boot\_policy} + +{\bf Overview:} +Set the HVM/boot\_policy field of the given VM. + + \noindent {\bf Signature:} +\begin{verbatim} void set_HVM_boot_policy (session_id s, VM ref self, string value)\end{verbatim} \noindent{\bf Arguments:} @@ -3348,6 +3351,143 @@ Set the HVM/boot field of the given VM. {\tt VM ref } & self & reference to the object \\ \hline {\tt string } & 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:~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} @@ -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 valu \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 -r 976dd90c2fdb -r fbc128aafdeb extras/mini-os/arch/x86/x86_32.S --- a/extras/mini-os/arch/x86/x86_32.S Sun Feb 04 12:18:48 2007 -0700 +++ b/extras/mini-os/arch/x86/x86_32.S Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb extras/mini-os/xenbus/xenbus.c --- a/extras/mini-os/xenbus/xenbus.c Sun Feb 04 12:18:48 2007 -0700 +++ b/extras/mini-os/xenbus/xenbus.c Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Sun Feb 04 12:18:48 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Sun Feb 04 12:24:53 2007 -0700 @@ -1935,8 +1935,6 @@ static struct net_device * __devinit cre 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 cre SET_NETDEV_DEV(netdev, &dev->dev); np->netdev = netdev; + + netif_carrier_off(netdev); + return netdev; exit_free_tx: diff -r 976dd90c2fdb -r fbc128aafdeb linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Sun Feb 04 12:18:48 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Sun Feb 04 12:24:53 2007 -0700 @@ -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) -{ - static char *name[] = { +const char *xenbus_strstate(enum xenbus_state state) +{ + static const char *const name[] = { [ XenbusStateUnknown ] = "Unknown", [ XenbusStateInitialising ] = "Initialising", [ XenbusStateInitWait ] = "InitWait", @@ -55,6 +55,7 @@ char *xenbus_strstate(enum xenbus_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 -r 976dd90c2fdb -r fbc128aafdeb linux-2.6-xen-sparse/include/xen/xenbus.h --- a/linux-2.6-xen-sparse/include/xen/xenbus.h Sun Feb 04 12:18:48 2007 -0700 +++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Sun Feb 04 12:24:53 2007 -0700 @@ -295,7 +295,7 @@ void xenbus_dev_fatal(struct xenbus_devi 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 -r 976dd90c2fdb -r fbc128aafdeb patches/linux-2.6.18/xenoprof-generic.patch --- a/patches/linux-2.6.18/xenoprof-generic.patch Sun Feb 04 12:18:48 2007 -0700 +++ b/patches/linux-2.6.18/xenoprof-generic.patch Sun Feb 04 12:24:53 2007 -0700 @@ -363,9 +363,9 @@ diff -pruN ../orig-linux-2.6.18/drivers/ + 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/ + 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 -r 976dd90c2fdb -r fbc128aafdeb tools/Rules.mk --- a/tools/Rules.mk Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/Rules.mk Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxc/xc_dom_boot.c --- a/tools/libxc/xc_dom_boot.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxc/xc_dom_boot.c Sun Feb 04 12:24:53 2007 -0700 @@ -144,7 +144,7 @@ static int x86_shadow(int xc, domid_t do 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_do return rc; } -static int arch_setup_middle(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_bootearly(struct xc_dom_image *dom) +{ + xc_dom_printf("%s: doing nothing\n", __FUNCTION__); + return 0; +} + +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 #elif defined(__ia64__) -static int arch_setup_early(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_meminit(struct xc_dom_image *dom) +{ + xc_dom_printf("%s: doing nothing\n", __FUNCTION__); + return 0; +} + +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_d 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_d 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 #elif defined(__powerpc64__) -static int arch_setup_early(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) -{ - xc_dom_printf("%s: doing nothing\n", __FUNCTION__); - return 0; -} - -static int arch_setup_late(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_bootearly(struct xc_dom_image *dom) +{ + xc_dom_printf("%s: doing nothing\n", __FUNCTION__); + return 0; +} + +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 #else -static int arch_setup_early(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) -{ - xc_dom_printf("%s: doing nothing\n", __FUNCTION__); - return 0; -} - -static int arch_setup_late(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_bootearly(struct xc_dom_image *dom) +{ + xc_dom_printf("%s: doing nothing\n", __FUNCTION__); + return 0; +} + +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_i 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_i 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_imag 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_imag 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxc/xc_dom_core.c --- a/tools/libxc/xc_dom_core.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxc/xc_dom_core.c Sun Feb 04 12:24:53 2007 -0700 @@ -717,6 +717,9 @@ int xc_dom_build_image(struct xc_dom_ima } 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxc/xc_dom_ia64.c --- a/tools/libxc/xc_dom_ia64.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxc/xc_dom_ia64.c Sun Feb 04 12:24:53 2007 -0700 @@ -26,11 +26,7 @@ static int alloc_magic_pages(struct xc_d /* 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxc/xc_dom_x86.c --- a/tools/libxc/xc_dom_x86.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxc/xc_dom_x86.c Sun Feb 04 12:24:53 2007 -0700 @@ -66,11 +66,12 @@ static int count_pgtables(struct xc_dom_ 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_d if (xc_dom_feature_translated(dom)) dom->shared_info_pfn = xc_dom_alloc_page(dom, "shared info"); dom->alloc_bootstack = 1; + return 0; } diff -r 976dd90c2fdb -r fbc128aafdeb tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxc/xc_domain.c Sun Feb 04 12:24:53 2007 -0700 @@ -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) -{ - int rc; + uint8_t *ctxt_buf, + uint32_t size) +{ + int ret; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_gethvmcontext; domctl.domain = (domid_t)domid; - set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt); - - if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 ) - return rc; - - rc = do_domctl(xc_handle, &domctl); - - safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt)); - - return rc; + domctl.u.hvmcontext.size = size; + set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf); + + if ( (ret = lock_pages(ctxt_buf, size)) != 0 ) + return ret; + + ret = do_domctl(xc_handle, &domctl); + + unlock_pages(ctxt_buf, size); + + 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) -{ - int rc; + uint8_t *ctxt_buf, + uint32_t size) +{ + int ret; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_sethvmcontext; domctl.domain = domid; - set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt); - - if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 ) - return rc; - - rc = do_domctl(xc_handle, &domctl); - - safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt)); - - return rc; + domctl.u.hvmcontext.size = size; + set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf); + + if ( (ret = lock_pages(ctxt_buf, size)) != 0 ) + return ret; + + ret = do_domctl(xc_handle, &domctl); + + unlock_pages(ctxt_buf, size); + + return ret; } int xc_vcpu_getcontext(int xc_handle, diff -r 976dd90c2fdb -r fbc128aafdeb tools/libxc/xc_hvm_restore.c --- a/tools/libxc/xc_hvm_restore.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxc/xc_hvm_restore.c Sun Feb 04 12:24:53 2007 -0700 @@ -87,7 +87,7 @@ int xc_hvm_restore(int xc_handle, int io 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 } - 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 ERROR("error read hvm context size!\n"); goto out; } - if (rec_len != sizeof(hvm_ctxt)) { - ERROR("hvm context size dismatch!\n"); - goto out; - } - - if (!read_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt))) { - ERROR("error read hvm context!\n"); - goto out; - } - - if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, &hvm_ctxt))) { - ERROR("error set hvm context!\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_buf, rec_len)) { + ERROR("error read hvm buffer!\n"); + goto out; + } + + 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 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxc/xc_hvm_save.c --- a/tools/libxc/xc_hvm_save.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxc/xc_hvm_save.c Sun Feb 04 12:24:53 2007 -0700 @@ -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 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 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 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 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"); - goto out; - } - - rec_size = sizeof(hvm_ctxt); + 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; + } + if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) { - ERROR("error write hvm ctxt size"); - goto out; - } - - if ( !write_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt)) ) { + ERROR("error write hvm buffer size"); + goto out; + } + + 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 } } + free(hvm_buf); free(page_array); free(pfn_type); diff -r 976dd90c2fdb -r fbc128aafdeb tools/libxc/xc_linux_save.c --- a/tools/libxc/xc_linux_save.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxc/xc_linux_save.c Sun Feb 04 12:24:53 2007 -0700 @@ -536,8 +536,6 @@ static int canonicalize_pagetable(unsign 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxc/xenctrl.h Sun Feb 04 12:24:53 2007 -0700 @@ -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_hand * @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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/Makefile --- a/tools/libxen/Makefile Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/Makefile Sun Feb 04 12:24:53 2007 -0700 @@ -51,6 +51,9 @@ test/test_bindings: test/test_bindings.o 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/include/xen_host.h --- a/tools/libxen/include/xen_host.h Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/include/xen_host.h Sun Feb 04 12:24:53 2007 -0700 @@ -394,6 +394,13 @@ xen_host_reboot(xen_session *session, xe /** + * 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/include/xen_vdi.h --- a/tools/libxen/include/xen_vdi.h Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/include/xen_vdi.h Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/include/xen_vm.h --- a/tools/libxen/include/xen_vm.h Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/include/xen_vm.h Sun Feb 04 12:24:53 2007 -0700 @@ -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_sessio /** - * Get the HVM/boot field of the given VM. - */ -extern bool -xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm); + * Get the HVM/boot_policy field of the given VM. + */ +extern bool +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_sessio /** - * Set the HVM/boot field of the given VM. - */ -extern bool -xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot); + * 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_remove_from_hvm_boot_params(xen_session *session, xen_vm vm, char *key); /** diff -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/include/xen_vm_power_state.h --- a/tools/libxen/include/xen_vm_power_state.h Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/include/xen_vm_power_state.h Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/src/xen_common.c --- a/tools/libxen/src/xen_common.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/src/xen_common.c Sun Feb 04 12:24:53 2007 -0700 @@ -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 @@ add_param_struct(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 @@ -106,6 +108,9 @@ parse_structmap_value(xen_session *, xml void *); static size_t size_of_member(const abstract_type *); + +static const char * +get_val_as_string(const struct abstract_type *, void *, char *); void @@ -1174,37 +1179,12 @@ add_struct_value(const struct abstract_t 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: - { - int64_t val = *(int64_t *)value; - snprintf(buf, sizeof(buf), "%"PRId64, val); - adder(node, key, "string", buf); + case ENUM: + { + const char *val_as_string = get_val_as_string(type, value, buf); + adder(node, key, "string", val_as_string); } break; @@ -1220,13 +1200,6 @@ add_struct_value(const struct abstract_t { bool val = *(bool *)value; adder(node, key, "boolean", val ? "1" : "0"); - } - break; - - case ENUM: - { - int val = *(int *)value; - adder(node, key, "string", type->enum_marshaller(val)); } break; @@ -1251,12 +1224,95 @@ add_struct_value(const struct abstract_t 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, c 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/src/xen_host.c --- a/tools/libxen/src/xen_host.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/src/xen_host.c Sun Feb 04 12:24:53 2007 -0700 @@ -632,6 +632,23 @@ xen_host_reboot(xen_session *session, xe 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/src/xen_int_float_map.c --- a/tools/libxen/src/xen_int_float_map.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/src/xen_int_float_map.c Sun Feb 04 12:24:53 2007 -0700 @@ -25,8 +25,10 @@ xen_int_float_map * 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/src/xen_string_string_map.c --- a/tools/libxen/src/xen_string_string_map.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/src/xen_string_string_map.c Sun Feb 04 12:24:53 2007 -0700 @@ -25,8 +25,10 @@ xen_string_string_map * 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/src/xen_vdi.c --- a/tools/libxen/src/xen_vdi.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/src/xen_vdi.c Sun Feb 04 12:24:53 2007 -0700 @@ -67,6 +67,9 @@ static const struct_member xen_vdi_recor { .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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/src/xen_vm.c --- a/tools/libxen/src/xen_vm.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/src/xen_vm.c Sun Feb 04 12:24:53 2007 -0700 @@ -145,9 +145,12 @@ static const struct_member xen_vm_record { .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_sessio 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 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_sessio bool -xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = vm }, - { .type = &abstract_type_string, - .u.string_val = boot } - }; - - xen_call_(session, "VM.set_HVM_boot", param_values, 2, NULL, NULL); +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_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.remove_from_HVM_boot_params", param_values, 2, NULL, NULL); return session->ok; } diff -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/src/xen_vm_power_state.c --- a/tools/libxen/src/xen_vm_power_state.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/src/xen_vm_power_state.c Sun Feb 04 12:24:53 2007 -0700 @@ -32,7 +32,6 @@ static const char *lookup_table[] = "Paused", "Running", "Suspended", - "ShuttingDown", "Unknown" }; diff -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/test/test_bindings.c --- a/tools/libxen/test/test_bindings.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/libxen/test/test_bindings.c Sun Feb 04 12:24:53 2007 -0700 @@ -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 "); @@ -221,6 +236,8 @@ int main(int argc, char **argv) printf("%s -> %s.\n", versions->contents[i].key, versions->contents[i].val); } + + printf("Host dmesg follows:\n%s\n\n", dmesg); printf("%s.\n", vm_record->uuid); @@ -243,9 +260,10 @@ int main(int argc, char **argv) xen_host_free(host); xen_string_string_map_free(versions); - - - xen_vm new_vm = create_new_vm(session); + free(dmesg); + + + 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,17 +327,17 @@ static xen_vm create_new_vm(xen_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) { @@ -368,7 +401,8 @@ static xen_vm create_new_vm(xen_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; @@ -381,15 +415,40 @@ static xen_vm create_new_vm(xen_session xen_sr_set_free(srs); xen_vm_free(vm); 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 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 -r 976dd90c2fdb -r fbc128aafdeb tools/libxen/test/test_hvm_bindings.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxen/test/test_hvm_bindings.c Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/misc/Makefile --- a/tools/misc/Makefile Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/misc/Makefile Sun Feb 04 12:24:53 2007 -0700 @@ -12,7 +12,7 @@ TARGETS = xenperf xc_shadow 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 -r 976dd90c2fdb -r fbc128aafdeb tools/misc/xen-python-path --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/misc/xen-python-path Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/misc/xend --- a/tools/misc/xend Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/misc/xend Sun Feb 04 12:24:53 2007 -0700 @@ -31,23 +31,13 @@ import time 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 -r 976dd90c2fdb -r fbc128aafdeb tools/pygrub/src/pygrub --- a/tools/pygrub/src/pygrub Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/pygrub/src/pygrub Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/scripts/test_hvm_create.py --- a/tools/python/scripts/test_hvm_create.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/scripts/test_hvm_create.py Sun Feb 04 12:24:53 2007 -0700 @@ -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 @@ local_vdi_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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/scripts/test_vm_create.py --- a/tools/python/scripts/test_vm_create.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/scripts/test_vm_create.py Sun Feb 04 12:24:53 2007 -0700 @@ -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 @@ local_vdi_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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/xen/xend/XendAPI.py Sun Feb 04 12:24:53 2007 -0700 @@ -22,7 +22,7 @@ import traceback 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)')] @@ -673,6 +674,9 @@ class XendAPI(object): if not XendDomain.instance().allow_new_domains(): 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() @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/xen/xend/XendAPIConstants.py --- a/tools/python/xen/xend/XendAPIConstants.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/xen/xend/XendAPIConstants.py Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/xen/xend/XendBootloader.py --- a/tools/python/xen/xend/XendBootloader.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/xen/xend/XendBootloader.py Sun Feb 04 12:24:53 2007 -0700 @@ -97,7 +97,9 @@ def bootloader(blexec, disk, dom, quiet 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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/xen/xend/XendConfig.py Sun Feb 04 12:24:53 2007 -0700 @@ -28,7 +28,7 @@ from xen.xend.XendConstants import DOM_S 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'] @@ -495,6 +497,12 @@ class XendConfig(dict): except (TypeError, ValueError), e: 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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/xen/xend/XendDomainInfo.py Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/xen/xend/XendVDI.py --- a/tools/python/xen/xend/XendVDI.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/xen/xend/XendVDI.py Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/xen/xend/image.py Sun Feb 04 12:24:53 2007 -0700 @@ -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: + 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('-nographic') - return ret - - - 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) return ret diff -r 976dd90c2fdb -r fbc128aafdeb tools/python/xen/xend/server/vfbif.py --- a/tools/python/xen/xend/server/vfbif.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/xen/xend/server/vfbif.py Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/python/xen/xm/messages/en/xen-xm.po --- a/tools/python/xen/xm/messages/en/xen-xm.po Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/python/xen/xm/messages/en/xen-xm.po Sun Feb 04 12:24:53 2007 -0700 @@ -19,7 +19,7 @@ msgid "" 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@xxxxxxxxxxxxx>\n" "Language-Team: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>\n" "MIME-Version: 1.0\n" @@ -40,6 +40,9 @@ msgstr "The method %(1)s takes %(2)s arg 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 -r 976dd90c2fdb -r fbc128aafdeb tools/xcutils/readnotes.c --- a/tools/xcutils/readnotes.c Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/xcutils/readnotes.c Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/xm-test/configure.ac --- a/tools/xm-test/configure.ac Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/xm-test/configure.ac Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb tools/xm-test/lib/XmTestLib/XenDomain.py --- a/tools/xm-test/lib/XmTestLib/XenDomain.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/xm-test/lib/XmTestLib/XenDomain.py Sun Feb 04 12:24:53 2007 -0700 @@ -31,6 +31,9 @@ from XenDevice import * from XenDevice import * from DomainTracking import * from acm import * + + +DOM0_UUID = "00000000-0000-0000-0000-000000000000" def getDefaultKernel(): diff -r 976dd90c2fdb -r fbc128aafdeb tools/xm-test/lib/XmTestLib/__init__.py --- a/tools/xm-test/lib/XmTestLib/__init__.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/xm-test/lib/XmTestLib/__init__.py Sun Feb 04 12:24:53 2007 -0700 @@ -2,26 +2,6 @@ # Copyright (C) International Business Machines Corp., 2005 # Author: Dan Smith <danms@xxxxxxxxxx> # - -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 * diff -r 976dd90c2fdb -r fbc128aafdeb tools/xm-test/tests/vtpm/09_vtpm-xapi.py --- a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py Sun Feb 04 12:18:48 2007 -0700 +++ b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py Sun Feb 04 12:24:53 2007 -0700 @@ -13,7 +13,6 @@ from XmTestLib import xapi 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 @@ vm_uuid = domain.get_uuid() vm_uuid = domain.get_uuid() vtpmcfg = {} -vtpmcfg['backend'] = XendDomain.DOM0_UUID +vtpmcfg['backend'] = DOM0_UUID vtpmcfg['VM'] = vm_uuid session = xapi.connect() diff -r 976dd90c2fdb -r fbc128aafdeb xen/arch/x86/dmi_scan.c --- a/xen/arch/x86/dmi_scan.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/arch/x86/dmi_scan.c Sun Feb 04 12:24:53 2007 -0700 @@ -159,7 +159,7 @@ static void __init dmi_save_ident(struct 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 -r 976dd90c2fdb -r fbc128aafdeb xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/arch/x86/domctl.c Sun Feb 04 12:24:53 2007 -0700 @@ -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); - - xfree(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; + + 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 = -ENOMEM; + if ( (c.data = xmalloc_bytes(c.size)) == NULL ) + goto gethvmcontext_out; + + ret = hvm_save(d, &c); + + if ( copy_to_guest(domctl->u.hvmcontext.buffer, c.data, c.size) != 0 ) ret = -EFAULT; - - if ( copy_to_guest(domctl->u.hvmcontext.ctxt, c, 1) ) - ret = -EFAULT; - - xfree(c); 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 -r 976dd90c2fdb -r fbc128aafdeb xen/arch/x86/hvm/hpet.c --- a/xen/arch/x86/hvm/hpet.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/arch/x86/hvm/hpet.c Sun Feb 04 12:24:53 2007 -0700 @@ -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]; - } - set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, h->period[tn])); + h->hpet.timers[tn].cmp += h->hpet.period[tn]; + } + set_timer(&h->timers[tn], + NOW() + hpet_tick_to_ns(h, h->hpet.period[tn])); } } @@ -377,6 +378,35 @@ void hpet_migrate_timers(struct vcpu *v) for ( i = 0; i < HPET_TIMER_NUM; i++ ) 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) { diff -r 976dd90c2fdb -r fbc128aafdeb xen/arch/x86/hvm/intercept.c --- a/xen/arch/x86/hvm/intercept.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/arch/x86/hvm/intercept.c Sun Feb 04 12:24:53 2007 -0700 @@ -205,7 +205,7 @@ int hvm_save(struct domain *d, hvm_domai 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_domai { 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_domai { /* 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 -r 976dd90c2fdb -r fbc128aafdeb xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/arch/x86/hvm/svm/svm.c Sun Feb 04 12:24:53 2007 -0700 @@ -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, case 8: vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4)); + vmcb->vintr.fields.tpr = value & 0x0F; break; default: diff -r 976dd90c2fdb -r fbc128aafdeb xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/arch/x86/hvm/vlapic.c Sun Feb 04 12:24:53 2007 -0700 @@ -593,6 +593,7 @@ static void vlapic_write(struct vcpu *v, { case APIC_TASKPRI: vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff); + hvm_update_vtpr(v, (val >> 4) & 0x0f); break; case APIC_EOI: diff -r 976dd90c2fdb -r fbc128aafdeb xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/arch/x86/hvm/vmx/vmx.c Sun Feb 04 12:24:53 2007 -0700 @@ -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) { @@ -1010,6 +1015,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 -r 976dd90c2fdb -r fbc128aafdeb xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/arch/x86/traps.c Sun Feb 04 12:24:53 2007 -0700 @@ -596,6 +596,11 @@ static int emulate_forced_invalid_op(str clear_bit(X86_FEATURE_SEP, &d); 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 { diff -r 976dd90c2fdb -r fbc128aafdeb xen/arch/x86/x86_64/compat/entry.S --- a/xen/arch/x86/x86_64/compat/entry.S Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/arch/x86/x86_64/compat/entry.S Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb xen/common/kexec.c --- a/xen/common/kexec.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/common/kexec.c Sun Feb 04 12:24:53 2007 -0700 @@ -131,10 +131,18 @@ __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 @@ -155,23 +163,24 @@ static int kexec_get(xen)(xen_kexec_rang 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 -r 976dd90c2fdb -r fbc128aafdeb xen/common/perfc.c --- a/xen/common/perfc.c Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/common/perfc.c Sun Feb 04 12:24:53 2007 -0700 @@ -136,8 +136,8 @@ static xen_sysctl_perfc_val_t *perfc_val 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 @@ int perfc_control(xen_sysctl_perfc_op_t 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 -r 976dd90c2fdb -r fbc128aafdeb xen/include/asm-x86/cpufeature.h --- a/xen/include/asm-x86/cpufeature.h Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/asm-x86/cpufeature.h Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb xen/include/asm-x86/hvm/domain.h --- a/xen/include/asm-x86/hvm/domain.h Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/asm-x86/hvm/domain.h Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/asm-x86/hvm/hvm.h Sun Feb 04 12:24:53 2007 -0700 @@ -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 @@ -201,6 +206,12 @@ hvm_update_host_cr3(struct vcpu *v) 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); diff -r 976dd90c2fdb -r fbc128aafdeb xen/include/asm-x86/hvm/support.h --- a/xen/include/asm-x86/hvm/support.h Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/asm-x86/hvm/support.h Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb xen/include/asm-x86/hvm/vpt.h --- a/xen/include/asm-x86/hvm/vpt.h Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/asm-x86/hvm/vpt.h Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb xen/include/public/arch-x86/xen-x86_32.h --- a/xen/include/public/arch-x86/xen-x86_32.h Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/public/arch-x86/xen-x86_32.h Sun Feb 04 12:24:53 2007 -0700 @@ -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 -r 976dd90c2fdb -r fbc128aafdeb xen/include/public/domctl.h --- a/xen/include/public/domctl.h Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/public/domctl.h Sun Feb 04 12:24:53 2007 -0700 @@ -386,18 +386,11 @@ typedef 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 -r 976dd90c2fdb -r fbc128aafdeb xen/include/public/foreign/Makefile --- a/xen/include/public/foreign/Makefile Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/public/foreign/Makefile Sun Feb 04 12:24:53 2007 -0700 @@ -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 @@ ia64.h: ../arch-ia64.h ../xen.h $(script 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 -r 976dd90c2fdb -r fbc128aafdeb xen/include/public/hvm/save.h --- a/xen/include/public/hvm/save.h Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/public/hvm/save.h Sun Feb 04 12:24:53 2007 -0700 @@ -381,10 +381,40 @@ DECLARE_HVM_SAVE_TYPE(RTC, 9, struct hvm 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 -r 976dd90c2fdb -r fbc128aafdeb xen/include/xen/string.h --- a/xen/include/xen/string.h Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/include/xen/string.h Sun Feb 04 12:24:53 2007 -0700 @@ -82,8 +82,16 @@ extern void * memchr(const void *,int,__ } #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 -r 976dd90c2fdb -r fbc128aafdeb xen/tools/get-fields.sh --- a/xen/tools/get-fields.sh Sun Feb 04 12:18:48 2007 -0700 +++ b/xen/tools/get-fields.sh Sun Feb 04 12:24:53 2007 -0700 @@ -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 "" } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |