[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] save restore: frame work
# HG changeset patch # User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx> # Date 1169138883 0 # Node ID 1e590ddb127789cfde6ed29eef0127b79bfff2a8 # Parent d64601b977b03e0752792396706255e805d87fdc [HVM] save restore: frame work Signed-off-by: Zhai Edwin <edwin.zhai@xxxxxxxxx> frame work for HVM save restore in Control Panel --- tools/libxc/Makefile | 2 tools/libxc/xc_hvm_restore.c | 42 +++++++++++++++ tools/libxc/xc_hvm_save.c | 40 ++++++++++++++ tools/libxc/xenguest.h | 20 +++++++ tools/python/xen/lowlevel/xc/xc.c | 22 ++++++++ tools/python/xen/xend/XendCheckpoint.py | 87 +++++++++++++++++++++++++++++--- tools/python/xen/xend/XendDomainInfo.py | 26 +++++++++ tools/python/xen/xend/image.py | 14 +++-- tools/xcutils/xc_restore.c | 19 +++++- tools/xcutils/xc_save.c | 5 + 10 files changed, 260 insertions(+), 17 deletions(-) diff -r d64601b977b0 -r 1e590ddb1277 tools/libxc/Makefile --- a/tools/libxc/Makefile Thu Jan 18 16:21:08 2007 +0000 +++ b/tools/libxc/Makefile Thu Jan 18 16:48:03 2007 +0000 @@ -27,7 +27,7 @@ GUEST_SRCS-$(CONFIG_X86) += xc_linux_bui GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c -GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c +GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c xc_hvm_restore.c xc_hvm_save.c -include $(XEN_TARGET_ARCH)/Makefile diff -r d64601b977b0 -r 1e590ddb1277 tools/libxc/xc_hvm_restore.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/xc_hvm_restore.c Thu Jan 18 16:48:03 2007 +0000 @@ -0,0 +1,42 @@ +/****************************************************************************** + * xc_hvm_restore.c + * + * Restore the state of a HVM guest. + * + * Copyright (c) 2003, K A Fraser. + * Copyright (c) 2006 Intel Corperation + * rewriten for hvm guest by Zhai Edwin <edwin.zhai@xxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +#include <stdlib.h> +#include <unistd.h> + +#include "xg_private.h" +#include "xg_save_restore.h" + +#include <xen/hvm/ioreq.h> +#include <xen/hvm/params.h> +#include <xen/hvm/e820.h> + +int xc_hvm_restore(int xc_handle, int io_fd, + uint32_t dom, unsigned long nr_pfns, + unsigned int store_evtchn, unsigned long *store_mfn, + unsigned int console_evtchn, unsigned long *console_mfn, + unsigned int pae, unsigned int apic) +{ + return 0; +} diff -r d64601b977b0 -r 1e590ddb1277 tools/libxc/xc_hvm_save.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/xc_hvm_save.c Thu Jan 18 16:48:03 2007 +0000 @@ -0,0 +1,40 @@ +/****************************************************************************** + * xc_hvm_save.c + * + * Save the state of a running HVM guest. + * + * Copyright (c) 2003, K A Fraser. + * Copyright (c) 2006 Intel Corperation + * rewriten for hvm guest by Zhai Edwin <edwin.zhai@xxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +#include <inttypes.h> +#include <time.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/time.h> + +#include "xc_private.h" +#include "xg_private.h" +#include "xg_save_restore.h" + +int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, + uint32_t max_factor, uint32_t flags, int (*suspend)(int)) +{ + + return 0; +} diff -r d64601b977b0 -r 1e590ddb1277 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Thu Jan 18 16:21:08 2007 +0000 +++ b/tools/libxc/xenguest.h Thu Jan 18 16:48:03 2007 +0000 @@ -11,6 +11,7 @@ #define XCFLAGS_LIVE 1 #define XCFLAGS_DEBUG 2 +#define XCFLAGS_HVM 4 /** @@ -25,6 +26,13 @@ int xc_linux_save(int xc_handle, int io_ uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */, int (*suspend)(int domid)); +/** + * This function will save a hvm domain running unmodified guest. + * @return 0 on success, -1 on failure + */ +int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, + uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */, + int (*suspend)(int domid)); /** * This function will restore a saved domain running Linux. @@ -41,6 +49,18 @@ int xc_linux_restore(int xc_handle, int unsigned long nr_pfns, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn); + +/** + * This function will restore a saved hvm domain running unmodified guest. + * + * @parm store_mfn pass mem size & returned with the mfn of the store page + * @return 0 on success, -1 on failure + */ +int xc_hvm_restore(int xc_handle, int io_fd, uint32_t dom, + unsigned long nr_pfns, unsigned int store_evtchn, + unsigned long *store_mfn, unsigned int console_evtchn, + unsigned long *console_mfn, + unsigned int pae, unsigned int apic); /** * This function will create a domain for a paravirtualized Linux diff -r d64601b977b0 -r 1e590ddb1277 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Thu Jan 18 16:21:08 2007 +0000 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu Jan 18 16:48:03 2007 +0000 @@ -158,6 +158,20 @@ static PyObject *pyxc_domain_destroy(XcO static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args) { return dom_op(self, args, xc_domain_destroy); +} + +static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args) +{ + uint32_t dom, reason; + + if (!PyArg_ParseTuple(args, "ii", &dom, &reason)) + return NULL; + + if (xc_domain_shutdown(self->xc_handle, dom, reason) != 0) + return pyxc_error_to_exception(); + + Py_INCREF(zero); + return zero; } @@ -1027,6 +1041,14 @@ static PyMethodDef pyxc_methods[] = { METH_VARARGS, "\n" "Destroy a domain.\n" " dom [int]: Identifier of domain to be destroyed.\n\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + + { "domain_shutdown", + (PyCFunction)pyxc_domain_shutdown, + METH_VARARGS, "\n" + "Shutdown a domain.\n" + " dom [int, 0]: Domain identifier to use.\n" + " reason [int, 0]: Reason for shutdown.\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "vcpu_setaffinity", diff -r d64601b977b0 -r 1e590ddb1277 tools/python/xen/xend/XendCheckpoint.py --- a/tools/python/xen/xend/XendCheckpoint.py Thu Jan 18 16:21:08 2007 +0000 +++ b/tools/python/xen/xend/XendCheckpoint.py Thu Jan 18 16:48:03 2007 +0000 @@ -22,11 +22,14 @@ from xen.xend.XendConstants import * from xen.xend.XendConstants import * SIGNATURE = "LinuxGuestRecord" +QEMU_SIGNATURE = "QemuDeviceModelRecord" +dm_batch = 512 XC_SAVE = "xc_save" XC_RESTORE = "xc_restore" sizeof_int = calcsize("i") +sizeof_unsigned_int = calcsize("I") sizeof_unsigned_long = calcsize("L") @@ -69,6 +72,11 @@ def save(fd, dominfo, network, live, dst "could not write guest state file: config len") write_exact(fd, config, "could not write guest state file: config") + image_cfg = dominfo.info.get('image', {}) + hvm = image_cfg.has_key('hvm') + + if hvm: + log.info("save hvm domain") # xc_save takes three customization parameters: maxit, max_f, and # flags the last controls whether or not save is 'live', while the # first two further customize behaviour when 'live' save is @@ -76,7 +84,7 @@ def save(fd, dominfo, network, live, dst # libxenguest; see the comments and/or code in xc_linux_save() for # more information. cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd), - str(dominfo.getDomid()), "0", "0", str(int(live)) ] + str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ] log.debug("[xc_save]: %s", string.join(cmd)) def saveInputHandler(line, tochild): @@ -90,11 +98,28 @@ def save(fd, dominfo, network, live, dst log.info("Domain %d suspended.", dominfo.getDomid()) dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP3, domain_name) + #send signal to device model for save + if hvm: + log.info("release_devices for hvm domain") + dominfo._releaseDevices(True) tochild.write("done\n") tochild.flush() log.debug('Written done') forkHelper(cmd, fd, saveInputHandler, False) + + # put qemu device model state + if hvm: + write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature") + qemu_fd = os.open("/tmp/xen.qemu-dm.%d" % dominfo.getDomid(), os.O_RDONLY) + while True: + buf = os.read(qemu_fd, dm_batch) + if len(buf): + write_exact(fd, buf, "could not write device model state") + else: + break + os.close(qemu_fd) + os.remove("/tmp/xen.qemu-dm.%d" % dominfo.getDomid()) dominfo.destroyDomain() try: @@ -149,19 +174,49 @@ def restore(xd, fd, dominfo = None, paus nr_pfns = (dominfo.getMemoryTarget() + 3) / 4 + # if hvm, pass mem size to calculate the store_mfn + hvm = 0 + apic = 0 + pae = 0 + image_cfg = dominfo.info.get('image', {}) + hvm = image_cfg.has_key('hvm') + if hvm: + # the 'memory' in config has been removed + hvm = dominfo.info['memory_static_min'] + apic = dominfo.info['image']['hvm'].get('apic', 0) + pae = dominfo.info['image']['hvm'].get('pae', 0) + log.info("restore hvm domain %d, mem=%d, apic=%d, pae=%d", + dominfo.domid, hvm, apic, pae) + try: - l = read_exact(fd, sizeof_unsigned_long, - "not a valid guest state file: pfn count read") + if hvm: + l = read_exact(fd, sizeof_unsigned_int, + "not a valid hvm guest state file: pfn count read") + nr_pfns = unpack("I", l)[0] # native sizeof int + else: + l = read_exact(fd, sizeof_unsigned_long, + "not a valid guest state file: pfn count read") + max_pfn = unpack("L", l)[0] # native sizeof long if max_pfn > 16*1024*1024: # XXX raise XendError( "not a valid guest state file: pfn count out of range") - balloon.free(xc.pages_to_kib(nr_pfns)) + shadow = dominfo.info['shadow_memory'] + log.debug("restore:shadow=0x%x, _static_max=0x%x, _static_min=0x%x, " + "nr_pfns=0x%x.", dominfo.info['shadow_memory'], + dominfo.info['memory_static_max'], + dominfo.info['memory_static_min'], nr_pfns) + + + balloon.free(xc.pages_to_kib(nr_pfns) + shadow * 1024) + + shadow_cur = xc.shadow_mem_control(dominfo.getDomid(), shadow) + dominfo.info['shadow_memory'] = shadow_cur cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE), fd, dominfo.getDomid(), max_pfn, - store_port, console_port]) + store_port, console_port, hvm, pae, apic]) log.debug("[xc_restore]: %s", string.join(cmd)) handler = RestoreInputHandler() @@ -171,10 +226,30 @@ def restore(xd, fd, dominfo = None, paus if handler.store_mfn is None or handler.console_mfn is None: raise XendError('Could not read store/console MFN') - os.read(fd, 1) # Wait for source to close connection dominfo.waitForDevices() # Wait for backends to set up if not paused: dominfo.unpause() + + # get qemu state and create a tmp file for dm restore + if hvm: + qemu_signature = read_exact(fd, len(QEMU_SIGNATURE), + "invalid device model signature read") + if qemu_signature != QEMU_SIGNATURE: + raise XendError("not a valid device model state: found '%s'" % + qemu_signature) + qemu_fd = os.open("/tmp/xen.qemu-dm.%d" % dominfo.getDomid(), + os.O_WRONLY | os.O_CREAT | os.O_TRUNC) + while True: + buf = os.read(fd, dm_batch) + if len(buf): + write_exact(qemu_fd, buf, + "could not write dm state to tmp file") + else: + break + os.close(qemu_fd) + + + os.read(fd, 1) # Wait for source to close connection dominfo.completeRestore(handler.store_mfn, handler.console_mfn) diff -r d64601b977b0 -r 1e590ddb1277 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu Jan 18 16:21:08 2007 +0000 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu Jan 18 16:48:03 2007 +0000 @@ -451,6 +451,16 @@ class XendDomainInfo: self._removeVm('xend/previous_restart_time') self.storeDom("control/shutdown", reason) + ## shutdown hypercall for hvm domain desides xenstore write + image_cfg = self.info.get('image', {}) + hvm = image_cfg.has_key('hvm') + if hvm: + for code in DOMAIN_SHUTDOWN_REASONS.keys(): + if DOMAIN_SHUTDOWN_REASONS[code] == reason: + break + xc.domain_shutdown(self.domid, code) + + def pause(self): """Pause domain @@ -1228,8 +1238,11 @@ class XendDomainInfo: if self.image: self.image.createDeviceModel() - def _releaseDevices(self): + def _releaseDevices(self, suspend = False): """Release all domain's devices. Nothrow guarantee.""" + if suspend and self.image: + self.image.destroy(suspend) + return while True: t = xstransact("%s/device" % self.dompath) @@ -1395,6 +1408,7 @@ class XendDomainInfo: self.info['shadow_memory'] * 1024, self.info['memory_static_max'] * 1024) + log.debug("_initDomain:shadow_memory=0x%x, memory_static_max=0x%x, memory_static_min=0x%x.", self.info['shadow_memory'], self.info['memory_static_max'], self.info['memory_static_min'],) # Round shadow up to a multiple of a MiB, as shadow_mem_control # takes MiB and we must not round down and end up under-providing. shadow = ((shadow + 1023) / 1024) * 1024 @@ -1494,6 +1508,16 @@ class XendDomainInfo: self.console_mfn = console_mfn self._introduceDomain() + image_cfg = self.info.get('image', {}) + hvm = image_cfg.has_key('hvm') + if hvm: + self.image = image.create(self, + self.info, + self.info['image'], + self.info['devices']) + if self.image: + self.image.createDeviceModel(True) + self.image.register_shutdown_watch() self._storeDomDetails() self._registerWatches() self.refreshShutdown() diff -r d64601b977b0 -r 1e590ddb1277 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Thu Jan 18 16:21:08 2007 +0000 +++ b/tools/python/xen/xend/image.py Thu Jan 18 16:48:03 2007 +0000 @@ -173,7 +173,7 @@ class ImageHandler: """Build the domain. Define in subclass.""" raise NotImplementedError() - def createDeviceModel(self): + def createDeviceModel(self, restore = False): """Create device model for the domain (define in subclass if needed).""" pass @@ -478,7 +478,7 @@ class HVMImageHandler(ImageHandler): return ret - def createDeviceModel(self): + def createDeviceModel(self, restore = False): if self.pid: return # Execute device model. @@ -487,6 +487,8 @@ class HVMImageHandler(ImageHandler): args = args + ([ "-d", "%d" % self.vm.getDomid(), "-m", "%s" % (self.getRequiredInitialReservation() / 1024)]) args = args + self.dmargs + if restore: + args = args + ([ "-loadvm", "/tmp/xen.qemu-dm.%d" % self.vm.getDomid() ]) env = dict(os.environ) if self.display: env['DISPLAY'] = self.display @@ -505,12 +507,16 @@ class HVMImageHandler(ImageHandler): self.register_reboot_feature_watch() self.pid = self.vm.gatherDom(('image/device-model-pid', int)) - def destroy(self): + def destroy(self, suspend = False): self.unregister_shutdown_watch() self.unregister_reboot_feature_watch(); if self.pid: try: - os.kill(self.pid, signal.SIGKILL) + sig = signal.SIGKILL + if suspend: + log.info("use sigusr1 to signal qemu %d", self.pid) + sig = signal.SIGUSR1 + os.kill(self.pid, sig) except OSError, exn: log.exception(exn) try: diff -r d64601b977b0 -r 1e590ddb1277 tools/xcutils/xc_restore.c --- a/tools/xcutils/xc_restore.c Thu Jan 18 16:21:08 2007 +0000 +++ b/tools/xcutils/xc_restore.c Thu Jan 18 16:48:03 2007 +0000 @@ -19,12 +19,13 @@ main(int argc, char **argv) main(int argc, char **argv) { unsigned int xc_fd, io_fd, domid, nr_pfns, store_evtchn, console_evtchn; + unsigned int hvm, pae, apic; int ret; unsigned long store_mfn, console_mfn; - if (argc != 6) + if (argc != 9) errx(1, - "usage: %s iofd domid nr_pfns store_evtchn console_evtchn", + "usage: %s iofd domid nr_pfns store_evtchn console_evtchn hvm pae apic", argv[0]); xc_fd = xc_interface_open(); @@ -36,9 +37,19 @@ main(int argc, char **argv) nr_pfns = atoi(argv[3]); store_evtchn = atoi(argv[4]); console_evtchn = atoi(argv[5]); + hvm = atoi(argv[6]); + pae = atoi(argv[7]); + apic = atoi(argv[8]); - ret = xc_linux_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn, - &store_mfn, console_evtchn, &console_mfn); + if (hvm) { + /* pass the memsize to xc_hvm_restore to find the store_mfn */ + store_mfn = hvm; + ret = xc_hvm_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn, + &store_mfn, console_evtchn, &console_mfn, pae, apic); + } else + ret = xc_linux_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn, + &store_mfn, console_evtchn, &console_mfn); + if (ret == 0) { printf("store-mfn %li\n", store_mfn); printf("console-mfn %li\n", console_mfn); diff -r d64601b977b0 -r 1e590ddb1277 tools/xcutils/xc_save.c --- a/tools/xcutils/xc_save.c Thu Jan 18 16:21:08 2007 +0000 +++ b/tools/xcutils/xc_save.c Thu Jan 18 16:48:03 2007 +0000 @@ -51,7 +51,10 @@ main(int argc, char **argv) max_f = atoi(argv[4]); flags = atoi(argv[5]); - ret = xc_linux_save(xc_fd, io_fd, domid, maxit, max_f, flags, &suspend); + if (flags & XCFLAGS_HVM) + ret = xc_hvm_save(xc_fd, io_fd, domid, maxit, max_f, flags, &suspend); + else + ret = xc_linux_save(xc_fd, io_fd, domid, maxit, max_f, flags, &suspend); xc_interface_close(xc_fd); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |