direct-io.hg

changeset 7423:8dbf531776e1

Take advantage of the new UUID (handle) stored for us in Xen to improve the
recreation semantics.

Remove the unpause at the end of xc_linux_restore, and move it to
XendDomainInfo. This is necessary because xenstored now allocates the domain
path when the domain is introduced, which means that the new domain cannot
start running until that introduce is performed and the new devices
configured.

Give restore a separate completion phase in which domain details are stored.
This is required because the domain path is no longer available until after
the introduceDomain call.

TODO: Split the domain introduction into two so that the domain path is
available earlier. At the moment, the domain <-> store channel details are
passed in to xenstored when the domain is introduced, but in the case of
restore it is necessary to wait until the restore is completed before the
channel MFN is available.

Change the interface between XendDomainInfo and XendCheckpoint/image to not
have hideous callbacks through setConsoleRef and setStoreRef. Instead,
image.createImage explicitly returns those values, and XendCheckpoint passes
them through to completeRestore.

Move the purging of the domain path corresponding to a new domain from Xend
to xenstored, since xenstored is now in charge of this path. With the domain
path creation moved to xenstored, Xend cannot remove the path, because watches
may have fired on it already.

Fix the printf statement in xenstored in verbose mode that details the
messages being written. This statement was printing the buffer using %s, but
this buffer has an explicit length field, so we were seeing garbage after the
correct details.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Wed Oct 19 11:47:51 2005 +0100 (2005-10-19)
parents 4dd58ef39639
children 9b18b85e0146
files tools/libxc/xc_linux_restore.c tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/xenstore/xenstored_core.c tools/xenstore/xenstored_core.h tools/xenstore/xenstored_domain.c
line diff
     1.1 --- a/tools/libxc/xc_linux_restore.c	Wed Oct 19 07:43:03 2005 +0100
     1.2 +++ b/tools/libxc/xc_linux_restore.c	Wed Oct 19 11:47:51 2005 +0100
     1.3 @@ -642,16 +642,6 @@ int xc_linux_restore(int xc_handle, int 
     1.4          goto out;
     1.5      }
     1.6  
     1.7 -    DPRINTF("Domain ready to be unpaused\n");
     1.8 -    op.cmd = DOM0_UNPAUSEDOMAIN;
     1.9 -    op.u.unpausedomain.domain = (domid_t)dom;
    1.10 -    rc = xc_dom0_op(xc_handle, &op);
    1.11 -    if (rc == 0) {
    1.12 -        /* Success: print the domain id. */
    1.13 -        DPRINTF("DOM=%u\n", dom);
    1.14 -        return 0;
    1.15 -    }
    1.16 -
    1.17   out:
    1.18      if ( (rc != 0) && (dom != 0) )
    1.19          xc_domain_destroy(xc_handle, dom);
     2.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Wed Oct 19 07:43:03 2005 +0100
     2.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Wed Oct 19 11:47:51 2005 +0100
     2.3 @@ -118,9 +118,11 @@ def restore(xd, fd):
     2.4  
     2.5      dominfo = xd.restore_(vmconfig)
     2.6  
     2.7 -    assert dominfo.store_channel
     2.8 -    assert dominfo.console_channel
     2.9 -    assert dominfo.getDomainPath()
    2.10 +    store_port   = dominfo.getStorePort()
    2.11 +    console_port = dominfo.getConsolePort()
    2.12 +
    2.13 +    assert store_port
    2.14 +    assert console_port
    2.15  
    2.16      try:
    2.17          l = read_exact(fd, sizeof_unsigned_long,
    2.18 @@ -130,32 +132,19 @@ def restore(xd, fd):
    2.19              raise XendError(
    2.20                  "not a valid guest state file: pfn count out of range")
    2.21  
    2.22 -        store_evtchn = dominfo.store_channel
    2.23 -        console_evtchn = dominfo.console_channel
    2.24 -
    2.25 -        cmd = [xen.util.auxbin.pathTo(XC_RESTORE), str(xc.handle()), str(fd),
    2.26 -               str(dominfo.getDomid()), str(nr_pfns),
    2.27 -               str(store_evtchn), str(console_evtchn)]
    2.28 +        cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
    2.29 +                        xc.handle(), fd, dominfo.getDomid(), nr_pfns,
    2.30 +                        store_port, console_port])
    2.31          log.debug("[xc_restore]: %s", string.join(cmd))
    2.32  
    2.33 -        def restoreInputHandler(line, _):
    2.34 -            m = re.match(r"^(store-mfn) (\d+)$", line)
    2.35 -            if m:
    2.36 -                store_mfn = int(m.group(2))
    2.37 -                dominfo.setStoreRef(store_mfn)
    2.38 -                log.debug("IntroduceDomain %d %d %d",
    2.39 -                          dominfo.getDomid(),
    2.40 -                          store_mfn,
    2.41 -                          dominfo.store_channel)
    2.42 -                IntroduceDomain(dominfo.getDomid(),
    2.43 -                                store_mfn,
    2.44 -                                dominfo.store_channel)
    2.45 -            else:
    2.46 -                m = re.match(r"^(console-mfn) (\d+)$", line)
    2.47 -                if m:
    2.48 -                    dominfo.setConsoleRef(int(m.group(2)))
    2.49 +        handler = RestoreInputHandler()
    2.50 +
    2.51 +        forkHelper(cmd, fd, handler.handler, True)
    2.52  
    2.53 -        forkHelper(cmd, fd, restoreInputHandler, True)
    2.54 +        if handler.store_mfn is None or handler.console_mfn is None:
    2.55 +            raise XendError('Could not read store/console MFN')
    2.56 +
    2.57 +        dominfo.completeRestore(handler.store_mfn, handler.console_mfn)
    2.58  
    2.59          return dominfo
    2.60      except:
    2.61 @@ -163,6 +152,22 @@ def restore(xd, fd):
    2.62          raise
    2.63  
    2.64  
    2.65 +class RestoreInputHandler:
    2.66 +    def __init__(self):
    2.67 +        self.store_mfn = None
    2.68 +        self.console_mfn = None
    2.69 +
    2.70 +
    2.71 +    def handler(self, line, _):
    2.72 +        m = re.match(r"^(store-mfn) (\d+)$", line)
    2.73 +        if m:
    2.74 +            self.store_mfn = int(m.group(2))
    2.75 +        else:
    2.76 +            m = re.match(r"^(console-mfn) (\d+)$", line)
    2.77 +            if m:
    2.78 +                self.console_mfn = int(m.group(2))
    2.79 +
    2.80 +
    2.81  def forkHelper(cmd, fd, inputHandler, closeToChild):
    2.82      child = xPopen3(cmd, True, -1, [fd, xc.handle()])
    2.83  
     3.1 --- a/tools/python/xen/xend/XendDomain.py	Wed Oct 19 07:43:03 2005 +0100
     3.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Oct 19 11:47:51 2005 +0100
     3.3 @@ -347,7 +347,7 @@ class XendDomain:
     3.4              dominfo = self.domain_lookup(domid)
     3.5              log.info("Domain %s (%d) unpaused.", dominfo.getName(),
     3.6                       dominfo.getDomid())
     3.7 -            return xc.domain_unpause(dom=dominfo.getDomid())
     3.8 +            return dominfo.unpause()
     3.9          except Exception, ex:
    3.10              raise XendError(str(ex))
    3.11  
    3.12 @@ -358,7 +358,7 @@ class XendDomain:
    3.13              dominfo = self.domain_lookup(domid)
    3.14              log.info("Domain %s (%d) paused.", dominfo.getName(),
    3.15                       dominfo.getDomid())
    3.16 -            return xc.domain_pause(dom=dominfo.getDomid())
    3.17 +            return dominfo.pause()
    3.18          except Exception, ex:
    3.19              raise XendError(str(ex))
    3.20  
     4.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Oct 19 07:43:03 2005 +0100
     4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Oct 19 11:47:51 2005 +0100
     4.3 @@ -145,8 +145,6 @@ def create(config):
     4.4      try:
     4.5          vm.construct()
     4.6          vm.initDomain()
     4.7 -        vm.construct_image()
     4.8 -        vm.configure()
     4.9          vm.storeVmDetails()
    4.10          vm.storeDomDetails()
    4.11          vm.refreshShutdown()
    4.12 @@ -167,6 +165,7 @@ def recreate(xeninfo, priv):
    4.13      assert not xeninfo['dying']
    4.14  
    4.15      domid = xeninfo['dom']
    4.16 +    uuid1 = xeninfo['handle']
    4.17      dompath = GetDomainPath(domid)
    4.18      if not dompath:
    4.19          raise XendError(
    4.20 @@ -176,44 +175,34 @@ def recreate(xeninfo, priv):
    4.21          if not vmpath:
    4.22              raise XendError(
    4.23                  'No vm path in store for existing domain %d' % domid)
    4.24 -        uuid1_str = xstransact.Read(vmpath, "uuid")
    4.25 -        if not uuid1_str:
    4.26 +        uuid2_str = xstransact.Read(vmpath, "uuid")
    4.27 +        if not uuid2_str:
    4.28              raise XendError(
    4.29                  'No vm/uuid path in store for existing domain %d' % domid)
    4.30  
    4.31 -        uuid1 = uuid.fromString(uuid1_str)
    4.32 -
    4.33 -        uuid2 = xeninfo['handle']
    4.34 +        uuid2 = uuid.fromString(uuid2_str)
    4.35  
    4.36          if uuid1 != uuid2:
    4.37              raise XendError(
    4.38                  'Uuid in store does not match uuid for existing domain %d: '
    4.39 -                '%s != %s' % (domid, uuid1_str, uuid.toString(uuid2)))
    4.40 +                '%s != %s' % (domid, uuid2_str, uuid.toString(uuid1)))
    4.41  
    4.42 -        log.info("Recreating domain %d, UUID %s.", domid, uuid1_str)
    4.43 +        log.info("Recreating domain %d, UUID %s.", domid, uuid2_str)
    4.44  
    4.45 -        vm = XendDomainInfo(uuid2, xeninfo, domid, dompath, True)
    4.46 +        vm = XendDomainInfo(uuid1, xeninfo, domid, dompath, True)
    4.47  
    4.48      except Exception, exn:
    4.49          log.warn(str(exn))
    4.50  
    4.51 -        if priv:
    4.52 -            new_uuid = [0 for i in range(0, 16)]
    4.53 -        else:
    4.54 -            new_uuid = uuid.create()
    4.55 +        log.info("Recreating domain %d with UUID %s.", domid,
    4.56 +                 uuid.toString(uuid1))
    4.57  
    4.58 -        log.info("Recreating domain %d with new UUID %s.", domid,
    4.59 -                 uuid.toString(new_uuid))
    4.60 -
    4.61 -        vm = XendDomainInfo(new_uuid, xeninfo, domid, dompath, True)
    4.62 +        vm = XendDomainInfo(uuid1, xeninfo, domid, dompath, True)
    4.63          vm.removeDom()
    4.64 +        vm.removeVm()
    4.65          vm.storeVmDetails()
    4.66          vm.storeDomDetails()
    4.67  
    4.68 -    if domid != 0:
    4.69 -        # Setup store and console channels 
    4.70 -        vm.create_channels()
    4.71 -
    4.72      vm.refreshShutdown(xeninfo)
    4.73      return vm
    4.74  
    4.75 @@ -230,11 +219,8 @@ def restore(config):
    4.76                          parseConfig(config))
    4.77      try:
    4.78          vm.construct()
    4.79 -        vm.configure()
    4.80 -        vm.create_channels()
    4.81          vm.storeVmDetails()
    4.82 -        vm.storeDomDetails()
    4.83 -        vm.refreshShutdown()
    4.84 +        vm.createChannels()
    4.85          return vm
    4.86      except:
    4.87          vm.destroy()
    4.88 @@ -379,9 +365,9 @@ class XendDomainInfo:
    4.89  
    4.90          self.image = None
    4.91  
    4.92 -        self.store_channel = None
    4.93 +        self.store_port = None
    4.94          self.store_mfn = None
    4.95 -        self.console_channel = None
    4.96 +        self.console_port = None
    4.97          self.console_mfn = None
    4.98  
    4.99          self.state = STATE_DOM_OK
   4.100 @@ -571,6 +557,18 @@ class XendDomainInfo:
   4.101  
   4.102      ## public:
   4.103  
   4.104 +    def completeRestore(self, store_mfn, console_mfn):
   4.105 +
   4.106 +        self.store_mfn = store_mfn
   4.107 +        self.console_mfn = console_mfn
   4.108 +
   4.109 +        self.introduceDomain()
   4.110 +        self.create_devices()
   4.111 +        self.storeDomDetails()
   4.112 +        self.unpause()
   4.113 +        self.refreshShutdown()
   4.114 +
   4.115 +
   4.116      def storeVmDetails(self):
   4.117          to_store = {
   4.118              'uuid':               uuid.toString(self.uuidbytes),
   4.119 @@ -604,6 +602,15 @@ class XendDomainInfo:
   4.120              if v:
   4.121                  to_store[k] = str(v)
   4.122  
   4.123 +        def f(n, v):
   4.124 +            if v is not None:
   4.125 +                to_store[n] = str(v)
   4.126 +
   4.127 +        f('console/port',     self.console_port)
   4.128 +        f('console/ring-ref', self.console_mfn)
   4.129 +        f('store/port',       self.store_port)
   4.130 +        f('store/ring-ref',   self.store_mfn)
   4.131 +
   4.132          to_store.update(self.vcpuDomDetails())
   4.133  
   4.134          log.debug("Storing domain details: %s", to_store)
   4.135 @@ -649,6 +656,16 @@ class XendDomainInfo:
   4.136          return self.dompath
   4.137  
   4.138  
   4.139 +    def getStorePort(self):
   4.140 +        """For use only by image.py and XendCheckpoint.py."""
   4.141 +        return self.store_port
   4.142 +
   4.143 +
   4.144 +    def getConsolePort(self):
   4.145 +        """For use only by image.py and XendCheckpoint.py"""
   4.146 +        return self.console_port
   4.147 +
   4.148 +
   4.149      def getVCpuCount(self):
   4.150          return self.info['vcpus']
   4.151  
   4.152 @@ -666,10 +683,6 @@ class XendDomainInfo:
   4.153          """Get this domain's target memory size, in KiB."""
   4.154          return self.info['memory_KiB']
   4.155  
   4.156 -    def setStoreRef(self, ref):
   4.157 -        self.store_mfn = ref
   4.158 -        self.storeDom("store/ring-ref", ref)
   4.159 -
   4.160  
   4.161      def refreshShutdown(self, xeninfo = None):
   4.162          # If set at the end of this method, a restart is required, with the
   4.163 @@ -704,6 +717,11 @@ class XendDomainInfo:
   4.164                  return
   4.165  
   4.166              elif xeninfo['crashed']:
   4.167 +                if self.readDom('xend/shutdown_completed'):
   4.168 +                    # We've seen this shutdown already, but we are preserving
   4.169 +                    # the domain for debugging.  Leave it alone.
   4.170 +                    return
   4.171 +
   4.172                  log.warn('Domain has crashed: name=%s id=%d.',
   4.173                           self.info['name'], self.domid)
   4.174  
   4.175 @@ -735,6 +753,11 @@ class XendDomainInfo:
   4.176                      else:
   4.177                          self.destroy()
   4.178  
   4.179 +            elif self.dompath is None:
   4.180 +                # We have yet to manage to call introduceDomain on this
   4.181 +                # domain.  This can happen if a restore is in progress, or has
   4.182 +                # failed.  Ignore this domain.
   4.183 +                pass
   4.184              else:
   4.185                  # Domain is alive.  If we are shutting it down, then check
   4.186                  # the timeout on that, and destroy it if necessary.
   4.187 @@ -802,11 +825,6 @@ class XendDomainInfo:
   4.188  
   4.189      ## public:
   4.190  
   4.191 -    def setConsoleRef(self, ref):
   4.192 -        self.console_mfn = ref
   4.193 -        self.storeDom("console/ring-ref", ref)
   4.194 -
   4.195 -
   4.196      def setMemoryTarget(self, target):
   4.197          """Set the memory target of this domain.
   4.198          @param target In MiB.
   4.199 @@ -1034,15 +1052,20 @@ class XendDomainInfo:
   4.200              raise VmError('Creating domain failed: name=%s' %
   4.201                            self.info['name'])
   4.202  
   4.203 -        self.dompath = DOMROOT + str(self.domid)
   4.204 -
   4.205 -        # Ensure that the domain entry is clean.  This prevents a stale
   4.206 -        # shutdown_start_time from killing the domain, for example.
   4.207 -        self.removeDom()
   4.208 -
   4.209          # Set maximum number of vcpus in domain
   4.210          xc.domain_max_vcpus(self.domid, int(self.info['vcpus']))
   4.211  
   4.212 +
   4.213 +    def introduceDomain(self):
   4.214 +        assert self.domid is not None
   4.215 +        assert self.store_mfn is not None
   4.216 +        assert self.store_port is not None
   4.217 +        
   4.218 +        IntroduceDomain(self.domid, self.store_mfn, self.store_port)
   4.219 +        self.dompath = GetDomainPath(self.domid)
   4.220 +        assert self.dompath
   4.221 +
   4.222 +
   4.223      def initDomain(self):
   4.224          log.debug('XendDomainInfo.initDomain: %s %s %s',
   4.225                    self.domid,
   4.226 @@ -1061,27 +1084,27 @@ class XendDomainInfo:
   4.227  
   4.228          xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
   4.229  
   4.230 -        # XXX Merge with configure_maxmem?
   4.231          m = self.image.getDomainMemory(self.info['memory_KiB'])
   4.232 -        xc.domain_setmaxmem(self.domid, m)
   4.233 +        xc.domain_setmaxmem(self.domid, maxmem_kb = m)
   4.234          xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
   4.235  
   4.236          cpu = self.info['cpu']
   4.237          if cpu is not None and cpu != -1:
   4.238              xc.domain_pincpu(self.domid, 0, 1 << cpu)
   4.239  
   4.240 -        self.info['start_time'] = time.time()
   4.241 +        self.createChannels()
   4.242  
   4.243 -        log.debug('init_domain> Created domain=%d name=%s memory=%d',
   4.244 -                  self.domid, self.info['name'], self.info['memory_KiB'])
   4.245 -
   4.246 +        channel_details = self.image.createImage()
   4.247  
   4.248 -    def construct_image(self):
   4.249 -        """Construct the boot image for the domain.
   4.250 -        """
   4.251 -        self.create_channels()
   4.252 -        self.image.createImage()
   4.253 -        IntroduceDomain(self.domid, self.store_mfn, self.store_channel)
   4.254 +        self.store_mfn = channel_details['store_mfn']
   4.255 +        if 'console_mfn' in channel_details:
   4.256 +            self.console_mfn = channel_details['console_mfn']
   4.257 +
   4.258 +        self.introduceDomain()
   4.259 +
   4.260 +        self.create_devices()
   4.261 +
   4.262 +        self.info['start_time'] = time.time()
   4.263  
   4.264  
   4.265      ## public:
   4.266 @@ -1166,33 +1189,22 @@ class XendDomainInfo:
   4.267                  break
   4.268  
   4.269  
   4.270 -    def eventChannel(self, path=None):
   4.271 -        """Create an event channel to the domain.
   4.272 -        
   4.273 -        @param path under which port is stored in db
   4.274 +    def createChannels(self):
   4.275 +        """Create the channels to the domain.
   4.276          """
   4.277 -        if path:
   4.278 -            try:
   4.279 -                return int(self.readDom(path))
   4.280 -            except:
   4.281 -                # The port is not yet set, i.e. the channel has not yet been
   4.282 -                # created.
   4.283 -                pass
   4.284 +        self.store_port = self.createChannel()
   4.285 +        self.console_port = self.createChannel()
   4.286 +
   4.287  
   4.288 +    def createChannel(self):
   4.289 +        """Create an event channel to the domain.
   4.290 +        """
   4.291          try:
   4.292 -            port = xc.evtchn_alloc_unbound(dom=self.domid, remote_dom=0)
   4.293 +            return xc.evtchn_alloc_unbound(dom=self.domid, remote_dom=0)
   4.294          except:
   4.295              log.exception("Exception in alloc_unbound(%d)", self.domid)
   4.296              raise
   4.297  
   4.298 -        self.storeDom(path, port)
   4.299 -        return port
   4.300 -
   4.301 -    def create_channels(self):
   4.302 -        """Create the channels to the domain.
   4.303 -        """
   4.304 -        self.store_channel = self.eventChannel("store/port")
   4.305 -        self.console_channel = self.eventChannel("console/port")
   4.306  
   4.307      def create_configured_devices(self):
   4.308          for (n, c) in self.info['device']:
   4.309 @@ -1231,6 +1243,14 @@ class XendDomainInfo:
   4.310          self.reconfigureDevice(deviceClass, devid, dev_config)
   4.311  
   4.312  
   4.313 +    def pause(self):
   4.314 +        xc.domain_pause(self.domid)
   4.315 +
   4.316 +
   4.317 +    def unpause(self):
   4.318 +        xc.domain_unpause(self.domid)
   4.319 +
   4.320 +
   4.321      ## private:
   4.322  
   4.323      def restart_check(self):
   4.324 @@ -1280,7 +1300,7 @@ class XendDomainInfo:
   4.325                  xd = get_component('xen.xend.XendDomain')
   4.326                  new_dom = xd.domain_create(config)
   4.327                  try:
   4.328 -                    xc.domain_unpause(new_dom.getDomid())
   4.329 +                    new_dom.unpause()
   4.330                  except:
   4.331                      new_dom.destroy()
   4.332                      raise
   4.333 @@ -1355,20 +1375,6 @@ class XendDomainInfo:
   4.334          self.config = sxp.merge(['vm', ['image', blcfg]], self.config)
   4.335  
   4.336  
   4.337 -    def configure(self):
   4.338 -        """Configure a vm.
   4.339 -
   4.340 -        """
   4.341 -        self.configure_maxmem()
   4.342 -        self.create_devices()
   4.343 -
   4.344 -
   4.345 -    def configure_maxmem(self):
   4.346 -        if self.image:
   4.347 -            m = self.image.getDomainMemory(self.info['memory_KiB'])
   4.348 -            xc.domain_setmaxmem(self.domid, maxmem_kb = m)
   4.349 -
   4.350 -
   4.351      def send_sysrq(self, key):
   4.352          asserts.isCharConvertible(key)
   4.353  
     5.1 --- a/tools/python/xen/xend/image.py	Wed Oct 19 07:43:03 2005 +0100
     5.2 +++ b/tools/python/xen/xend/image.py	Wed Oct 19 11:47:51 2005 +0100
     5.3 @@ -111,7 +111,8 @@ class ImageHandler:
     5.4          """Entry point to create domain memory image.
     5.5          Override in subclass  if needed.
     5.6          """
     5.7 -        self.createDomain()
     5.8 +        return self.createDomain()
     5.9 +
    5.10  
    5.11      def createDomain(self):
    5.12          """Build the domain boot image.
    5.13 @@ -128,10 +129,15 @@ class ImageHandler:
    5.14          
    5.15          log.info("buildDomain os=%s dom=%d vcpus=%d", self.ostype,
    5.16                   self.vm.getDomid(), self.vm.getVCpuCount())
    5.17 -        err = self.buildDomain()
    5.18 -        if err != 0:
    5.19 -            raise VmError('Building domain failed: ostype=%s dom=%d err=%d'
    5.20 -                          % (self.ostype, self.vm.getDomid(), err))
    5.21 +
    5.22 +        result = self.buildDomain()
    5.23 +
    5.24 +        if isinstance(result, dict):
    5.25 +            return result
    5.26 +        else:
    5.27 +            raise VmError('Building domain failed: ostype=%s dom=%d err=%s'
    5.28 +                          % (self.ostype, self.vm.getDomid(), str(result)))
    5.29 +
    5.30  
    5.31      def getDomainMemory(self, mem):
    5.32          """@return The memory required, in KiB, by the domain to store the
    5.33 @@ -151,26 +157,14 @@ class ImageHandler:
    5.34          """Extra cleanup on domain destroy (define in subclass if needed)."""
    5.35          pass
    5.36  
    5.37 -    def set_vminfo(self, d):
    5.38 -        if d.has_key('store_mfn'):
    5.39 -            self.vm.setStoreRef(d.get('store_mfn'))
    5.40 -        if d.has_key('console_mfn'):
    5.41 -            self.vm.setConsoleRef(d.get('console_mfn'))
    5.42 -
    5.43  
    5.44  class LinuxImageHandler(ImageHandler):
    5.45  
    5.46      ostype = "linux"
    5.47  
    5.48      def buildDomain(self):
    5.49 -        if self.vm.store_channel:
    5.50 -            store_evtchn = self.vm.store_channel
    5.51 -        else:
    5.52 -            store_evtchn = 0
    5.53 -        if self.vm.console_channel:
    5.54 -            console_evtchn = self.vm.console_channel
    5.55 -        else:
    5.56 -            console_evtchn = 0
    5.57 +        store_evtchn = self.vm.getStorePort()
    5.58 +        console_evtchn = self.vm.getConsolePort()
    5.59  
    5.60          log.debug("dom            = %d", self.vm.getDomid())
    5.61          log.debug("image          = %s", self.kernel)
    5.62 @@ -180,16 +174,12 @@ class LinuxImageHandler(ImageHandler):
    5.63          log.debug("ramdisk        = %s", self.ramdisk)
    5.64          log.debug("vcpus          = %d", self.vm.getVCpuCount())
    5.65  
    5.66 -        ret = xc.linux_build(dom            = self.vm.getDomid(),
    5.67 -                             image          = self.kernel,
    5.68 -                             store_evtchn   = store_evtchn,
    5.69 -                             console_evtchn = console_evtchn,
    5.70 -                             cmdline        = self.cmdline,
    5.71 -                             ramdisk        = self.ramdisk)
    5.72 -        if isinstance(ret, dict):
    5.73 -            self.set_vminfo(ret)
    5.74 -            return 0
    5.75 -        return ret
    5.76 +        return xc.linux_build(dom            = self.vm.getDomid(),
    5.77 +                              image          = self.kernel,
    5.78 +                              store_evtchn   = store_evtchn,
    5.79 +                              console_evtchn = console_evtchn,
    5.80 +                              cmdline        = self.cmdline,
    5.81 +                              ramdisk        = self.ramdisk)
    5.82  
    5.83  class VmxImageHandler(ImageHandler):
    5.84  
    5.85 @@ -214,20 +204,13 @@ class VmxImageHandler(ImageHandler):
    5.86          self.dmargs += self.configVNC(imageConfig)
    5.87  
    5.88  
    5.89 -    def createImage(self):
    5.90 -        """Create a VM for the VMX environment.
    5.91 -        """
    5.92 -        self.createDomain()
    5.93 -
    5.94      def buildDomain(self):
    5.95          # Create an event channel
    5.96          self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
    5.97                                                        remote_dom=0)
    5.98          log.info("VMX device model port: %d", self.device_channel)
    5.99 -        if self.vm.store_channel:
   5.100 -            store_evtchn = self.vm.store_channel
   5.101 -        else:
   5.102 -            store_evtchn = 0
   5.103 +
   5.104 +        store_evtchn = self.vm.getStorePort()
   5.105  
   5.106          log.debug("dom            = %d", self.vm.getDomid())
   5.107          log.debug("image          = %s", self.kernel)
   5.108 @@ -236,16 +219,13 @@ class VmxImageHandler(ImageHandler):
   5.109          log.debug("memsize        = %d", self.vm.getMemoryTarget() / 1024)
   5.110          log.debug("vcpus          = %d", self.vm.getVCpuCount())
   5.111  
   5.112 -        ret = xc.vmx_build(dom            = self.vm.getDomid(),
   5.113 -                           image          = self.kernel,
   5.114 -                           control_evtchn = self.device_channel,
   5.115 -                           store_evtchn   = store_evtchn,
   5.116 -                           memsize        = self.vm.getMemoryTarget() / 1024,
   5.117 -                           vcpus          = self.vm.getVCpuCount())
   5.118 -        if isinstance(ret, dict):
   5.119 -            self.set_vminfo(ret)
   5.120 -            return 0
   5.121 -        return ret
   5.122 +        return xc.vmx_build(dom            = self.vm.getDomid(),
   5.123 +                            image          = self.kernel,
   5.124 +                            control_evtchn = self.device_channel,
   5.125 +                            store_evtchn   = store_evtchn,
   5.126 +                            memsize        = self.vm.getMemoryTarget() / 1024,
   5.127 +                            vcpus          = self.vm.getVCpuCount())
   5.128 +
   5.129  
   5.130      # Return a list of cmd line args to the device models based on the
   5.131      # xm config file
     6.1 --- a/tools/xenstore/xenstored_core.c	Wed Oct 19 07:43:03 2005 +0100
     6.2 +++ b/tools/xenstore/xenstored_core.c	Wed Oct 19 11:47:51 2005 +0100
     6.3 @@ -246,8 +246,9 @@ static bool write_messages(struct connec
     6.4  
     6.5  	if (out->inhdr) {
     6.6  		if (verbose)
     6.7 -			xprintf("Writing msg %s (%s) out to %p\n",
     6.8 +			xprintf("Writing msg %s (%.*s) out to %p\n",
     6.9  				sockmsg_string(out->hdr.msg.type),
    6.10 +				out->hdr.msg.len,
    6.11  				out->buffer, conn);
    6.12  		ret = conn->write(conn, out->hdr.raw + out->used,
    6.13  				  sizeof(out->hdr) - out->used);
    6.14 @@ -946,9 +947,29 @@ static bool delete_child(struct connecti
    6.15  	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
    6.16  }
    6.17  
    6.18 +
    6.19 +static int _rm(struct connection *conn, struct node *node, const char *name)
    6.20 +{
    6.21 +	/* Delete from parent first, then if something explodes fsck cleans. */
    6.22 +	struct node *parent = read_node(conn, get_parent(name));
    6.23 +	if (!parent) {
    6.24 +		send_error(conn, EINVAL);
    6.25 +		return 0;
    6.26 +	}
    6.27 +
    6.28 +	if (!delete_child(conn, parent, basename(name))) {
    6.29 +		send_error(conn, EINVAL);
    6.30 +		return 0;
    6.31 +	}
    6.32 +
    6.33 +	delete_node(conn, node);
    6.34 +	return 1;
    6.35 +}
    6.36 +
    6.37 +
    6.38  static void do_rm(struct connection *conn, const char *name)
    6.39  {
    6.40 -	struct node *node, *parent;
    6.41 +	struct node *node;
    6.42  
    6.43  	name = canonicalize(conn, name);
    6.44  	node = get_node(conn, name, XS_PERM_WRITE);
    6.45 @@ -972,23 +993,23 @@ static void do_rm(struct connection *con
    6.46  		return;
    6.47  	}
    6.48  
    6.49 -	/* Delete from parent first, then if something explodes fsck cleans. */
    6.50 -	parent = read_node(conn, get_parent(name));
    6.51 -	if (!parent) {
    6.52 -		send_error(conn, EINVAL);
    6.53 +	if (_rm(conn, node, name)) {
    6.54 +		add_change_node(conn->transaction, name, true);
    6.55 +		fire_watches(conn, name, true);
    6.56 +		send_ack(conn, XS_RM);
    6.57 +	}
    6.58 +}
    6.59 +
    6.60 +
    6.61 +void internal_rm(const char *name)
    6.62 +{
    6.63 +	struct node *node = read_node(NULL, name);
    6.64 +	if (!node) {
    6.65  		return;
    6.66  	}
    6.67 -
    6.68 -	if (!delete_child(conn, parent, basename(name))) {
    6.69 -		send_error(conn, EINVAL);
    6.70 -		return;
    6.71 -	}
    6.72 +	_rm(NULL, node, name);
    6.73 +}
    6.74  
    6.75 -	delete_node(conn, node);
    6.76 -	add_change_node(conn->transaction, name, true);
    6.77 -	fire_watches(conn, name, true);
    6.78 -	send_ack(conn, XS_RM);
    6.79 -}
    6.80  
    6.81  static void do_get_perms(struct connection *conn, const char *name)
    6.82  {
     7.1 --- a/tools/xenstore/xenstored_core.h	Wed Oct 19 07:43:03 2005 +0100
     7.2 +++ b/tools/xenstore/xenstored_core.h	Wed Oct 19 11:47:51 2005 +0100
     7.3 @@ -154,6 +154,10 @@ void __attribute__((noreturn)) corrupt(s
     7.4  
     7.5  struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
     7.6  
     7.7 +
     7.8 +void internal_rm(const char *name);
     7.9 +
    7.10 +
    7.11  /* Is this a valid node name? */
    7.12  bool is_valid_nodename(const char *node);
    7.13  
     8.1 --- a/tools/xenstore/xenstored_domain.c	Wed Oct 19 07:43:03 2005 +0100
     8.2 +++ b/tools/xenstore/xenstored_domain.c	Wed Oct 19 11:47:51 2005 +0100
     8.3 @@ -271,6 +271,8 @@ static struct domain *new_domain(void *c
     8.4  	list_add(&domain->list, &domains);
     8.5  	talloc_set_destructor(domain, destroy_domain);
     8.6  
     8.7 +	internal_rm(domain->path);
     8.8 +
     8.9  	/* Tell kernel we're interested in this event. */
    8.10          bind.remote_domain = domid;
    8.11          bind.remote_port   = port;