[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] XendDomain.py:
ChangeSet 1.1546, 2005/05/25 11:10:05+01:00, cl349@xxxxxxxxxxxxxxxxxxxx XendDomain.py: Move save/restore code in seperate file. XendCheckpoint.py: Support code for save/restore of domains. Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx> XendCheckpoint.py | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ XendDomain.py | 142 ++--------------------------------------------------- 2 files changed, 149 insertions(+), 136 deletions(-) diff -Nru a/tools/python/xen/xend/XendCheckpoint.py b/tools/python/xen/xend/XendCheckpoint.py --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/tools/python/xen/xend/XendCheckpoint.py 2005-05-25 07:02:00 -04:00 @@ -0,0 +1,143 @@ +# Copyright (C) 2005 Christian Limpach <Christian.Limpach@xxxxxxxxxxxx> + +# This file is subject to the terms and conditions of the GNU General +# Public License. See the file "COPYING" in the main directory of +# this archive for more details. + +import errno +import os +import select +import sxp +from string import join +from struct import pack, unpack, calcsize +from xen.util.xpopen import xPopen3 +import xen.lowlevel.xc; xc = xen.lowlevel.xc.new() + +from XendLogging import log + +SIGNATURE = "LinuxGuestRecord" +PAGE_SIZE = 4096 +PATH_XC_SAVE = "/usr/libexec/xen/xc_save" +PATH_XC_RESTORE = "/usr/libexec/xen/xc_restore" + +sizeof_int = calcsize("i") +sizeof_unsigned_long = calcsize("L") + +def save(xd, fd, dominfo): + if os.write(fd, SIGNATURE) != len(SIGNATURE): + raise XendError("could not write guest state file: signature") + + config = sxp.to_string(dominfo.sxpr()) + if os.write(fd, pack("!i", len(config))) != sizeof_int: + raise XendError("could not write guest state file: config len") + if os.write(fd, config) != len(config): + raise XendError("could not write guest state file: config") + + cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd), + dominfo.id] + log.info("[xc_save] " + join(cmd)) + child = xPopen3(cmd, True, -1, [fd, xc.handle()]) + + lasterr = "" + p = select.poll() + p.register(child.fromchild.fileno()) + p.register(child.childerr.fileno()) + while True: + r = p.poll() + for (fd, event) in r: + if not event & select.POLLIN: + continue + if fd == child.childerr.fileno(): + l = child.childerr.readline() + log.error(l.rstrip()) + lasterr = l.rstrip() + if fd == child.fromchild.fileno(): + l = child.fromchild.readline() + if l.rstrip() == "suspend": + log.info("suspending %s" % dominfo.id) + xd.domain_shutdown(dominfo.id, reason='suspend') + dominfo.state_wait("suspended") + log.info("suspend %s done" % dominfo.id) + child.tochild.write("done\n") + child.tochild.flush() + if filter(lambda (fd, event): event & select.POLLHUP, r): + break + + if child.wait() >> 8 == 127: + lasterr = "popen %s failed" % PATH_XC_SAVE + if child.wait() != 0: + raise XendError("xc_save failed: %s" % lasterr) + + xd.domain_destroy(dominfo.id) + return None + +def restore(xd, fd): + try: + signature = fd.read_exact(len(SIGNATURE), + "not a valid guest state file: signature read") + if signature != SIGNATURE: + raise XendError("not a valid guest state file: found '%s'" % + signature) + + l = fd.read_exact(sizeof_int, + "not a valid guest state file: config size read") + vmconfig_size = unpack("!i", l)[0] + vmconfig_buf = fd.read_exact(vmconfig_size, + "not a valid guest state file: config read") + + p = sxp.Parser() + p.input(vmconfig_buf) + if not p.ready: + raise XendError("not a valid guest state file: config parse") + + vmconfig = p.get_val() + dominfo = xd.domain_configure(vmconfig) + + l = fd.read_exact(sizeof_unsigned_long, + "not a valid guest state file: pfn count read") + nr_pfns = unpack("=L", l)[0] # XXX endianess + if nr_pfns > 1024*1024: # XXX + raise XendError( + "not a valid guest state file: pfn count out of range") + + # XXXcl hack: fd.tell will sync up the object and + # underlying file descriptor + ignore = fd.tell() + + cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd.fileno()), + dominfo.id, str(nr_pfns)] + log.info("[xc_restore] " + join(cmd)) + child = xPopen3(cmd, True, -1, [fd.fileno(), xc.handle()]) + child.tochild.close() + + lasterr = "" + p = select.poll() + p.register(child.fromchild.fileno()) + p.register(child.childerr.fileno()) + while True: + r = p.poll() + for (fd, event) in r: + if not event & select.POLLIN: + continue + if fd == child.childerr.fileno(): + l = child.childerr.readline() + log.error(l.rstrip()) + lasterr = l.rstrip() + if fd == child.fromchild.fileno(): + l = child.fromchild.readline() + log.info(l.rstrip()) + if filter(lambda (fd, event): event & select.POLLHUP, r): + break + + if child.wait() >> 8 == 127: + lasterr = "popen %s failed" % PATH_XC_RESTORE + if child.wait() != 0: + raise XendError("xc_restore failed: %s" % lasterr) + + return dominfo + + except IOError, ex: + if ex.errno == errno.ENOENT: + raise XendError("can't open guest state file %s" % src) + else: + raise diff -Nru a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py 2005-05-25 07:02:00 -04:00 +++ b/tools/python/xen/xend/XendDomain.py 2005-05-25 07:02:00 -04:00 @@ -5,6 +5,8 @@ Nothing here is persistent (across reboots). Needs to be persistent for one uptime. """ +import os +import scheduler import sys import traceback import time @@ -13,6 +15,7 @@ import sxp import XendRoot; xroot = XendRoot.instance() +import XendCheckpoint import XendDB import XendDomainInfo import XendMigrate @@ -20,18 +23,8 @@ from XendError import XendError from XendLogging import log -import scheduler - from xen.xend.server import channel - -import errno -import os -import select -from string import join -from struct import pack, unpack, calcsize -from xen.util.xpopen import xPopen3 - __all__ = [ "XendDomain" ] SHUTDOWN_TIMEOUT = 30 @@ -330,91 +323,17 @@ @param progress: output progress if true """ - SIGNATURE = "LinuxGuestRecord" - sizeof_int = calcsize("i") - sizeof_unsigned_long = calcsize("L") - PAGE_SIZE = 4096 - PATH_XC_RESTORE = "/usr/libexec/xen/xc_restore" - class XendFile(file): def read_exact(self, size, error_msg): buf = self.read(size) if len(buf) != size: raise XendError(error_msg) return buf - - try: - fd = XendFile(src, 'rb') - signature = fd.read_exact(len(SIGNATURE), - "not a valid guest state file: signature read") - if signature != SIGNATURE: - raise XendError("not a valid guest state file: found '%s'" % - signature) - - l = fd.read_exact(sizeof_int, - "not a valid guest state file: config size read") - vmconfig_size = unpack("!i", l)[0] - vmconfig_buf = fd.read_exact(vmconfig_size, - "not a valid guest state file: config read") - - p = sxp.Parser() - p.input(vmconfig_buf) - if not p.ready: - raise XendError("not a valid guest state file: config parse") - - vmconfig = p.get_val() - dominfo = self.domain_configure(vmconfig) - - l = fd.read_exact(sizeof_unsigned_long, - "not a valid guest state file: pfn count read") - nr_pfns = unpack("=L", l)[0] # XXX endianess - if nr_pfns > 1024*1024: # XXX - raise XendError( - "not a valid guest state file: pfn count out of range") - - # XXXcl hack: fd.tell will sync up the object and - # underlying file descriptor - ignore = fd.tell() - - cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd.fileno()), - dominfo.id, str(nr_pfns)] - log.info("[xc_restore] " + join(cmd)) - child = xPopen3(cmd, True, -1, [fd.fileno(), xc.handle()]) - child.tochild.close() - - lasterr = "" - p = select.poll() - p.register(child.fromchild.fileno()) - p.register(child.childerr.fileno()) - while True: - r = p.poll() - for (fd, event) in r: _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |