ia64/xen-unstable

changeset 5144:c0d620b026e7

bitkeeper revision 1.1546 (42944efdY94XWSK3i6H669MdigOOzw)

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@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Wed May 25 10:10:05 2005 +0000 (2005-05-25)
parents e41c470ae8b5
children d61ceec31dfd
files .rootkeys tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomain.py
line diff
     1.1 --- a/.rootkeys	Wed May 25 08:42:31 2005 +0000
     1.2 +++ b/.rootkeys	Wed May 25 10:10:05 2005 +0000
     1.3 @@ -829,6 +829,7 @@ 40c9c468Um_qc66OQeLEceIz1pgD5g tools/pyt
     1.4  40c9c468QJTEuk9g4qHxGpmIi70PEQ tools/python/xen/xend/PrettyPrint.py
     1.5  40e15b7eeQxWE_hUPB2YTgM9fsZ1PQ tools/python/xen/xend/Vifctl.py
     1.6  4270cc81xbweGYhsM4326N3dX1bGHQ tools/python/xen/xend/XendBootloader.py
     1.7 +42944ee8FQaAdZMF56O_WkWyBdCalA tools/python/xen/xend/XendCheckpoint.py
     1.8  40c9c4688m3eqnC8fhLu1APm36VOVA tools/python/xen/xend/XendClient.py
     1.9  40c9c468t6iIKTjwuYoe-UMCikDcOQ tools/python/xen/xend/XendConsole.py
    1.10  40c9c468WnXs6eOUSff23IIGI4kMfQ tools/python/xen/xend/XendDB.py
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Wed May 25 10:10:05 2005 +0000
     2.3 @@ -0,0 +1,143 @@
     2.4 +# Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
     2.5 +
     2.6 +# This file is subject to the terms and conditions of the GNU General
     2.7 +# Public License.  See the file "COPYING" in the main directory of
     2.8 +# this archive for more details.
     2.9 +
    2.10 +import errno
    2.11 +import os
    2.12 +import select
    2.13 +import sxp
    2.14 +from string import join
    2.15 +from struct import pack, unpack, calcsize
    2.16 +from xen.util.xpopen import xPopen3
    2.17 +import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
    2.18 +
    2.19 +from XendLogging import log
    2.20 +
    2.21 +SIGNATURE = "LinuxGuestRecord"
    2.22 +PAGE_SIZE = 4096
    2.23 +PATH_XC_SAVE = "/usr/libexec/xen/xc_save"
    2.24 +PATH_XC_RESTORE = "/usr/libexec/xen/xc_restore"
    2.25 +
    2.26 +sizeof_int = calcsize("i")
    2.27 +sizeof_unsigned_long = calcsize("L")
    2.28 +
    2.29 +def save(xd, fd, dominfo):
    2.30 +    if os.write(fd, SIGNATURE) != len(SIGNATURE):
    2.31 +        raise XendError("could not write guest state file: signature")
    2.32 +
    2.33 +    config = sxp.to_string(dominfo.sxpr())
    2.34 +    if os.write(fd, pack("!i", len(config))) != sizeof_int:
    2.35 +        raise XendError("could not write guest state file: config len")
    2.36 +    if os.write(fd, config) != len(config):
    2.37 +        raise XendError("could not write guest state file: config")
    2.38 +
    2.39 +    cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
    2.40 +           dominfo.id]
    2.41 +    log.info("[xc_save] " + join(cmd))
    2.42 +    child = xPopen3(cmd, True, -1, [fd, xc.handle()])
    2.43 +    
    2.44 +    lasterr = ""
    2.45 +    p = select.poll()
    2.46 +    p.register(child.fromchild.fileno())
    2.47 +    p.register(child.childerr.fileno())
    2.48 +    while True:
    2.49 +        r = p.poll()
    2.50 +        for (fd, event) in r:
    2.51 +            if not event & select.POLLIN:
    2.52 +                continue
    2.53 +            if fd == child.childerr.fileno():
    2.54 +                l = child.childerr.readline()
    2.55 +                log.error(l.rstrip())
    2.56 +                lasterr = l.rstrip()
    2.57 +            if fd == child.fromchild.fileno():
    2.58 +                l = child.fromchild.readline()
    2.59 +                if l.rstrip() == "suspend":
    2.60 +                    log.info("suspending %s" % dominfo.id)
    2.61 +                    xd.domain_shutdown(dominfo.id, reason='suspend')
    2.62 +                    dominfo.state_wait("suspended")
    2.63 +                    log.info("suspend %s done" % dominfo.id)
    2.64 +                    child.tochild.write("done\n")
    2.65 +                    child.tochild.flush()
    2.66 +        if filter(lambda (fd, event): event & select.POLLHUP, r):
    2.67 +            break
    2.68 +
    2.69 +    if child.wait() >> 8 == 127:
    2.70 +        lasterr = "popen %s failed" % PATH_XC_SAVE
    2.71 +    if child.wait() != 0:
    2.72 +        raise XendError("xc_save failed: %s" % lasterr)
    2.73 +
    2.74 +    xd.domain_destroy(dominfo.id)
    2.75 +    return None
    2.76 +
    2.77 +def restore(xd, fd):
    2.78 +    try:
    2.79 +        signature = fd.read_exact(len(SIGNATURE),
    2.80 +            "not a valid guest state file: signature read")
    2.81 +        if signature != SIGNATURE:
    2.82 +            raise XendError("not a valid guest state file: found '%s'" %
    2.83 +                            signature)
    2.84 +    
    2.85 +        l = fd.read_exact(sizeof_int,
    2.86 +                          "not a valid guest state file: config size read")
    2.87 +        vmconfig_size = unpack("!i", l)[0]
    2.88 +        vmconfig_buf = fd.read_exact(vmconfig_size,
    2.89 +            "not a valid guest state file: config read")
    2.90 +    
    2.91 +        p = sxp.Parser()
    2.92 +        p.input(vmconfig_buf)
    2.93 +        if not p.ready:
    2.94 +            raise XendError("not a valid guest state file: config parse")
    2.95 +    
    2.96 +        vmconfig = p.get_val()
    2.97 +        dominfo = xd.domain_configure(vmconfig)
    2.98 +    
    2.99 +        l = fd.read_exact(sizeof_unsigned_long,
   2.100 +                          "not a valid guest state file: pfn count read")
   2.101 +        nr_pfns = unpack("=L", l)[0]   # XXX endianess
   2.102 +        if nr_pfns > 1024*1024:     # XXX
   2.103 +            raise XendError(
   2.104 +                "not a valid guest state file: pfn count out of range")
   2.105 +    
   2.106 +        # XXXcl hack: fd.tell will sync up the object and
   2.107 +        #             underlying file descriptor
   2.108 +        ignore = fd.tell()
   2.109 +    
   2.110 +        cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd.fileno()),
   2.111 +               dominfo.id, str(nr_pfns)]
   2.112 +        log.info("[xc_restore] " + join(cmd))
   2.113 +        child = xPopen3(cmd, True, -1, [fd.fileno(), xc.handle()])
   2.114 +        child.tochild.close()
   2.115 +    
   2.116 +        lasterr = ""
   2.117 +        p = select.poll()
   2.118 +        p.register(child.fromchild.fileno())
   2.119 +        p.register(child.childerr.fileno())
   2.120 +        while True:
   2.121 +            r = p.poll()
   2.122 +            for (fd, event) in r:
   2.123 +                if not event & select.POLLIN:
   2.124 +                    continue
   2.125 +                if fd == child.childerr.fileno():
   2.126 +                    l = child.childerr.readline()
   2.127 +                    log.error(l.rstrip())
   2.128 +                    lasterr = l.rstrip()
   2.129 +                if fd == child.fromchild.fileno():
   2.130 +                    l = child.fromchild.readline()
   2.131 +                    log.info(l.rstrip())
   2.132 +            if filter(lambda (fd, event): event & select.POLLHUP, r):
   2.133 +                break
   2.134 +    
   2.135 +        if child.wait() >> 8 == 127:
   2.136 +            lasterr = "popen %s failed" % PATH_XC_RESTORE
   2.137 +        if child.wait() != 0:
   2.138 +            raise XendError("xc_restore failed: %s" % lasterr)
   2.139 +    
   2.140 +        return dominfo
   2.141 +
   2.142 +    except IOError, ex:
   2.143 +        if ex.errno == errno.ENOENT:
   2.144 +            raise XendError("can't open guest state file %s" % src)
   2.145 +        else:
   2.146 +            raise
     3.1 --- a/tools/python/xen/xend/XendDomain.py	Wed May 25 08:42:31 2005 +0000
     3.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed May 25 10:10:05 2005 +0000
     3.3 @@ -5,6 +5,8 @@
     3.4   Nothing here is persistent (across reboots).
     3.5   Needs to be persistent for one uptime.
     3.6  """
     3.7 +import os
     3.8 +import scheduler
     3.9  import sys
    3.10  import traceback
    3.11  import time
    3.12 @@ -13,6 +15,7 @@ import xen.lowlevel.xc; xc = xen.lowleve
    3.13  
    3.14  import sxp
    3.15  import XendRoot; xroot = XendRoot.instance()
    3.16 +import XendCheckpoint
    3.17  import XendDB
    3.18  import XendDomainInfo
    3.19  import XendMigrate
    3.20 @@ -20,18 +23,8 @@ import EventServer; eserver = EventServe
    3.21  from XendError import XendError
    3.22  from XendLogging import log
    3.23  
    3.24 -import scheduler
    3.25 -
    3.26  from xen.xend.server import channel
    3.27  
    3.28 -
    3.29 -import errno
    3.30 -import os
    3.31 -import select
    3.32 -from string import join
    3.33 -from struct import pack, unpack, calcsize
    3.34 -from xen.util.xpopen import xPopen3
    3.35 -
    3.36  __all__ = [ "XendDomain" ]
    3.37  
    3.38  SHUTDOWN_TIMEOUT = 30
    3.39 @@ -330,91 +323,17 @@ class XendDomain:
    3.40          @param progress: output progress if true
    3.41          """
    3.42  
    3.43 -        SIGNATURE = "LinuxGuestRecord"
    3.44 -        sizeof_int = calcsize("i")
    3.45 -        sizeof_unsigned_long = calcsize("L")
    3.46 -        PAGE_SIZE = 4096
    3.47 -        PATH_XC_RESTORE = "/usr/libexec/xen/xc_restore"
    3.48 -
    3.49          class XendFile(file):
    3.50              def read_exact(self, size, error_msg):
    3.51                  buf = self.read(size)
    3.52                  if len(buf) != size:
    3.53                      raise XendError(error_msg)
    3.54                  return buf
    3.55 -        
    3.56 -        try:
    3.57 -            fd = XendFile(src, 'rb')
    3.58  
    3.59 -            signature = fd.read_exact(len(SIGNATURE),
    3.60 -                "not a valid guest state file: signature read")
    3.61 -            if signature != SIGNATURE:
    3.62 -                raise XendError("not a valid guest state file: found '%s'" %
    3.63 -                                signature)
    3.64 -
    3.65 -            l = fd.read_exact(sizeof_int,
    3.66 -                              "not a valid guest state file: config size read")
    3.67 -            vmconfig_size = unpack("!i", l)[0]
    3.68 -            vmconfig_buf = fd.read_exact(vmconfig_size,
    3.69 -                "not a valid guest state file: config read")
    3.70 -
    3.71 -            p = sxp.Parser()
    3.72 -            p.input(vmconfig_buf)
    3.73 -            if not p.ready:
    3.74 -                raise XendError("not a valid guest state file: config parse")
    3.75 -
    3.76 -            vmconfig = p.get_val()
    3.77 -            dominfo = self.domain_configure(vmconfig)
    3.78 -
    3.79 -            l = fd.read_exact(sizeof_unsigned_long,
    3.80 -                              "not a valid guest state file: pfn count read")
    3.81 -            nr_pfns = unpack("=L", l)[0]   # XXX endianess
    3.82 -            if nr_pfns > 1024*1024:     # XXX
    3.83 -                raise XendError(
    3.84 -                    "not a valid guest state file: pfn count out of range")
    3.85 -
    3.86 -            # XXXcl hack: fd.tell will sync up the object and
    3.87 -            #             underlying file descriptor
    3.88 -            ignore = fd.tell()
    3.89 +        fd = XendFile(src, 'rb')
    3.90  
    3.91 -            cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd.fileno()),
    3.92 -                   dominfo.id, str(nr_pfns)]
    3.93 -            log.info("[xc_restore] " + join(cmd))
    3.94 -            child = xPopen3(cmd, True, -1, [fd.fileno(), xc.handle()])
    3.95 -            child.tochild.close()
    3.96 +        return XendCheckpoint.restore(self, fd)
    3.97  
    3.98 -            lasterr = ""
    3.99 -            p = select.poll()
   3.100 -            p.register(child.fromchild.fileno())
   3.101 -            p.register(child.childerr.fileno())
   3.102 -            while True:
   3.103 -                r = p.poll()
   3.104 -                for (fd, event) in r:
   3.105 -                    if not event & select.POLLIN:
   3.106 -                        continue
   3.107 -                    if fd == child.childerr.fileno():
   3.108 -                        l = child.childerr.readline()
   3.109 -                        log.error(l.rstrip())
   3.110 -                        lasterr = l.rstrip()
   3.111 -                    if fd == child.fromchild.fileno():
   3.112 -                        l = child.fromchild.readline()
   3.113 -                        log.info(l.rstrip())
   3.114 -                if filter(lambda (fd, event): event & select.POLLHUP, r):
   3.115 -                    break
   3.116 -
   3.117 -            if child.wait() >> 8 == 127:
   3.118 -                lasterr = "popen %s failed" % PATH_XC_RESTORE
   3.119 -            if child.wait() != 0:
   3.120 -                raise XendError("xc_restore failed: %s" % lasterr)
   3.121 -
   3.122 -            return dominfo
   3.123 -
   3.124 -        except IOError, ex:
   3.125 -            if ex.errno == errno.ENOENT:
   3.126 -                raise XendError("can't open guest state file %s" % src)
   3.127 -            else:
   3.128 -                raise
   3.129 -    
   3.130      def domain_get(self, id):
   3.131          """Get up-to-date info about a domain.
   3.132  
   3.133 @@ -604,61 +523,12 @@ class XendDomain:
   3.134          @param progress: output progress if true
   3.135          """
   3.136  
   3.137 -        SIGNATURE = "LinuxGuestRecord"
   3.138 -        sizeof_int = calcsize("i")
   3.139 -        PATH_XC_SAVE = "/usr/libexec/xen/xc_save"
   3.140 -
   3.141          try:
   3.142              dominfo = self.domain_lookup(id)
   3.143  
   3.144              fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
   3.145  
   3.146 -            if os.write(fd, SIGNATURE) != len(SIGNATURE):
   3.147 -                raise XendError("could not write guest state file: signature")
   3.148 -
   3.149 -            config = sxp.to_string(dominfo.sxpr())
   3.150 -            if os.write(fd, pack("!i", len(config))) != sizeof_int:
   3.151 -                raise XendError("could not write guest state file: config len")
   3.152 -            if os.write(fd, config) != len(config):
   3.153 -                raise XendError("could not write guest state file: config")
   3.154 -
   3.155 -            cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
   3.156 -                   dominfo.id]
   3.157 -            log.info("[xc_save] " + join(cmd))
   3.158 -            child = xPopen3(cmd, True, -1, [fd, xc.handle()])
   3.159 -            
   3.160 -            lasterr = ""
   3.161 -            p = select.poll()
   3.162 -            p.register(child.fromchild.fileno())
   3.163 -            p.register(child.childerr.fileno())
   3.164 -            while True:
   3.165 -                r = p.poll()
   3.166 -                for (fd, event) in r:
   3.167 -                    if not event & select.POLLIN:
   3.168 -                        continue
   3.169 -                    if fd == child.childerr.fileno():
   3.170 -                        l = child.childerr.readline()
   3.171 -                        log.error(l.rstrip())
   3.172 -                        lasterr = l.rstrip()
   3.173 -                    if fd == child.fromchild.fileno():
   3.174 -                        l = child.fromchild.readline()
   3.175 -                        if l.rstrip() == "suspend":
   3.176 -                            log.info("suspending %s" % dominfo.id)
   3.177 -                            self.domain_shutdown(dominfo.id, reason='suspend')
   3.178 -                            dominfo.state_wait("suspended")
   3.179 -                            log.info("suspend %s done" % dominfo.id)
   3.180 -                            child.tochild.write("done\n")
   3.181 -                            child.tochild.flush()
   3.182 -                if filter(lambda (fd, event): event & select.POLLHUP, r):
   3.183 -                    break
   3.184 -
   3.185 -            if child.wait() >> 8 == 127:
   3.186 -                lasterr = "popen %s failed" % PATH_XC_SAVE
   3.187 -            if child.wait() != 0:
   3.188 -                raise XendError("xc_save failed: %s" % lasterr)
   3.189 -
   3.190 -            self.domain_destroy(dominfo.id)
   3.191 -            return None
   3.192 +            return XendCheckpoint.save(self, fd, dominfo)
   3.193  
   3.194          except:
   3.195              raise