ia64/xen-unstable

changeset 1754:095e969226c4

bitkeeper revision 1.1068 (40f2bd236qdLHUh6BZA_h_brBDxINw)

Merge ssh://xenbk@gandalf.hpl.hp.com//var/bk/xeno-unstable.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Mon Jul 12 16:32:35 2004 +0000 (2004-07-12)
parents 17be2261d755 2f1d50d10f6f
children ba1f4ebe0154 2ae481a95b81
files linux-2.4.26-xen-sparse/arch/xen/defconfig-xen0 tools/libxc/xc_io.h tools/python/xen/xend/XendClient.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendMigrate.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/SrvDomainDir.py tools/xfrd/Makefile tools/xfrd/xen_domain.c tools/xfrd/xfrd.c tools/xfrd/xfrd.h
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/defconfig-xen0	Mon Jul 12 16:32:11 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/defconfig-xen0	Mon Jul 12 16:32:35 2004 +0000
     1.3 @@ -387,9 +387,22 @@ CONFIG_CHR_DEV_SG=y
     1.4  # CONFIG_SCSI_AHA1542 is not set
     1.5  # CONFIG_SCSI_AHA1740 is not set
     1.6  CONFIG_SCSI_AACRAID=y
     1.7 -# CONFIG_SCSI_AIC7XXX is not set
     1.8 -# CONFIG_SCSI_AIC79XX is not set
     1.9 -# CONFIG_SCSI_AIC7XXX_OLD is not set
    1.10 +CONFIG_SCSI_AIC7XXX=y
    1.11 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
    1.12 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000
    1.13 +# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
    1.14 +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
    1.15 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
    1.16 +CONFIG_AIC7XXX_DEBUG_MASK=0
    1.17 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
    1.18 +CONFIG_SCSI_AIC79XX=y
    1.19 +CONFIG_AIC79XX_CMDS_PER_DEVICE=32
    1.20 +CONFIG_AIC79XX_RESET_DELAY_MS=15000
    1.21 +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
    1.22 +# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
    1.23 +# CONFIG_AIC79XX_DEBUG_ENABLE is not set
    1.24 +CONFIG_AIC79XX_DEBUG_MASK=0
    1.25 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
    1.26  # CONFIG_SCSI_DPT_I2O is not set
    1.27  # CONFIG_SCSI_ADVANSYS is not set
    1.28  # CONFIG_SCSI_IN2000 is not set
    1.29 @@ -412,9 +425,11 @@ CONFIG_SCSI_BUSLOGIC=y
    1.30  # CONFIG_SCSI_INIA100 is not set
    1.31  # CONFIG_SCSI_NCR53C406A is not set
    1.32  # CONFIG_SCSI_NCR53C7xx is not set
    1.33 -# CONFIG_SCSI_SYM53C8XX_2 is not set
    1.34 -# CONFIG_SCSI_NCR53C8XX is not set
    1.35 -# CONFIG_SCSI_SYM53C8XX is not set
    1.36 +CONFIG_SCSI_SYM53C8XX_2=y
    1.37 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
    1.38 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
    1.39 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
    1.40 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
    1.41  # CONFIG_SCSI_PAS16 is not set
    1.42  # CONFIG_SCSI_PCI2000 is not set
    1.43  # CONFIG_SCSI_PCI2220I is not set
     2.1 --- a/tools/libxc/xc_io.h	Mon Jul 12 16:32:11 2004 +0000
     2.2 +++ b/tools/libxc/xc_io.h	Mon Jul 12 16:32:35 2004 +0000
     2.3 @@ -1,6 +1,7 @@
     2.4  #ifndef __XC_XC_IO_H__
     2.5  #define __XC_XC_IO_H__
     2.6  
     2.7 +#include <errno.h>
     2.8  #include "xc_private.h"
     2.9  #include "iostream.h"
    2.10  
    2.11 @@ -12,8 +13,21 @@ typedef struct XcIOContext {
    2.12      IOStream *err;
    2.13      char *vmconfig;
    2.14      int vmconfig_n;
    2.15 +    int (*suspend)(u32 domain, void *data);
    2.16 +    void *data;
    2.17  } XcIOContext;
    2.18  
    2.19 +static inline int xcio_suspend_domain(XcIOContext *ctxt){
    2.20 +    int err = 0;
    2.21 +
    2.22 +    if(ctxt->suspend){
    2.23 +        err = ctxt->suspend(ctxt->domain, ctxt->data);
    2.24 +    } else {
    2.25 +        err = -EINVAL;
    2.26 +    }
    2.27 +    return err;
    2.28 +}
    2.29 +
    2.30  static inline int xcio_read(XcIOContext *ctxt, void *buf, int n){
    2.31      int rc;
    2.32  
     3.1 --- a/tools/python/xen/xend/XendClient.py	Mon Jul 12 16:32:11 2004 +0000
     3.2 +++ b/tools/python/xen/xend/XendClient.py	Mon Jul 12 16:32:35 2004 +0000
     3.3 @@ -231,6 +231,11 @@ class Xend:
     3.4      def xend_domain(self, id):
     3.5          return xend_get(self.domainurl(id))
     3.6  
     3.7 +    def xend_domain_configure(self, id, config):
     3.8 +        return xend_call(self.domainurl(id),
     3.9 +                         {'op'      : 'configure',
    3.10 +                          'config'  : fileof(conf) })
    3.11 +
    3.12      def xend_domain_unpause(self, id):
    3.13          return xend_call(self.domainurl(id),
    3.14                           {'op'      : 'unpause'})
     4.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Jul 12 16:32:11 2004 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomain.py	Mon Jul 12 16:32:35 2004 +0000
     4.3 @@ -311,6 +311,42 @@ class XendDomain:
     4.4              return dominfo
     4.5          deferred.addCallback(fn)
     4.6          return deferred
     4.7 +
     4.8 +    def domain_configure(self, id, config):
     4.9 +        """Configure an existing domain. This is intended for internal
    4.10 +        use by domain restore and migrate.
    4.11 +
    4.12 +        @param id:     domain id
    4.13 +        @param config: configuration
    4.14 +        @return: deferred
    4.15 +        """
    4.16 +        dom = int(id)
    4.17 +        dominfo = self.domain_get(dom)
    4.18 +        if not dominfo:
    4.19 +            raise ValueError("Invalid domain: " + str(id))
    4.20 +        if dominfo.config:
    4.21 +            raise ValueError("Domain already configured: " + str(id))
    4.22 +        def fn(dominfo):
    4.23 +            self._add_domain(dominfo.id, dominfo)
    4.24 +            return dominfo
    4.25 +        deferred = dominfo.construct(config)
    4.26 +        deferred.addCallback(fn)
    4.27 +        return deferred
    4.28 +    
    4.29 +    def domain_restore(self, src, progress=0):
    4.30 +        """Restore a domain from file.
    4.31 +
    4.32 +        @param src:      source file
    4.33 +        @param progress: output progress if true
    4.34 +        @return: deferred
    4.35 +        """
    4.36 +        
    4.37 +        def fn(dominfo):
    4.38 +            self._add_domain(dominfo.id, dominfo)
    4.39 +            return dominfo
    4.40 +        deferred = XendDomainInfo.vm_restore(src, progress=progress)
    4.41 +        deferred.addCallback(fn)
    4.42 +        return deferred
    4.43      
    4.44      def domain_get(self, id):
    4.45          """Get up-to-date info about a domain.
    4.46 @@ -346,6 +382,8 @@ class XendDomain:
    4.47           - reboot: domain will restart.
    4.48           - halt: domain will not restart (even if has autorestart set).
    4.49  
    4.50 +         Returns immediately.
    4.51 +
    4.52          @param id:     domain id
    4.53          @param reason: shutdown type: poweroff, reboot, suspend, halt
    4.54          """
    4.55 @@ -443,7 +481,7 @@ class XendDomain:
    4.56  
    4.57      def domain_destroy(self, id):
    4.58          """Terminate domain immediately.
    4.59 -        Camcels any restart for the domain.
    4.60 +        Cancels any restart for the domain.
    4.61  
    4.62          @param id: domain id
    4.63          """
    4.64 @@ -456,6 +494,7 @@ class XendDomain:
    4.65          """Start domain migration.
    4.66  
    4.67          @param id: domain id
    4.68 +        @return: deferred
    4.69          """
    4.70          # Need a cancel too?
    4.71          # Don't forget to cancel restart for it.
    4.72 @@ -464,41 +503,16 @@ class XendDomain:
    4.73          return xmigrate.migrate_begin(dom, dst)
    4.74  
    4.75      def domain_save(self, id, dst, progress=0):
    4.76 -        """Save domain state to file, destroy domain on success.
    4.77 -        Leave domain running on error.
    4.78 +        """Start saving a domain to file.
    4.79  
    4.80          @param id:       domain id
    4.81          @param dst:      destination file
    4.82          @param progress: output progress if true
    4.83 +        @return: deferred
    4.84          """
    4.85          dom = int(id)
    4.86 -        dominfo = self.domain_get(id)
    4.87 -        if not dominfo:
    4.88 -            return -1
    4.89 -        vmconfig = sxp.to_string(dominfo.sxpr())
    4.90 -        self.domain_pause(id)
    4.91 -        eserver.inject('xend.domain.save', id)
    4.92 -        try:
    4.93 -            rc = xc.linux_save(dom=dom, state_file=dst,
    4.94 -                               vmconfig=vmconfig, progress=progress)
    4.95 -        except:
    4.96 -            rc = -1
    4.97 -        if rc == 0:
    4.98 -            self.domain_destroy(id)
    4.99 -        else:
   4.100 -            self.domain_unpause(id)
   4.101 -        return rc
   4.102 -    
   4.103 -    def domain_restore(self, src, progress=0):
   4.104 -        """Restore domain from file.
   4.105 -
   4.106 -        @param src :     source file
   4.107 -        @param progress: output progress if true
   4.108 -        @return: domain object
   4.109 -        """
   4.110 -        dominfo = XendDomainInfo.vm_restore(src, progress=progress)
   4.111 -        self._add_domain(dominfo.id, dominfo)
   4.112 -        return dominfo
   4.113 +        xmigrate = XendMigrate.instance()
   4.114 +        return xmigrate.save_begin(dom, dst)
   4.115      
   4.116      def domain_pincpu(self, dom, cpu):
   4.117          """Pin a domain to a cpu.
     5.1 --- a/tools/python/xen/xend/XendMigrate.py	Mon Jul 12 16:32:11 2004 +0000
     5.2 +++ b/tools/python/xen/xend/XendMigrate.py	Mon Jul 12 16:32:35 2004 +0000
     5.3 @@ -1,5 +1,6 @@
     5.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     5.5  
     5.6 +import errno
     5.7  import sys
     5.8  import socket
     5.9  import time
    5.10 @@ -14,9 +15,12 @@ import sxp
    5.11  import XendDB
    5.12  import EventServer; eserver = EventServer.instance()
    5.13  
    5.14 +"""The port for the migrate/save daemon xfrd."""
    5.15  XFRD_PORT = 8002
    5.16  
    5.17 +"""The transfer protocol major version number."""
    5.18  XFR_PROTO_MAJOR = 1
    5.19 +"""The transfer protocol minor version number."""
    5.20  XFR_PROTO_MINOR = 0
    5.21  
    5.22  class Xfrd(Protocol):
    5.23 @@ -46,7 +50,7 @@ class Xfrd(Protocol):
    5.24          self.parser.input(data)
    5.25          if self.parser.ready():
    5.26              val = self.parser.get_val()
    5.27 -            self.xinfo.dispatch(val)
    5.28 +            self.xinfo.dispatch(self, val)
    5.29          if self.parser.at_eof():
    5.30              self.loseConnection()
    5.31              
    5.32 @@ -55,16 +59,16 @@ class XfrdClientFactory(ClientFactory):
    5.33      """Factory for clients of the migration/save daemon xfrd.
    5.34      """
    5.35  
    5.36 -    def __init__(self, minfo):
    5.37 +    def __init__(self, xinfo):
    5.38          #ClientFactory.__init__(self)
    5.39 -        self.minfo = minfo
    5.40 +        self.xinfo = xinfo
    5.41  
    5.42      def startedConnecting(self, connector):
    5.43          print 'Started to connect', 'self=', self, 'connector=', connector
    5.44  
    5.45      def buildProtocol(self, addr):
    5.46          print 'buildProtocol>', addr
    5.47 -        return Migrate(self.minfo)
    5.48 +        return Xfrd(self.xinfo)
    5.49  
    5.50      def clientConnectionLost(self, connector, reason):
    5.51          print 'clientConnectionLost>', 'connector=', connector, 'reason=', reason
    5.52 @@ -76,13 +80,15 @@ class XfrdInfo:
    5.53      """Abstract class for info about a session with xfrd.
    5.54      Has subclasses for save and migrate.
    5.55      """
    5.56 -    
    5.57 +
    5.58 +    def __init__(self):
    5.59 +        from xen.xend import XendDomain
    5.60 +        self.xd = XendDomain.instance()
    5.61 +        self.deferred = defer.Deferred()
    5.62 +        
    5.63      def vmconfig(self):
    5.64          print 'vmconfig>'
    5.65 -        from xen.xend import XendDomain
    5.66 -        xd = XendDomain.instance()
    5.67 -
    5.68 -        dominfo = xd.domain_get(self.src_dom)
    5.69 +        dominfo = self.xd.domain_get(self.src_dom)
    5.70          print 'vmconfig>', type(dominfo), dominfo
    5.71          if dominfo:
    5.72              val = sxp.to_string(dominfo.sxpr())
    5.73 @@ -93,6 +99,8 @@ class XfrdInfo:
    5.74  
    5.75      def error(self, err):
    5.76          self.state = 'error'
    5.77 +        if not self.deferred.called:
    5.78 +            self.deferred.errback(err)
    5.79  
    5.80      def dispatch(self, xfrd, val):
    5.81          op = sxp.name(val)
    5.82 @@ -100,38 +108,70 @@ class XfrdInfo:
    5.83          if op.startswith('xfr_'):
    5.84              fn = getattr(self, op, self.unknown)
    5.85          else:
    5.86 -            fn = self.unknown()
    5.87 -        fn(xfrd, val)
    5.88 +            fn = self.unknown
    5.89 +        val = fn(xfrd, val)
    5.90 +        if val is not None:
    5.91 +            sxp.show(val, out=self.transport)
    5.92  
    5.93      def unknown(self, xfrd, val):
    5.94          print 'unknown>', val
    5.95 +        xfrd.loseConnection()
    5.96 +        return None
    5.97  
    5.98      def xfr_err(self, xfrd, val):
    5.99 -        # If we get an error with non-zero code the migrate failed.
   5.100 +        # If we get an error with non-zero code the operation failed.
   5.101          # An error with code zero indicates hello success.
   5.102          print 'xfr_err>', val
   5.103 -        v = sxp.child(val)
   5.104 +        v = sxp.child0(val)
   5.105          print 'xfr_err>', type(v), v
   5.106 -        err = int(sxp.child(val))
   5.107 +        err = int(sxp.child0(val))
   5.108          if not err: return
   5.109          self.error(err);
   5.110          xfrd.loseConnection()
   5.111 +        #try:
   5.112 +        #    self.xd.domain_unpause(self.src_dom)
   5.113 +        #except:
   5.114 +        #    print >>sys.stdout, "Error unpausing domain:", self.src_dom
   5.115 +        return None
   5.116  
   5.117      def xfr_progress(self, val):
   5.118          print 'xfr_progress>', val
   5.119 +        return None
   5.120  
   5.121 -    def xfr_domain_pause(self, val):
   5.122 -        print 'xfr__domain_pause>', val
   5.123 +    def xfr_vm_pause(self, val):
   5.124 +        print 'xfr_vm_pause>', val
   5.125 +        try:
   5.126 +            vmid = sxp.child0(val)
   5.127 +            val = self.xd.domain_pause(vmid)
   5.128 +        except:
   5.129 +            val = errno.EINVAL
   5.130 +        return ['xfr.err', val]
   5.131  
   5.132 -    def xfr_domain_suspend(self, val):
   5.133 -        print 'xfr_domain_suspend>', val
   5.134 +    def xfr_vm_unpause(self, val):
   5.135 +        print 'xfr_vm_unpause>', val
   5.136 +        try:
   5.137 +            vmid = sxp.child0(val)
   5.138 +            val = self.xd.domain_unpause(vmid)
   5.139 +        except:
   5.140 +            val = errno.EINVAL
   5.141 +        return ['xfr.err', val]
   5.142 +
   5.143 +    def xfr_vm_suspend(self, val):
   5.144 +        print 'xfr_vm_suspend>', val
   5.145 +        try:
   5.146 +            vmid = sxp.child0(val)
   5.147 +            val = self.xd.domain_shutdown(vmid, reason='suspend')
   5.148 +        except:
   5.149 +            val = errno.EINVAL
   5.150 +        return ['xfr.err', val]
   5.151  
   5.152  class XendMigrateInfo(XfrdInfo):
   5.153      """Representation of a migrate in-progress and its interaction with xfrd.
   5.154      """
   5.155  
   5.156 -    def __init__(self, id, dom, host, port):
   5.157 -        self.id = id
   5.158 +    def __init__(self, xid, dom, host, port):
   5.159 +        XfrdInfo.__init__(self)
   5.160 +        self.xid = xid
   5.161          self.state = 'begin'
   5.162          self.src_host = socket.gethostname()
   5.163          self.src_dom = dom
   5.164 @@ -139,10 +179,9 @@ class XendMigrateInfo(XfrdInfo):
   5.165          self.dst_port = port
   5.166          self.dst_dom = None
   5.167          self.start = 0
   5.168 -        self.deferred = defer.Deferred()
   5.169          
   5.170      def sxpr(self):
   5.171 -        sxpr = ['migrate', ['id', self.id], ['state', self.state] ]
   5.172 +        sxpr = ['migrate', ['id', self.xid], ['state', self.state] ]
   5.173          sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
   5.174          sxpr.append(sxpr_src)
   5.175          sxpr_dst = ['dst', ['host', self.dst_host] ]
   5.176 @@ -160,12 +199,15 @@ class XendMigrateInfo(XfrdInfo):
   5.177                        self.src_dom,
   5.178                        vmconfig,
   5.179                        self.dst_host,
   5.180 -                      self.d.dst_port])
   5.181 +                      self.dst_port])
   5.182          
   5.183      def xfr_migrate_ok(self, val):
   5.184          dom = int(sxp.child0(val))
   5.185          self.state = 'ok'
   5.186          self.dst_dom = dom
   5.187 +        self.xd_domain_destroy(self.src_dom)
   5.188 +        if not self.deferred.called:
   5.189 +            self.deferred.callback(self)
   5.190  
   5.191      def connectionLost(self, reason=None):
   5.192          if self.state =='ok':
   5.193 @@ -178,17 +220,17 @@ class XendSaveInfo(XfrdInfo):
   5.194      """Representation of a save in-progress and its interaction with xfrd.
   5.195      """
   5.196      
   5.197 -    def __init__(self, id, dom, file):
   5.198 -        self.id = id
   5.199 +    def __init__(self, xid, dom, file):
   5.200 +        XfrdInfo.__init__(self)
   5.201 +        self.xid = xid
   5.202          self.state = 'begin'
   5.203          self.src_dom = dom
   5.204          self.file = file
   5.205          self.start = 0
   5.206 -        self.deferred = defer.Deferred()
   5.207          
   5.208      def sxpr(self):
   5.209          sxpr = ['save',
   5.210 -                ['id', self.id],
   5.211 +                ['id', self.xid],
   5.212                  ['state', self.state],
   5.213                  ['domain', self.src_dom],
   5.214                  ['file', self.file] ]
   5.215 @@ -204,6 +246,9 @@ class XendSaveInfo(XfrdInfo):
   5.216      def xfr_save_ok(self, val):
   5.217          dom = int(sxp.child0(val))
   5.218          self.state = 'ok'
   5.219 +        self.xd_domain_destroy(self.src_dom)
   5.220 +        if not self.deferred.called:
   5.221 +            self.deferred.callback(self)
   5.222  
   5.223      def connectionLost(self, reason=None):
   5.224          if self.state =='ok':
   5.225 @@ -217,7 +262,6 @@ class XendMigrate:
   5.226      """External api for interaction with xfrd for migrate and save.
   5.227      Singleton.
   5.228      """
   5.229 -    # Represents migration in progress.
   5.230      # Use log for indications of begin/end/errors?
   5.231      # Need logging of: domain create/halt, migrate begin/end/fail
   5.232      # Log via event server?
   5.233 @@ -226,53 +270,77 @@ class XendMigrate:
   5.234      
   5.235      def __init__(self):
   5.236          self.db = XendDB.XendDB(self.dbpath)
   5.237 -        self.migrate = {}
   5.238 -        self.migrate_db = self.db.fetchall("")
   5.239 -        self.id = 0
   5.240 +        self.session = {}
   5.241 +        self.session_db = self.db.fetchall("")
   5.242 +        self.xid = 0
   5.243  
   5.244      def nextid(self):
   5.245 -        self.id += 1
   5.246 -        return "%d" % self.id
   5.247 +        self.xid += 1
   5.248 +        return "%d" % self.xid
   5.249  
   5.250      def sync(self):
   5.251 -        self.db.saveall("", self.migrate_db)
   5.252 +        self.db.saveall("", self.session_db)
   5.253  
   5.254 -    def sync_migrate(self, id):
   5.255 -        self.db.save(id, self.migrate_db[id])
   5.256 +    def sync_session(self, xid):
   5.257 +        print 'sync_session>', type(xid), xid, self.session_db[xid]
   5.258 +        self.db.save(xid, self.session_db[xid])
   5.259  
   5.260      def close(self):
   5.261          pass
   5.262  
   5.263 -    def _add_migrate(self, id, info):
   5.264 -        self.migrate[id] = info
   5.265 -        self.migrate_db[id] = info.sxpr()
   5.266 -        self.sync_migrate(id)
   5.267 +    def _add_session(self, xid, info):
   5.268 +        self.session[xid] = info
   5.269 +        self.session_db[xid] = info.sxpr()
   5.270 +        self.sync_session(xid)
   5.271          #eserver.inject('xend.migrate.begin', info.sxpr())
   5.272  
   5.273 -    def _delete_migrate(self, id):
   5.274 -        #eserver.inject('xend.migrate.end', id)
   5.275 -        del self.migrate[id]
   5.276 -        del self.migrate_db[id]
   5.277 -        self.db.delete(id)
   5.278 +    def _delete_session(self, xid):
   5.279 +        #eserver.inject('xend.migrate.end', xid)
   5.280 +        del self.session[xid]
   5.281 +        del self.session_db[xid]
   5.282 +        self.db.delete(xid)
   5.283  
   5.284 -    def migrate_ls(self):
   5.285 -        return self.migrate.keys()
   5.286 +    def session_ls(self):
   5.287 +        return self.session.keys()
   5.288  
   5.289 -    def migrates(self):
   5.290 -        return self.migrate.values()
   5.291 +    def sessions(self):
   5.292 +        return self.session.values()
   5.293  
   5.294 -    def migrate_get(self, id):
   5.295 -        return self.migrate.get(id)
   5.296 -    
   5.297 -    def migrate_begin(self, dom, host, port=XFRD_PORT):
   5.298 -        # Check dom for existence, not migrating already.
   5.299 -        # Subscribe to migrate notifications (for updating).
   5.300 -        id = self.nextid()
   5.301 -        info = XendMigrateInfo(id, dom, host, port)
   5.302 -        self._add_migrate(id, info)
   5.303 +    def session_get(self, xid):
   5.304 +        return self.session.get(xid)
   5.305 +
   5.306 +    def session_begin(self, info):
   5.307 +        self._add_session(info.xid, info)
   5.308          mcf = XfrdClientFactory(info)
   5.309          reactor.connectTCP('localhost', XFRD_PORT, mcf)
   5.310          return info
   5.311 +    
   5.312 +    def migrate_begin(self, dom, host, port=XFRD_PORT):
   5.313 +        """Begin to migrate a domain to another host.
   5.314 +
   5.315 +        @param dom:  domain
   5.316 +        @param host: destination host
   5.317 +        @param port: destination port
   5.318 +        @return: deferred
   5.319 +        """
   5.320 +        # Check dom for existence, not migrating already.
   5.321 +        # Subscribe to migrate notifications (for updating).
   5.322 +        xid = self.nextid()
   5.323 +        info = XendMigrateInfo(xid, dom, host, port)
   5.324 +        self.session_begin(info)
   5.325 +        return info.deferred
   5.326 +
   5.327 +    def save_begin(self, dom, file):
   5.328 +        """Begin saving a domain to file.
   5.329 +
   5.330 +        @param dom:  domain
   5.331 +        @param file: destination file
   5.332 +        @return: deferred
   5.333 +        """
   5.334 +        xid = self.nextid()
   5.335 +        info = XendSaveInfo(xid, dom, file)
   5.336 +        self.session_begin(info)
   5.337 +        return info.deferred
   5.338  
   5.339  def instance():
   5.340      global inst
     6.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Mon Jul 12 16:32:11 2004 +0000
     6.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Mon Jul 12 16:32:35 2004 +0000
     6.3 @@ -18,6 +18,14 @@ class SrvDomain(SrvDir):
     6.4          self.xd = XendDomain.instance()
     6.5          self.xconsole = XendConsole.instance()
     6.6  
     6.7 +    def op_configure(self, op, req):
     6.8 +        fn = FormFn(self.xd.domain_configure,
     6.9 +                    [['dom', 'int'],
    6.10 +                     ['config', 'sxp']])
    6.11 +        val = fn(req.args, {'dom': self.dom.id})
    6.12 +        #todo: may need to add ok and err callbacks.
    6.13 +        return val
    6.14 +
    6.15      def op_unpause(self, op, req):
    6.16          val = self.xd.domain_unpause(self.dom.id)
    6.17          return val
    6.18 @@ -27,7 +35,6 @@ class SrvDomain(SrvDir):
    6.19          return val
    6.20  
    6.21      def op_shutdown(self, op, req):
    6.22 -        #val = self.xd.domain_shutdown(self.dom.id)
    6.23          fn = FormFn(self.xd.domain_shutdown,
    6.24                      [['dom', 'int'],
    6.25                       ['reason', 'str']])
    6.26 @@ -202,8 +209,22 @@ class SrvDomain(SrvDir):
    6.27          req.write('<form method="post" action="%s">' % req.prePathURL())
    6.28          req.write('<input type="submit" name="op" value="unpause">')
    6.29          req.write('<input type="submit" name="op" value="pause">')
    6.30 +        req.write('<input type="submit" name="op" value="destroy">')
    6.31 +        req.write('</form>')
    6.32 +
    6.33 +        req.write('<form method="post" action="%s">' % req.prePathURL())
    6.34          req.write('<input type="submit" name="op" value="shutdown">')
    6.35 -        req.write('<input type="submit" name="op" value="destroy">')
    6.36 +        req.write('<input type="radio" name="reason" value="poweroff" checked>Poweroff<br>')
    6.37 +        req.write('<input type="radio" name="reason" value="halt">Halt<br>')
    6.38 +        req.write('<input type="radio" name="reason" value="reboot">Reboot<br>')
    6.39 +        req.write('</form>')
    6.40 +        
    6.41 +        req.write('<form method="post" action="%s">' % req.prePathURL())
    6.42 +        req.write('<br><input type="submit" name="op" value="save">')
    6.43 +        req.write('To file: <input type="text" name="file">')
    6.44 +        req.write('</form>')
    6.45 +        
    6.46 +        req.write('<form method="post" action="%s">' % req.prePathURL())
    6.47          req.write('<br><input type="submit" name="op" value="migrate">')
    6.48 -        req.write('To: <input type="text" name="destination">')
    6.49 +        req.write('To host: <input type="text" name="destination">')
    6.50          req.write('</form>')
     7.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Mon Jul 12 16:32:11 2004 +0000
     7.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Mon Jul 12 16:32:35 2004 +0000
     7.3 @@ -105,7 +105,10 @@ class SrvDomainDir(SrvDir):
     7.4  
     7.5      def op_restore(self, op, req):
     7.6          """Restore a domain from file.
     7.7 +
     7.8 +        @return: deferred
     7.9          """
    7.10 +        #todo: return is deferred. May need ok and err callbacks.
    7.11          fn = FormFn(self.xd.domain_restore,
    7.12                      [['file', 'str']])
    7.13          val = fn(req.args)
    7.14 @@ -154,9 +157,10 @@ class SrvDomainDir(SrvDir):
    7.15          req.write('<button type="submit" name="op" value="create">Create Domain</button>')
    7.16          req.write('Config <input type="file" name="config"><br>')
    7.17          req.write('</form>')
    7.18 +        
    7.19          req.write('<form method="post" action="%s" enctype="multipart/form-data">'
    7.20                    % req.prePathURL())
    7.21 -        req.write('<button type="submit" name="op" value="create">Restore Domain</button>')
    7.22 +        req.write('<button type="submit" name="op" value="restore">Restore Domain</button>')
    7.23          req.write('State <input type="string" name="state"><br>')
    7.24          req.write('</form>')
    7.25          
     8.1 --- a/tools/xfrd/Makefile	Mon Jul 12 16:32:11 2004 +0000
     8.2 +++ b/tools/xfrd/Makefile	Mon Jul 12 16:32:35 2004 +0000
     8.3 @@ -18,6 +18,9 @@ INCLUDES += -I $(XEN_LINUX_INCLUDE)
     8.4  vpath %.h      $(XEN_XU)
     8.5  INCLUDES += -I $(XEN_XU)
     8.6  
     8.7 +vpath %.h      $(XEN_LIBXC)
     8.8 +INCLUDES += -I $(XEN_LIBXC)
     8.9 +
    8.10  vpath %c       $(XEN_LIBXUTIL)
    8.11  INCLUDES += -I $(XEN_LIBXUTIL)
    8.12  
    8.13 @@ -28,7 +31,9 @@ UTIL_LIB_OBJ = $(UTIL_LIB_SRC:.c=.o)
    8.14  XFRD_PROG_OBJ = $(XFRD_PROG_SRC:.c=.o)
    8.15  XFRD_PROG_OBJ += $(UTIL_LIB)
    8.16  
    8.17 -CPPFLAGS += -D _XEN_XFR_STUB_
    8.18 +# Flag controlling whether to use stubs.
    8.19 +# Define to use stubs, undefine to use the real Xen functions.
    8.20 +#CPPFLAGS += -D _XEN_XFR_STUB_
    8.21  
    8.22  CFLAGS += -g
    8.23  CFLAGS += -Wall
    8.24 @@ -38,15 +43,31 @@ CFLAGS += $(INCLUDES)
    8.25  CFLAGS += -Wp,-MD,.$(@F).d
    8.26  PROG_DEP = .*.d
    8.27  
    8.28 -#LDFLAGS += -L $(COMPRESS_DIR) -lz
    8.29 +#$(warning XFRD_PROG_OBJ= $(XFRD_PROG_OBJ))
    8.30 +#$(warning UTIL_LIB= $(UTIL_LIB))
    8.31 +#$(warning UTIL_LIB_OBJ= $(UTIL_LIB_OBJ))
    8.32 +
    8.33 +# Libraries for xfrd.
    8.34 +XFRD_LIBS :=
    8.35 +
    8.36 +XFRD_LIBS += -L $(XEN_LIBXC) -lxc
    8.37 +XFRD_LIBS += -L $(XEN_LIBXUTIL) -lxutil
    8.38  
    8.39 -$(warning XFRD_PROG_OBJ= $(XFRD_PROG_OBJ))
    8.40 -$(warning UTIL_LIB= $(UTIL_LIB))
    8.41 -$(warning UTIL_LIB_OBJ= $(UTIL_LIB_OBJ))
    8.42 +# zlib library.
    8.43 +XFRD_LIBS += -lz
    8.44 +
    8.45 +CURL_FLAGS = $(shell curl-config --cflags)
    8.46 +CURL_LIBS  = $(shell curl-config --libs)
    8.47 +CFLAGS     += $(CURL_FLAGS)
    8.48 +# libcurl libraries.
    8.49 +XFRD_LIBS += $(CURL_LIBS)
    8.50 +
    8.51 +#$(warning XFRD_LIBS = $(XFRD_LIBS))
    8.52  
    8.53  all: xfrd
    8.54  
    8.55 -xfrd: $(XFRD_PROG_OBJ) -lz
    8.56 +xfrd: $(XFRD_PROG_OBJ)
    8.57 +	$(CC) -o $@ $^ $(XFRD_LIBS)
    8.58  
    8.59  .PHONY: install
    8.60  install: xfrd
    8.61 @@ -64,5 +85,6 @@ clean:
    8.62  	$(RM) *.o *.a *.so *~ xfrd
    8.63  	$(RM) $(PROG_DEP)
    8.64  
    8.65 +$(XFRD_PROG_OBJ): Makefile
    8.66  -include $(PROG_DEP)
    8.67  
     9.1 --- a/tools/xfrd/xen_domain.c	Mon Jul 12 16:32:11 2004 +0000
     9.2 +++ b/tools/xfrd/xen_domain.c	Mon Jul 12 16:32:35 2004 +0000
     9.3 @@ -3,18 +3,48 @@
     9.4  #include <stdio.h>
     9.5  
     9.6  #ifndef _XEN_XFR_STUB_
     9.7 -#include "dom0_defs.h"
     9.8 -#include "mem_defs.h"
     9.9 +#include "xc.h"
    9.10 +#include "xc_io.h"
    9.11  #endif
    9.12  
    9.13  #include "xen_domain.h"
    9.14  #include "marshal.h"
    9.15  #include "xdr.h"
    9.16 +#include "xfrd.h"
    9.17  
    9.18  #define MODULE_NAME "XFRD"
    9.19  #define DEBUG 1
    9.20  #include "debug.h"
    9.21  
    9.22 +#ifndef _XEN_XFR_STUB_
    9.23 +static int domain_suspend(u32 dom, void *data){
    9.24 +    int err = 0;
    9.25 +    Conn *xend = data;
    9.26 +
    9.27 +    dprintf("> dom=%lu data=%p\n", dom, data);
    9.28 +    err = xfr_vm_suspend(xend, dom);
    9.29 +    dprintf("< err=%d\n", err);
    9.30 +    return err;
    9.31 +}
    9.32 +
    9.33 +static int xc_handle = 0;
    9.34 +
    9.35 +int xcinit(void){
    9.36 +    if(xc_handle <= 0){
    9.37 +        xc_handle = xc_interface_open();
    9.38 +    }
    9.39 +    dprintf("< xc_handle=%d\n", xc_handle);
    9.40 +    return xc_handle;
    9.41 +}
    9.42 +
    9.43 +void xcfini(void){
    9.44 +    if(xc_handle > 0){
    9.45 +        xc_interface_close(xc_handle);
    9.46 +        xc_handle = 0;
    9.47 +    }
    9.48 +}
    9.49 +#endif   
    9.50 +
    9.51  /** Write domain state.
    9.52   *
    9.53   * At some point during this the domain is suspended, and then there's no way back.
    9.54 @@ -22,10 +52,10 @@
    9.55   */
    9.56  int xen_domain_snd(Conn *xend, IOStream *io, uint32_t dom, char *vmconfig, int vmconfig_n){
    9.57      int err = 0;
    9.58 +#ifdef _XEN_XFR_STUB_
    9.59      char buf[1024];
    9.60      int n, k, d, buf_n;
    9.61      dprintf("> dom=%d\n", dom);
    9.62 -#ifdef _XEN_XFR_STUB_
    9.63      err = marshal_uint32(io, dom);
    9.64      if(err) goto exit;
    9.65      err = marshal_string(io, vmconfig, vmconfig_n);
    9.66 @@ -41,8 +71,20 @@ int xen_domain_snd(Conn *xend, IOStream 
    9.67          dprintf("> k=%d n=%d\n", k, n);
    9.68      }
    9.69      
    9.70 +    dom = 99;
    9.71 +    err = xfr_vm_suspend(xend, dom);
    9.72    exit:
    9.73  #else 
    9.74 +    XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
    9.75 +    dprintf("> dom=%d\n", dom);
    9.76 +    ioctxt->domain = dom;
    9.77 +    ioctxt->io = io;
    9.78 +    ioctxt->info = iostdout;
    9.79 +    ioctxt->err = iostderr;
    9.80 +    ioctxt->data = xend;
    9.81 +    ioctxt->suspend = domain_suspend;
    9.82 +
    9.83 +    err = xc_linux_save(xcinit(), ioctxt);
    9.84  #endif   
    9.85      dprintf("< err=%d\n", err);
    9.86      return err;
    9.87 @@ -53,10 +95,10 @@ int xen_domain_snd(Conn *xend, IOStream 
    9.88   */
    9.89  int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n){
    9.90      int err = 0;
    9.91 +#ifdef _XEN_XFR_STUB_
    9.92      char buf[1024];
    9.93      int n, k, d, buf_n;
    9.94      dprintf(">\n");
    9.95 -#ifdef _XEN_XFR_STUB_
    9.96      err = unmarshal_uint32(io, dom);
    9.97      if(err) goto exit;
    9.98      err = unmarshal_new_string(io, vmconfig, vmconfig_n);
    9.99 @@ -72,19 +114,104 @@ int xen_domain_rcv(IOStream *io, uint32_
   9.100      }
   9.101    exit:
   9.102  #else    
   9.103 +    XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
   9.104 +    dprintf(">\n");
   9.105 +    ioctxt->io = io;
   9.106 +    ioctxt->info = iostdout;
   9.107 +    ioctxt->err = iostderr;
   9.108 +
   9.109 +    err = xc_linux_restore(xcinit(), ioctxt);
   9.110  #endif   
   9.111      dprintf("< err=%d\n", err);
   9.112      return err;
   9.113  }
   9.114  
   9.115 -/** Configure a new domain. Talk to xend. Use libcurl?
   9.116 +#include <curl/curl.h>
   9.117 +
   9.118 +static int do_curl_global_init = 1;
   9.119 +
   9.120 +static CURL *curlinit(void){
   9.121 +    if(do_curl_global_init){
   9.122 +        do_curl_global_init = 0;
   9.123 +        curl_global_init(CURL_GLOBAL_ALL);
   9.124 +    }
   9.125 +    return curl_easy_init();
   9.126 +}
   9.127 +
   9.128 +/** Configure a new domain. Talk to xend using libcurl.
   9.129   */
   9.130  int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){
   9.131      int err = 0;
   9.132 -    dprintf(">\n");
   9.133 +    CURL *curl = NULL;
   9.134 +    CURLcode curlcode = 0;
   9.135 +    char domainurl[128] = {};
   9.136 +    int domainurl_n = sizeof(domainurl) - 1;
   9.137 +    int n;
   9.138 +    struct curl_httppost *form = NULL, *last = NULL;
   9.139 +    CURLFORMcode formcode = 0;
   9.140 +
   9.141 +    dprintf("> dom=%u\n", dom);
   9.142 +    curl = curlinit();
   9.143 +    if(!curl){
   9.144 +        eprintf("> Could not init libcurl\n");
   9.145 +        err = -ENOMEM;
   9.146 +        goto exit;
   9.147 +    }
   9.148 +    n = snprintf(domainurl, domainurl_n,
   9.149 +                 "http://localhost:%d/xend/domain/%u", XEND_PORT, dom);
   9.150 +    if(n <= 0 || n >= domainurl_n){
   9.151 +        err = -ENOMEM;
   9.152 +        eprintf("Out of memory in url.\n");
   9.153 +        goto exit;
   9.154 +    }
   9.155 +    // Config field - set from vmconfig.
   9.156 +    formcode = curl_formadd(&form, &last,
   9.157 +                            CURLFORM_COPYNAME,     "config",
   9.158 +                            CURLFORM_BUFFER,       "config",
   9.159 +                            CURLFORM_BUFFERPTR,    vmconfig,
   9.160 +                            CURLFORM_BUFFERLENGTH, vmconfig_n,
   9.161 +                            CURLFORM_CONTENTTYPE,  "application/octet-stream",
   9.162 +                            CURLFORM_END);
   9.163 +    if(formcode){
   9.164 +        eprintf("> Error adding config field.\n");
   9.165 +        goto exit;
   9.166 +    }
   9.167 +    // Op field.
   9.168 +    formcode = curl_formadd(&form, &last,
   9.169 +                            CURLFORM_COPYNAME,     "op",
   9.170 +                            CURLFORM_COPYCONTENTS, "configure",
   9.171 +                            CURLFORM_END);
   9.172 +
   9.173 +    if(formcode){
   9.174 +        eprintf("> Error adding op field.\n");
   9.175 +        goto exit;
   9.176 +    }
   9.177 +    // No progress meter.
   9.178 +    //curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
   9.179 +    // Completely quiet.
   9.180 +    //curl_easy_setopt(curl, CURLOPT_MUTE, 1);
   9.181 +    // Set the URL.
   9.182 +    curl_easy_setopt(curl, CURLOPT_URL, domainurl);
   9.183 +    // POST the form.
   9.184 +    curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
   9.185 +    dprintf("> curl perform...\n");
   9.186  #ifdef _XEN_XFR_STUB_
   9.187 -#else    
   9.188 -#endif   
   9.189 +    dprintf("> _XEN_XFR_STUB_ defined - not calling xend\n");
   9.190 +    curlcode = 0;
   9.191 +#else
   9.192 +    curlcode = curl_easy_perform(curl);
   9.193 +#endif
   9.194 +  exit:
   9.195 +    if(curl) curl_easy_cleanup(curl);
   9.196 +    if(form) curl_formfree(form);
   9.197 +    if(formcode){
   9.198 +        dprintf("> formcode=%d\n", formcode);
   9.199 +        err = -EINVAL;
   9.200 +    }
   9.201 +    if(curlcode){
   9.202 +        dprintf("> curlcode=%d\n", curlcode);
   9.203 +        err = -EINVAL;
   9.204 +    }
   9.205      dprintf("< err=%d\n", err);
   9.206      return err;
   9.207  }
    10.1 --- a/tools/xfrd/xfrd.c	Mon Jul 12 16:32:11 2004 +0000
    10.2 +++ b/tools/xfrd/xfrd.c	Mon Jul 12 16:32:35 2004 +0000
    10.3 @@ -93,22 +93,26 @@ Sxpr oxfr_configure; // (xfr.configure <
    10.4  Sxpr oxfr_err;       // (xfr.err <code>)
    10.5  Sxpr oxfr_hello;     // (xfr.hello <major> <minor>)
    10.6  Sxpr oxfr_migrate;   // (xfr.migrate <vmid> <vmconfig> <host> <port>)
    10.7 -Sxpr oxfr_ok;        // (xfr.ok <value>)
    10.8 +Sxpr oxfr_migrate_ok;// (xfr.migrate.ok <value>)
    10.9  Sxpr oxfr_progress;  // (xfr.progress <percent> <rate: kb/s>)
   10.10  Sxpr oxfr_save;      // (xfr.save <vmid> <vmconfig> <file>)
   10.11 -Sxpr oxfr_suspend;   // (xfr.suspend <vmid>)
   10.12 +Sxpr oxfr_save_ok;   // (xfr.save.ok)
   10.13 +Sxpr oxfr_vm_suspend;// (xfr.vm.suspend <vmid>)
   10.14  Sxpr oxfr_xfr;       // (xfr.xfr <vmid>)
   10.15 +Sxpr oxfr_xfr_ok;    // (xfr.xfr.ok <vmid>)
   10.16  
   10.17  void xfr_init(void){
   10.18 -    oxfr_configure = intern("xfr.configure");
   10.19 -    oxfr_err       = intern("xfr.err");
   10.20 -    oxfr_hello     = intern("xfr.hello");
   10.21 -    oxfr_migrate   = intern("xfr.migrate");
   10.22 -    oxfr_ok        = intern("xfr.ok");
   10.23 -    oxfr_progress  = intern("xfr.progress");
   10.24 -    oxfr_save      = intern("xfr.save");
   10.25 -    oxfr_suspend   = intern("xfr.suspend");
   10.26 -    oxfr_xfr       = intern("xfr.xfr");
   10.27 +    oxfr_configure      = intern("xfr.configure");
   10.28 +    oxfr_err            = intern("xfr.err");
   10.29 +    oxfr_hello          = intern("xfr.hello");
   10.30 +    oxfr_migrate        = intern("xfr.migrate");
   10.31 +    oxfr_migrate_ok     = intern("xfr.migrate.ok");
   10.32 +    oxfr_progress       = intern("xfr.progress");
   10.33 +    oxfr_save           = intern("xfr.save");
   10.34 +    oxfr_save_ok        = intern("xfr.save.ok");
   10.35 +    oxfr_vm_suspend     = intern("xfr.vm.suspend");
   10.36 +    oxfr_xfr            = intern("xfr.xfr");
   10.37 +    oxfr_xfr_ok         = intern("xfr.xfr.ok");
   10.38  }
   10.39  
   10.40  #ifndef TRUE
   10.41 @@ -518,11 +522,27 @@ int xfr_send_xfr(Conn *conn, uint32_t vm
   10.42      return (err < 0 ? err : 0);
   10.43  }
   10.44  
   10.45 -int xfr_send_ok(Conn *conn, uint32_t vmid){
   10.46 +int xfr_send_xfr_ok(Conn *conn, uint32_t vmid){
   10.47      int err = 0;
   10.48  
   10.49      err = IOStream_print(conn->out, "(%s %d)",
   10.50 -                         atom_name(oxfr_ok), vmid);
   10.51 +                         atom_name(oxfr_xfr_ok), vmid);
   10.52 +    return (err < 0 ? err : 0);
   10.53 +}
   10.54 +
   10.55 +int xfr_send_migrate_ok(Conn *conn, uint32_t vmid){
   10.56 +    int err = 0;
   10.57 +
   10.58 +    err = IOStream_print(conn->out, "(%s %d)",
   10.59 +                         atom_name(oxfr_migrate_ok), vmid);
   10.60 +    return (err < 0 ? err : 0);
   10.61 +}
   10.62 +
   10.63 +int xfr_send_save_ok(Conn *conn){
   10.64 +    int err = 0;
   10.65 +
   10.66 +    err = IOStream_print(conn->out, "(%s)",
   10.67 +                         atom_name(oxfr_save_ok));
   10.68      return (err < 0 ? err : 0);
   10.69  }
   10.70  
   10.71 @@ -530,10 +550,24 @@ int xfr_send_suspend(Conn *conn, uint32_
   10.72      int err = 0;
   10.73  
   10.74      err = IOStream_print(conn->out, "(%s %d)",
   10.75 -                         atom_name(oxfr_suspend), vmid);
   10.76 +                         atom_name(oxfr_vm_suspend), vmid);
   10.77      return (err < 0 ? err : 0);
   10.78  }
   10.79  
   10.80 +/** Suspend a vm on behalf of save/migrate.
   10.81 + */
   10.82 +int xfr_vm_suspend(Conn *xend, uint32_t vmid){
   10.83 +    int err = 0;
   10.84 +    dprintf("> vmid=%u\n", vmid);
   10.85 +    err = xfr_send_suspend(xend, vmid);
   10.86 +    if(err) goto exit;
   10.87 +    IOStream_flush(xend->out);
   10.88 +    err = xfr_response(xend);
   10.89 +  exit:
   10.90 +    dprintf("< err=%d\n", err);
   10.91 +    return err;
   10.92 +}
   10.93 +
   10.94  /** Get vm state. Send transfer message.
   10.95   *
   10.96   * @param peer connection
   10.97 @@ -561,7 +595,7 @@ int xfr_send_state(XfrState *state, Conn
   10.98          int errcode;
   10.99          err = intof(sxpr_childN(sxpr, 0, ONONE), &errcode);
  10.100          if(!err) err = errcode;
  10.101 -    } else if(sxpr_elementp(sxpr, oxfr_ok)){
  10.102 +    } else if(sxpr_elementp(sxpr, oxfr_xfr_ok)){
  10.103          // Ok - get the new domain id.
  10.104          err = intof(sxpr_childN(sxpr, 0, ONONE), &state->vmid_new);
  10.105          xfr_error(peer, err);
  10.106 @@ -592,7 +626,7 @@ int xfr_send_done(XfrState *state, Conn 
  10.107          err = xfr_error(xend, first_err);
  10.108      } else {
  10.109          // Report new domain id to xend.
  10.110 -        err = xfr_send_ok(xend, state->vmid_new);
  10.111 +        err = xfr_send_migrate_ok(xend, state->vmid_new);
  10.112      }  
  10.113  
  10.114      XfrState_set_err(state, err);
  10.115 @@ -677,17 +711,25 @@ int xfr_save(Args *args, XfrState *state
  10.116      int err = 0;
  10.117      IOStream *io = NULL;
  10.118  
  10.119 +    dprintf("> file=%s\n", file);
  10.120      io = file_stream_fopen(file, "wb");
  10.121      if(!io){
  10.122 +        dprintf("> Failed to open %s\n", file);
  10.123          err = -EIO;
  10.124          goto exit;
  10.125      }
  10.126      err = xen_domain_snd(xend, io, state->vmid, state->vmconfig, state->vmconfig_n);
  10.127 +    if(err){
  10.128 +        err = xfr_error(xend, err);
  10.129 +    } else {
  10.130 +        err = xfr_send_save_ok(xend);
  10.131 +    }
  10.132    exit:
  10.133      if(io){
  10.134          IOStream_close(io);
  10.135          IOStream_free(io);
  10.136      }
  10.137 +    dprintf("< err=%d\n", err);
  10.138      return err;
  10.139  }
  10.140  
  10.141 @@ -709,7 +751,7 @@ int xfr_recv(Args *args, XfrState *state
  10.142      if(err) goto exit;
  10.143  
  10.144      // Report new domain id to peer.
  10.145 -    err = xfr_send_ok(peer, state->vmid_new);
  10.146 +    err = xfr_send_xfr_ok(peer, state->vmid_new);
  10.147      if(err) goto exit;
  10.148      // Get the final ok.
  10.149      err = xfr_response(peer);
    11.1 --- a/tools/xfrd/xfrd.h	Mon Jul 12 16:32:11 2004 +0000
    11.2 +++ b/tools/xfrd/xfrd.h	Mon Jul 12 16:32:35 2004 +0000
    11.3 @@ -2,7 +2,7 @@
    11.4  #define _XFRD_XFRD_H_
    11.5  
    11.6  /** Xend port in host order. */
    11.7 -#define XEND_PORT 8001
    11.8 +#define XEND_PORT 8000
    11.9  
   11.10  /** Xfrd port in host order. */
   11.11  #define XFRD_PORT 8002
   11.12 @@ -11,4 +11,6 @@
   11.13  #define XFR_PROTO_MAJOR   1
   11.14  #define XFR_PROTO_MINOR   0
   11.15  
   11.16 +struct Conn;
   11.17 +extern int xfr_vm_suspend(struct Conn *xend, uint32_t vmid);
   11.18  #endif