ia64/xen-unstable

changeset 2574:a15ab016f0c6

bitkeeper revision 1.1159.96.3 (415c16a40z3XgMlliaGAnrifiHmpNg)

Move the configuration step for a restored/received domain so that it
is as early as possible in the domain construction process.
Change domain restore to use xfrd to avoid blocking and double
configuration.
author mjw@wray-m-3.hpl.hp.com
date Thu Sep 30 14:22:28 2004 +0000 (2004-09-30)
parents 3af1c3b54760
children 05ae99de2d3f
files tools/libxc/xc.h tools/libxc/xc_linux_restore.c tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendMigrate.py tools/xfrd/xen_domain.c tools/xfrd/xen_domain.h tools/xfrd/xfrd.c
line diff
     1.1 --- a/tools/libxc/xc.h	Thu Sep 30 11:26:11 2004 +0000
     1.2 +++ b/tools/libxc/xc.h	Thu Sep 30 14:22:28 2004 +0000
     1.3 @@ -75,9 +75,10 @@ int xc_shadow_control(int xc_handle,
     1.4                        xc_shadow_control_stats_t *stats);
     1.5  
     1.6  
     1.7 -#define XCFLAGS_VERBOSE 1
     1.8 -#define XCFLAGS_LIVE    2
     1.9 -#define XCFLAGS_DEBUG   4
    1.10 +#define XCFLAGS_VERBOSE   1
    1.11 +#define XCFLAGS_LIVE      2
    1.12 +#define XCFLAGS_DEBUG     4
    1.13 +#define XCFLAGS_CONFIGURE 8
    1.14  
    1.15  struct XcIOContext;
    1.16  int xc_linux_save(int xc_handle, struct XcIOContext *ioctxt);
     2.1 --- a/tools/libxc/xc_linux_restore.c	Thu Sep 30 11:26:11 2004 +0000
     2.2 +++ b/tools/libxc/xc_linux_restore.c	Thu Sep 30 14:22:28 2004 +0000
     2.3 @@ -245,6 +245,15 @@ int xc_linux_restore(int xc_handle, XcIO
     2.4      }
     2.5      shared_info_frame = op.u.getdomaininfo.shared_info_frame;
     2.6  
     2.7 +    if(ioctxt->flags & XCFLAGS_CONFIGURE)
     2.8 +    {
     2.9 +        if(xcio_configure_domain(ioctxt))
    2.10 +        {
    2.11 +           xcio_error(ioctxt, "Configuring domain failed"); 
    2.12 +           goto out;
    2.13 +        }
    2.14 +    }
    2.15 +
    2.16      if ( (pm_handle = init_pfn_mapper((domid_t)dom)) == NULL )
    2.17          goto out;
    2.18  
     3.1 --- a/tools/python/xen/xend/XendDomain.py	Thu Sep 30 11:26:11 2004 +0000
     3.2 +++ b/tools/python/xen/xend/XendDomain.py	Thu Sep 30 14:22:28 2004 +0000
     3.3 @@ -211,9 +211,9 @@ class XendDomain:
     3.4          @param id:     domain id
     3.5          @param notify: send a domain died event if true
     3.6          """
     3.7 -        for info in self.domain_by_name.values():
     3.8 +        for (k, info) in self.domain_by_name.items():
     3.9              if info.id == id:
    3.10 -                del self.domain_by_name[info.name]
    3.11 +                del self.domain_by_name[k]
    3.12          if id in self.domain_by_id:
    3.13              info = self.domain_by_id[id]
    3.14              del self.domain_by_id[id]
    3.15 @@ -408,11 +408,15 @@ class XendDomain:
    3.16          @return: deferred
    3.17          """
    3.18          
    3.19 -        def cbok(dominfo):
    3.20 -            self._add_domain(dominfo)
    3.21 -            return dominfo
    3.22 -        deferred = XendDomainInfo.vm_restore(src, progress=progress)
    3.23 -        deferred.addCallback(cbok)
    3.24 +        if 0:
    3.25 +            def cbok(dominfo):
    3.26 +                self._add_domain(dominfo)
    3.27 +                return dominfo
    3.28 +            deferred = XendDomainInfo.vm_restore(src, progress=progress)
    3.29 +            deferred.addCallback(cbok)
    3.30 +        else:
    3.31 +            xmigrate = XendMigrate.instance()
    3.32 +            deferred = xmigrate.restore_begin(src)
    3.33          return deferred
    3.34      
    3.35      def domain_get(self, id):
     4.1 --- a/tools/python/xen/xend/XendMigrate.py	Thu Sep 30 11:26:11 2004 +0000
     4.2 +++ b/tools/python/xen/xend/XendMigrate.py	Thu Sep 30 14:22:28 2004 +0000
     4.3 @@ -295,11 +295,6 @@ class XendMigrateInfo(XfrdInfo):
     4.4          eserver.inject('xend.domain.migrate',
     4.5                         [ self.dominfo.name, self.dominfo.id,
     4.6                           "begin", self.sxpr() ])
     4.7 -        # Special case for localhost: destroy all devices early.
     4.8 -        if 0 and self.dst_host in ["localhost", "127.0.0.1"]:
     4.9 -            self.dominfo.restart_cancel()
    4.10 -            self.dominfo.cleanup()
    4.11 -            #self.dominfo.destroy_console()
    4.12          xfrd.request(['xfr.migrate',
    4.13                        self.src_dom,
    4.14                        vmconfig,
    4.15 @@ -307,6 +302,19 @@ class XendMigrateInfo(XfrdInfo):
    4.16                        self.dst_port,
    4.17                        self.live ])
    4.18          
    4.19 +    def xfr_vm_suspend(self, xfrd, val):
    4.20 +        def cbok(val):
    4.21 +            # Special case for localhost: destroy devices early.
    4.22 +            if self.dst_host in ["localhost", "127.0.0.1"]:
    4.23 +                self.dominfo.restart_cancel()
    4.24 +                self.dominfo.cleanup()
    4.25 +                self.dominfo.destroy_console()
    4.26 +            return val
    4.27 +            
    4.28 +        d = XfrdInfo.xfr_vm_suspend(self, xfrd, val)
    4.29 +        d.addCallback(cbok)
    4.30 +        return d
    4.31 +    
    4.32      def xfr_migrate_ok(self, xfrd, val):
    4.33          dom = int(sxp.child0(val))
    4.34          self.state = 'ok'
    4.35 @@ -381,7 +389,35 @@ class XendSaveInfo(XfrdInfo):
    4.36                         [ self.dominfo.name, self.dominfo.id,
    4.37                           self.state, self.sxpr() ])
    4.38      
    4.39 +class XendRestoreInfo(XfrdInfo):
    4.40 +    """Representation of a restore in-progress and its interaction with xfrd.
    4.41 +    """
    4.42  
    4.43 +    def __init__(self, xid, file):
    4.44 +        XfrdInfo.__init__(self)
    4.45 +        self.xid = xid
    4.46 +        self.state = 'begin'
    4.47 +        self.file = file
    4.48 +
    4.49 +    def sxpr(self):
    4.50 +         sxpr = ['restore',
    4.51 +                 ['id', self.xid],
    4.52 +                 ['file', self.file] ]
    4.53 +         return sxpr
    4.54 +
    4.55 +    def request(self, xfrd):
    4.56 +        print '***request>', self.file
    4.57 +        log.info('restore BEGIN: ' + str(self.sxpr()))
    4.58 +        xfrd.request(['xfr.restore', self.file ])
    4.59 +        
    4.60 +    def xfr_restore_ok(self, xfrd, val):
    4.61 +        dom = int(sxp.child0(val))
    4.62 +        dominfo = self.xd.domain_get(dom)
    4.63 +        self.state = 'ok'
    4.64 +        if not self.deferred.called:
    4.65 +            self.deferred.callback(dominfo)
    4.66 +
    4.67 +         
    4.68  class XendMigrate:
    4.69      """External api for interaction with xfrd for migrate and save.
    4.70      Singleton.
    4.71 @@ -477,6 +513,12 @@ class XendMigrate:
    4.72          info = XendSaveInfo(xid, dominfo, file)
    4.73          return self.session_begin(info)
    4.74  
    4.75 +    def restore_begin(self, file):
    4.76 +        xid = self.nextid()
    4.77 +        info = XendRestoreInfo(xid, file)
    4.78 +        return self.session_begin(info)
    4.79 +        
    4.80 +
    4.81  def instance():
    4.82      global inst
    4.83      try:
     5.1 --- a/tools/xfrd/xen_domain.c	Thu Sep 30 11:26:11 2004 +0000
     5.2 +++ b/tools/xfrd/xen_domain.c	Thu Sep 30 14:22:28 2004 +0000
     5.3 @@ -108,7 +108,10 @@ int xen_domain_snd(Conn *xend, IOStream 
     5.4  /** Receive domain state.
     5.5   * Create a new domain and store the received state into it.
     5.6   */
     5.7 -int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n){
     5.8 +int xen_domain_rcv(IOStream *io,
     5.9 +                   uint32_t *dom,
    5.10 +                   char **vmconfig, int *vmconfig_n,
    5.11 +                   int *configured){
    5.12      int err = 0;
    5.13  #ifdef _XEN_XFR_STUB_
    5.14      char buf[1024];
    5.15 @@ -135,11 +138,13 @@ int xen_domain_rcv(IOStream *io, uint32_
    5.16      ioctxt->info = iostdout;
    5.17      ioctxt->err = iostderr;
    5.18      ioctxt->configure = domain_configure;
    5.19 +    ioctxt->flags |= XCFLAGS_CONFIGURE;
    5.20  
    5.21      err = xc_linux_restore(xcinit(), ioctxt);
    5.22      *dom = ioctxt->domain;
    5.23      *vmconfig = ioctxt->vmconfig;
    5.24      *vmconfig_n = ioctxt->vmconfig_n;
    5.25 +    *configured = (ioctxt->flags & XCFLAGS_CONFIGURE);
    5.26  #endif   
    5.27      dprintf("< err=%d\n", err);
    5.28      return err;
     6.1 --- a/tools/xfrd/xen_domain.h	Thu Sep 30 11:26:11 2004 +0000
     6.2 +++ b/tools/xfrd/xen_domain.h	Thu Sep 30 14:22:28 2004 +0000
     6.3 @@ -11,7 +11,10 @@ extern int xen_domain_snd(Conn *xend, IO
     6.4                            uint32_t dom,
     6.5                            char *vmconfig, int vmconfig_n,
     6.6                            int live);
     6.7 -extern int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n);
     6.8 +extern int xen_domain_rcv(IOStream *io,
     6.9 +                          uint32_t *dom,
    6.10 +                          char **vmconfig, int *vmconfig_n,
    6.11 +                          int *configured);
    6.12  
    6.13  
    6.14  extern int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n);
     7.1 --- a/tools/xfrd/xfrd.c	Thu Sep 30 11:26:11 2004 +0000
     7.2 +++ b/tools/xfrd/xfrd.c	Thu Sep 30 14:22:28 2004 +0000
     7.3 @@ -99,6 +99,8 @@ Sxpr oxfr_hello;     // (xfr.hello <majo
     7.4  Sxpr oxfr_migrate;   // (xfr.migrate <vmid> <vmconfig> <host> <port> <live>)
     7.5  Sxpr oxfr_migrate_ok;// (xfr.migrate.ok <value>)
     7.6  Sxpr oxfr_progress;  // (xfr.progress <percent> <rate: kb/s>)
     7.7 +Sxpr oxfr_restore;   // (xfr.restore <file>)
     7.8 +Sxpr oxfr_restore_ok;// (xfr.restore.ok <vmid>)
     7.9  Sxpr oxfr_save;      // (xfr.save <vmid> <vmconfig> <file>)
    7.10  Sxpr oxfr_save_ok;   // (xfr.save.ok)
    7.11  Sxpr oxfr_vm_destroy;// (xfr.vm.destroy <vmid>)
    7.12 @@ -113,6 +115,8 @@ void xfr_init(void){
    7.13      oxfr_migrate        = intern("xfr.migrate");
    7.14      oxfr_migrate_ok     = intern("xfr.migrate.ok");
    7.15      oxfr_progress       = intern("xfr.progress");
    7.16 +    oxfr_restore        = intern("xfr.restore");
    7.17 +    oxfr_restore_ok     = intern("xfr.restore.ok");
    7.18      oxfr_save           = intern("xfr.save");
    7.19      oxfr_save_ok        = intern("xfr.save.ok");
    7.20      oxfr_vm_destroy     = intern("xfr.vm.destroy");
    7.21 @@ -540,6 +544,14 @@ int xfr_send_migrate_ok(Conn *conn, uint
    7.22      return (err < 0 ? err : 0);
    7.23  }
    7.24  
    7.25 +int xfr_send_restore_ok(Conn *conn, uint32_t vmid){
    7.26 +    int err = 0;
    7.27 +
    7.28 +    err = IOStream_print(conn->out, "(%s %d)",
    7.29 +                         atom_name(oxfr_restore_ok), vmid);
    7.30 +    return (err < 0 ? err : 0);
    7.31 +}
    7.32 +
    7.33  int xfr_send_save_ok(Conn *conn){
    7.34      int err = 0;
    7.35  
    7.36 @@ -777,6 +789,46 @@ int xfr_save(Args *args, XfrState *state
    7.37      return err;
    7.38  }
    7.39  
    7.40 +/** Restore a vm from file.
    7.41 + *
    7.42 + * @return 0 on success, error code otherwise
    7.43 + */
    7.44 +int xfr_restore(Args *args, XfrState *state, Conn *xend, char *file){
    7.45 +    int err = 0;
    7.46 +    IOStream *io = NULL;
    7.47 +    int configured=0;
    7.48 +
    7.49 +    dprintf("> file=%s\n", file);
    7.50 +    io = gzip_stream_fopen(file, "rb");
    7.51 +    if(!io){
    7.52 +        eprintf("> Failed to open %s\n", file);
    7.53 +        err = -EINVAL;
    7.54 +        goto exit;
    7.55 +    }
    7.56 +    err = xen_domain_rcv(io,
    7.57 +                         &state->vmid_new,
    7.58 +                         &state->vmconfig, &state->vmconfig_n,
    7.59 +                         &configured);
    7.60 +    if(err) goto exit;
    7.61 +    if(!configured){
    7.62 +        err = xen_domain_configure(state->vmid_new, state->vmconfig, state->vmconfig_n);
    7.63 +        if(err) goto exit;
    7.64 +    }
    7.65 +    err = xen_domain_unpause(state->vmid_new);
    7.66 +  exit:
    7.67 +    if(io){
    7.68 +        IOStream_close(io);
    7.69 +        IOStream_free(io);
    7.70 +    }
    7.71 +    if(err){
    7.72 +        xfr_error(xend, err);
    7.73 +    } else {
    7.74 +        xfr_send_restore_ok(xend, state->vmid_new);
    7.75 +    }
    7.76 +    dprintf("< err=%d\n", err);
    7.77 +    return err;
    7.78 +}
    7.79 +
    7.80  /** Accept the transfer of a vm from another node.
    7.81   *
    7.82   * @param peer connection
    7.83 @@ -787,17 +839,23 @@ int xfr_recv(Args *args, XfrState *state
    7.84      int err = 0;
    7.85      time_t t0 = time(NULL), t1;
    7.86      Sxpr sxpr;
    7.87 +    int configured=0;
    7.88  
    7.89      dprintf(">\n");
    7.90 -    err = xen_domain_rcv(peer->in, &state->vmid_new, &state->vmconfig, &state->vmconfig_n);
    7.91 +    err = xen_domain_rcv(peer->in,
    7.92 +                         &state->vmid_new,
    7.93 +                         &state->vmconfig, &state->vmconfig_n,
    7.94 +                         &configured);
    7.95      if(err) goto exit;
    7.96      // Read from the peer. This is just so we wait before configuring.
    7.97      // When migrating to the same host the peer must destroy the domain
    7.98      // before we configure the new one.
    7.99      err = Conn_sxpr(peer, &sxpr);
   7.100      if(err) goto exit;
   7.101 -    err = xen_domain_configure(state->vmid_new, state->vmconfig, state->vmconfig_n);
   7.102 -    if(err) goto exit;
   7.103 +    if(!configured){
   7.104 +        err = xen_domain_configure(state->vmid_new, state->vmconfig, state->vmconfig_n);
   7.105 +        if(err) goto exit;
   7.106 +    }
   7.107      err = xen_domain_unpause(state->vmid_new);
   7.108      if(err) goto exit;
   7.109      // Report new domain id to peer.
   7.110 @@ -878,6 +936,17 @@ int xfrd_service(Args *args, int peersoc
   7.111          if(err) goto exit;
   7.112          err = xfr_save(args, state, conn, file);
   7.113  
   7.114 +    } else if(sxpr_elementp(sxpr, oxfr_restore)){
   7.115 +        // Restore message from xend.
   7.116 +        char *file;
   7.117 +        XfrState _state = {}, *state = &_state;
   7.118 +        int n = 0;
   7.119 +
   7.120 +        dprintf("> xfr.restore\n");
   7.121 +        err = stringof(sxpr_childN(sxpr, n++, ONONE), &file);
   7.122 +        if(err) goto exit;
   7.123 +        err = xfr_restore(args, state, conn, file);
   7.124 +
   7.125      } else if(sxpr_elementp(sxpr, oxfr_xfr)){
   7.126          // Xfr message from peer xfrd.
   7.127          XfrState _state = {}, *state = &_state;