Brendan Cully
2007-Feb-26 01:36 UTC
[Xen-devel] [PATCH 0 of 2] Parse image elfnotes, write them to xenstore, save and load via image sxpr
Here are two patches that let xm create, save and restore extract and preserve elfnotes read by the domain builder. This is handy for a few things. In particular, I''d like it so that xm can decide whether or not guest domains support fast resume (if save fails, or for checkpointing). _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Brendan Cully
2007-Feb-26 01:36 UTC
[Xen-devel] [PATCH 1 of 2] Write Xen ELF notes into xenstore on domain build
# HG changeset patch # User Brendan Cully <brendan@cs.ubc.ca> # Date 1172453755 28800 # Node ID ea6d1ab3d87507e414bd226fcbf768bf47cffe48 # Parent 2c3a13993b0d1c6b374e96c5a365fe615dca2f72 Write Xen ELF notes into xenstore on domain build. This information is plumbed through save and restore in a subsequent patch. Signed-off-by: Brendan Cully <brendan@cs.ubc.ca> diff -r 2c3a13993b0d -r ea6d1ab3d875 tools/libxc/xc_dom_compat_linux.c --- a/tools/libxc/xc_dom_compat_linux.c Fri Feb 23 14:44:07 2007 +0000 +++ b/tools/libxc/xc_dom_compat_linux.c Sun Feb 25 17:35:55 2007 -0800 @@ -122,3 +122,30 @@ int xc_linux_build(int xc_handle, uint32 xc_dom_release(dom); return rc; } + +int xc_dom_linux_build(int xc_handle, + struct xc_dom_image *dom, + uint32_t domid, + unsigned int mem_mb, + const char *image_name, + const char *initrd_name, + unsigned long flags, + unsigned int store_evtchn, + unsigned long *store_mfn, + unsigned int console_evtchn, unsigned long *console_mfn) +{ + int rc; + + if (0 != (rc = xc_dom_kernel_file(dom, image_name))) + return rc; + if (initrd_name && strlen(initrd_name)) + if (0 != (rc = xc_dom_ramdisk_file(dom, initrd_name))) + return rc; + + rc = xc_linux_build_internal(dom, xc_handle, domid, + mem_mb, flags, + store_evtchn, store_mfn, + console_evtchn, console_mfn); + + return rc; +} diff -r 2c3a13993b0d -r ea6d1ab3d875 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Fri Feb 23 14:44:07 2007 +0000 +++ b/tools/libxc/xenguest.h Sun Feb 25 17:35:55 2007 -0800 @@ -91,6 +91,20 @@ int xc_linux_build(int xc_handle, unsigned int console_evtchn, unsigned long *console_mfn); +/** The same interface, but the dom structure is managed by the caller */ +struct xc_dom_image; +int xc_dom_linux_build(int xc_handle, + struct xc_dom_image *dom, + uint32_t domid, + unsigned int mem_mb, + const char *image_name, + const char *ramdisk_name, + unsigned long flags, + unsigned int store_evtchn, + unsigned long *store_mfn, + unsigned int console_evtchn, + unsigned long *console_mfn); + /** * This function will create a domain for a paravirtualized Linux * using buffers for kernel and initrd diff -r 2c3a13993b0d -r ea6d1ab3d875 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Fri Feb 23 14:44:07 2007 +0000 +++ b/tools/python/xen/lowlevel/xc/xc.c Sun Feb 25 17:35:55 2007 -0800 @@ -18,6 +18,8 @@ #include <arpa/inet.h> #include "xenctrl.h" +#include <xen/elfnote.h> +#include "xc_dom.h" #include <xen/hvm/hvm_info_table.h> #include <xen/hvm/params.h> @@ -371,13 +373,17 @@ static PyObject *pyxc_linux_build(XcObje PyObject *args, PyObject *kwds) { - uint32_t dom; + uint32_t domid; + struct xc_dom_image *dom; char *image, *ramdisk = NULL, *cmdline = "", *features = NULL; int flags = 0; int store_evtchn, console_evtchn; unsigned int mem_mb; unsigned long store_mfn = 0; unsigned long console_mfn = 0; + PyObject* elfnote_dict; + PyObject* elfnote = NULL; + int i; static char *kwd_list[] = { "domid", "store_evtchn", "memsize", "console_evtchn", "image", @@ -386,22 +392,52 @@ static PyObject *pyxc_linux_build(XcObje "features", NULL }; if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list, - &dom, &store_evtchn, &mem_mb, + &domid, &store_evtchn, &mem_mb, &console_evtchn, &image, /* optional */ &ramdisk, &cmdline, &flags, &features) ) return NULL; - if ( xc_linux_build(self->xc_handle, dom, mem_mb, image, - ramdisk, cmdline, features, flags, - store_evtchn, &store_mfn, - console_evtchn, &console_mfn) != 0 ) { - return pyxc_error_to_exception(); + xc_dom_loginit(); + if (!(dom = xc_dom_allocate(cmdline, features))) + return pyxc_error_to_exception(); + + if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image, + ramdisk, flags, store_evtchn, &store_mfn, + console_evtchn, &console_mfn) != 0 ) { + goto out; } - return Py_BuildValue("{s:i,s:i}", + + if (!(elfnote_dict = PyDict_New())) + goto out; + for (i = 0; i < XEN_ELFNOTE_MAX; i++) { + switch (dom->parms.elf_notes[i].type) { + case XEN_ENT_NONE: + continue; + case XEN_ENT_LONG: + elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num); + break; + case XEN_ENT_STR: + elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str); + break; + } + PyDict_SetItemString(elfnote_dict, + dom->parms.elf_notes[i].name, + elfnote); + Py_DECREF(elfnote); + } + + xc_dom_release(dom); + + return Py_BuildValue("{s:i,s:i,s:N}", "store_mfn", store_mfn, - "console_mfn", console_mfn); + "console_mfn", console_mfn, + "notes", elfnote_dict); + + out: + xc_dom_release(dom); + return pyxc_error_to_exception(); } static PyObject *pyxc_hvm_build(XcObject *self, diff -r 2c3a13993b0d -r ea6d1ab3d875 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Fri Feb 23 14:44:07 2007 +0000 +++ b/tools/python/xen/xend/XendDomainInfo.py Sun Feb 25 17:35:55 2007 -0800 @@ -302,6 +302,8 @@ class XendDomainInfo: @type store_mfn: int @ivar console_mfn: xenconsoled mfn @type console_mfn: int + @ivar notes: OS image notes + @type notes: dictionary @ivar vmWatch: reference to a watch on the xenstored vmpath @type vmWatch: xen.xend.xenstore.xswatch @ivar shutdownWatch: reference to watch on the xenstored domain shutdown @@ -354,6 +356,7 @@ class XendDomainInfo: self.store_mfn = None self.console_port = None self.console_mfn = None + self.notes = {} self.vmWatch = None self.shutdownWatch = None @@ -776,12 +779,28 @@ class XendDomainInfo: def f(n, v): if v is not None: - to_store[n] = str(v) + if type(v) == bool: + to_store[n] = v and "1" or "0" + else: + to_store[n] = str(v) f(''console/port'', self.console_port) f(''console/ring-ref'', self.console_mfn) f(''store/port'', self.store_port) f(''store/ring-ref'', self.store_mfn) + + # elfnotes + for n, v in self.notes.iteritems(): + n = n.lower().replace(''_'', ''-'') + if n == ''features'': + for v in v.split(''|''): + v = v.replace(''_'', ''-'') + if v.startswith(''!''): + f(''image/%s/%s'' % (n, v[1:]), False) + else: + f(''image/%s/%s'' % (n, v), True) + else: + f(''image/%s'' % n, v) to_store.update(self._vcpuDomDetails()) @@ -1462,6 +1481,8 @@ class XendDomainInfo: self.store_mfn = channel_details[''store_mfn''] if ''console_mfn'' in channel_details: self.console_mfn = channel_details[''console_mfn''] + if ''notes'' in channel_details: + self.notes = channel_details[''notes''] self._introduceDomain() diff -r 2c3a13993b0d -r ea6d1ab3d875 xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Fri Feb 23 14:44:07 2007 +0000 +++ b/xen/arch/x86/domain_build.c Sun Feb 25 17:35:55 2007 -0800 @@ -28,6 +28,7 @@ #include <asm/paging.h> #include <public/version.h> +#include <public/elfnote.h> #include <public/libelf.h> extern unsigned long initial_images_nrpages(void); diff -r 2c3a13993b0d -r ea6d1ab3d875 xen/common/libelf/libelf-dominfo.c --- a/xen/common/libelf/libelf-dominfo.c Fri Feb 23 14:44:07 2007 +0000 +++ b/xen/common/libelf/libelf-dominfo.c Sun Feb 25 17:35:55 2007 -0800 @@ -119,13 +119,18 @@ int elf_xen_parse_note(struct elf_binary str = elf_note_desc(elf, note); elf_msg(elf, "%s: %s = \"%s\"\n", __FUNCTION__, note_desc[type].name, str); + parms->elf_notes[type].type = XEN_ENT_STR; + parms->elf_notes[type].data.str = str; } else { val = elf_note_numeric(elf, note); elf_msg(elf, "%s: %s = 0x%" PRIx64 "\n", __FUNCTION__, note_desc[type].name, val); - } + parms->elf_notes[type].type = XEN_ENT_LONG; + parms->elf_notes[type].data.num = val; + } + parms->elf_notes[type].name = note_desc[type].name; switch ( type ) { diff -r 2c3a13993b0d -r ea6d1ab3d875 xen/include/public/elfnote.h --- a/xen/include/public/elfnote.h Fri Feb 23 14:44:07 2007 +0000 +++ b/xen/include/public/elfnote.h Sun Feb 25 17:35:55 2007 -0800 @@ -157,6 +157,11 @@ #define XEN_ELFNOTE_L1_MFN_VALID 13 /* + * The number of the highest elfnote defined. + */ +#define XEN_ELFNOTE_MAX XEN_ELFNOTE_L1_MFN_VALID + +/* * System information exported through crash notes. * * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_INFO diff -r 2c3a13993b0d -r ea6d1ab3d875 xen/include/public/libelf.h --- a/xen/include/public/libelf.h Fri Feb 23 14:44:07 2007 +0000 +++ b/xen/include/public/libelf.h Sun Feb 25 17:35:55 2007 -0800 @@ -174,12 +174,28 @@ int elf_reloc(struct elf_binary *elf); #define UNSET_ADDR ((uint64_t)-1) +enum xen_elfnote_type { + XEN_ENT_NONE = 0, + XEN_ENT_LONG = 1, + XEN_ENT_STR = 2 +}; + +struct xen_elfnote { + enum xen_elfnote_type type; + const char *name; + union { + const char *str; + uint64_t num; + } data; +}; + struct elf_dom_parms { /* raw */ const char *guest_info; const void *elf_note_start; const void *elf_note_end; - + struct xen_elfnote elf_notes[XEN_ELFNOTE_MAX + 1]; + /* parsed */ char guest_os[16]; char guest_ver[16]; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Brendan Cully
2007-Feb-26 01:36 UTC
[Xen-devel] [PATCH 2 of 2] Save elfnotes in VM sxpr under image/notes, and load them on restore
# HG changeset patch # User Brendan Cully <brendan@cs.ubc.ca> # Date 1172453755 28800 # Node ID 0942ae7ee6bd4f071e9a60a1a7aa75a03f9bb9b7 # Parent ea6d1ab3d87507e414bd226fcbf768bf47cffe48 Save elfnotes in VM sxpr under image/notes, and load them on restore. Signed-off-by: Brendan Cully <brendan@cs.ubc.ca> diff -r ea6d1ab3d875 -r 0942ae7ee6bd tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Sun Feb 25 17:35:55 2007 -0800 +++ b/tools/python/xen/xend/XendConfig.py Sun Feb 25 17:35:55 2007 -0800 @@ -729,6 +729,10 @@ class XendConfig(dict): image[''hvm''] = image_hvm image[''hvm''][''devices''] = image_hvm_devices + notes = sxp.children(image_sxp, ''notes'') + if notes: + image[''notes''] = self.notes_from_sxp(notes[0]) + self[''image''] = image for apikey, imgkey in XENAPI_HVM_CFG.items(): @@ -1363,6 +1367,9 @@ class XendConfig(dict): image.append([arg, val]) + if ''notes'' in self[''image'']: + image.append(self.notes_sxp(self[''image''][''notes''])) + return image def update_with_image_sxp(self, image_sxp, bootloader = False): @@ -1420,6 +1427,10 @@ class XendConfig(dict): image[''hvm''] = image_hvm image[''hvm''][''devices''] = image_hvm_devices + notes = sxp.children(image_sxp, ''notes'') + if notes: + image[''notes''] = self.notes_from_sxp(notes[0]) + self[''image''] = image for apikey, imgkey in XENAPI_HVM_CFG.items(): @@ -1432,7 +1443,28 @@ class XendConfig(dict): self[apikey] = val self._hvm_boot_params_from_sxp(image_sxp) - + def set_notes(self, notes): + ''Add parsed elfnotes to image'' + self[''image''][''notes''] = notes + + def get_notes(self): + try: + return self[''image''][''notes''] or {} + except KeyError: + return {} + + def notes_from_sxp(self, nsxp): + notes = {} + for note in sxp.children(nsxp): + notes[note[0]] = note[1] + return notes + + def notes_sxp(self, notes): + nsxp = [''notes''] + for k, v in notes.iteritems(): + nsxp.append([k, str(v)]) + return nsxp + def _hvm_boot_params_from_sxp(self, image_sxp): boot = sxp.child_value(image_sxp, ''boot'', None) if boot is not None: diff -r ea6d1ab3d875 -r 0942ae7ee6bd tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Sun Feb 25 17:35:55 2007 -0800 +++ b/tools/python/xen/xend/XendDomainInfo.py Sun Feb 25 17:35:55 2007 -0800 @@ -356,7 +356,6 @@ class XendDomainInfo: self.store_mfn = None self.console_port = None self.console_mfn = None - self.notes = {} self.vmWatch = None self.shutdownWatch = None @@ -790,7 +789,7 @@ class XendDomainInfo: f(''store/ring-ref'', self.store_mfn) # elfnotes - for n, v in self.notes.iteritems(): + for n, v in self.info.get_notes().iteritems(): n = n.lower().replace(''_'', ''-'') if n == ''features'': for v in v.split(''|''): @@ -1482,7 +1481,7 @@ class XendDomainInfo: if ''console_mfn'' in channel_details: self.console_mfn = channel_details[''console_mfn''] if ''notes'' in channel_details: - self.notes = channel_details[''notes''] + self.info.set_notes(channel_details[''notes'']) self._introduceDomain() _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Apparently Analagous Threads
- Two problems with DomU reboot (cmdline, duplicate domains)
- [PATCH 0 of 3] Support for VM generation ID save/restore and migrate
- [PATCH 0 of 2] Support for VM generation ID save/restore and migrate
- [PATCH] xenguest: Add xsa-25 decompression limit prototypes
- [PATCH 0 of 4] Support for VM generation ID save/restore and migrate