ia64/xen-unstable

changeset 18565:616eea24aefa

xend: Move some backend configuration info.

This patch moves some dom0 variables and backend device
configuration from frontend directories to
/local/domain/<backdomid>/backend or /vm.

Also,
- /vm_path/<domid> is introduced, referencing the /vm path
- /vm_path/device/backend holds the backend device location,
rather than storing it in the frontend directory

Signed-off-by: Pascal Bouchareine <pascal@gandi.net>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Oct 01 13:35:39 2008 +0100 (2008-10-01)
parents 0a8ea3bbeb3d
children ab19284c5070
files tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/python/xen/xend/server/DevController.py tools/python/xen/xend/server/netif.py
line diff
     1.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Oct 01 09:31:13 2008 +0100
     1.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Oct 01 13:35:39 2008 +0100
     1.3 @@ -142,9 +142,7 @@ def recreate(info, priv):
     1.4      xeninfo['is_control_domain'] = priv
     1.5      xeninfo['is_a_template'] = False
     1.6      domid = xeninfo['domid']
     1.7 -    uuid1 = uuid.fromString(xeninfo['uuid'])
     1.8 -    needs_reinitialising = False
     1.9 -    
    1.10 +
    1.11      dompath = GetDomainPath(domid)
    1.12      if not dompath:
    1.13          raise XendError('No domain path in store for existing '
    1.14 @@ -153,42 +151,12 @@ def recreate(info, priv):
    1.15      log.info("Recreating domain %d, UUID %s. at %s" %
    1.16               (domid, xeninfo['uuid'], dompath))
    1.17  
    1.18 -    # need to verify the path and uuid if not Domain-0
    1.19 -    # if the required uuid and vm aren't set, then that means
    1.20 -    # we need to recreate the dom with our own values
    1.21 -    #
    1.22 -    # NOTE: this is probably not desirable, really we should just
    1.23 -    #       abort or ignore, but there may be cases where xenstore's
    1.24 -    #       entry disappears (eg. xenstore-rm /)
    1.25 -    #
    1.26 -    try:
    1.27 -        vmpath = xstransact.Read(dompath, "vm")
    1.28 -        if not vmpath:
    1.29 -            if not priv:
    1.30 -                log.warn('/local/domain/%d/vm is missing. recreate is '
    1.31 -                         'confused, trying our best to recover' % domid)
    1.32 -            needs_reinitialising = True
    1.33 -            raise XendError('reinit')
    1.34 -        
    1.35 -        uuid2_str = xstransact.Read(vmpath, "uuid")
    1.36 -        if not uuid2_str:
    1.37 -            log.warn('%s/uuid/ is missing. recreate is confused, '
    1.38 -                     'trying our best to recover' % vmpath)
    1.39 -            needs_reinitialising = True
    1.40 -            raise XendError('reinit')
    1.41 -        
    1.42 -        uuid2 = uuid.fromString(uuid2_str)
    1.43 -        if uuid1 != uuid2:
    1.44 -            log.warn('UUID in /vm does not match the UUID in /dom/%d.'
    1.45 -                     'Trying out best to recover' % domid)
    1.46 -            needs_reinitialising = True
    1.47 -    except XendError:
    1.48 -        pass # our best shot at 'goto' in python :)
    1.49 +    vmpath = xstransact.Read("/vm_path", str(domid))
    1.50  
    1.51      vm = XendDomainInfo(xeninfo, domid, dompath, augment = True, priv = priv,
    1.52                          vmpath = vmpath)
    1.53 -    
    1.54 -    if needs_reinitialising:
    1.55 +
    1.56 +    if not vmpath:
    1.57          vm._recreateDom()
    1.58          vm._removeVm()
    1.59          vm._storeVmDetails()
    1.60 @@ -477,8 +445,8 @@ class XendDomainInfo:
    1.61              try:
    1.62                  self._constructDomain()
    1.63                  self._storeVmDetails()
    1.64 +                self._createChannels()
    1.65                  self._createDevices()
    1.66 -                self._createChannels()
    1.67                  self._storeDomDetails()
    1.68                  self._endRestore()
    1.69              except:
    1.70 @@ -1240,6 +1208,8 @@ class XendDomainInfo:
    1.71          return xstransact.Write(self.vmpath, *args)
    1.72  
    1.73      def _removeVm(self, *args):
    1.74 +        if len(args) == 0:
    1.75 +            self._removeVmPath()
    1.76          return xstransact.Remove(self.vmpath, *args)
    1.77  
    1.78      def _gatherVm(self, *args):
    1.79 @@ -1254,31 +1224,6 @@ class XendDomainInfo:
    1.80      def permissionsVm(self, *args):
    1.81          return xstransact.SetPermissions(self.vmpath, *args)
    1.82  
    1.83 -
    1.84 -    def _readVmTxn(self, transaction,  *args):
    1.85 -        paths = map(lambda x: self.vmpath + "/" + x, args)
    1.86 -        return transaction.read(*paths)
    1.87 -
    1.88 -    def _writeVmTxn(self, transaction,  *args):
    1.89 -        paths = map(lambda x: self.vmpath + "/" + x, args)
    1.90 -        return transaction.write(*paths)
    1.91 -
    1.92 -    def _removeVmTxn(self, transaction,  *args):
    1.93 -        paths = map(lambda x: self.vmpath + "/" + x, args)
    1.94 -        return transaction.remove(*paths)
    1.95 -
    1.96 -    def _gatherVmTxn(self, transaction,  *args):
    1.97 -        paths = map(lambda x: self.vmpath + "/" + x, args)
    1.98 -        return transaction.gather(paths)
    1.99 -
   1.100 -    def storeVmTxn(self, transaction,  *args):
   1.101 -        paths = map(lambda x: self.vmpath + "/" + x, args)
   1.102 -        return transaction.store(*paths)
   1.103 -
   1.104 -    def permissionsVmTxn(self, transaction,  *args):
   1.105 -        paths = map(lambda x: self.vmpath + "/" + x, args)
   1.106 -        return transaction.set_permissions(*paths)
   1.107 -
   1.108      #
   1.109      # Function to update xenstore /dom/*
   1.110      #
   1.111 @@ -2715,6 +2660,15 @@ class XendDomainInfo:
   1.112                  log.info("Dev still active but hit max loop timeout")
   1.113                  break
   1.114  
   1.115 +    def _storeVmPath(self):
   1.116 +        log.info("storeVmPath(%s) => %s", self.domid, self.vmpath)
   1.117 +        if self.domid is not None:
   1.118 +            xstransact.Write('/vm_path', str(self.domid), self.vmpath)
   1.119 +
   1.120 +    def _removeVmPath(self):
   1.121 +        if self.domid is not None:
   1.122 +            xstransact.Remove('/vm_path/%s' % str(self.domid))
   1.123 +
   1.124      def _storeVmDetails(self):
   1.125          to_store = {}
   1.126  
   1.127 @@ -2739,7 +2693,7 @@ class XendDomainInfo:
   1.128  
   1.129          self._writeVm(to_store)
   1.130          self._setVmPermissions()
   1.131 -
   1.132 +        self._storeVmPath()
   1.133  
   1.134      def _setVmPermissions(self):
   1.135          """Allow the guest domain to read its UUID.  We don't allow it to
   1.136 @@ -2759,7 +2713,7 @@ class XendDomainInfo:
   1.137               log.warn("".join(traceback.format_stack()))
   1.138               return self._stateGet()
   1.139           else:
   1.140 -             raise AttributeError()
   1.141 +             raise AttributeError(name)
   1.142  
   1.143      def __setattr__(self, name, value):
   1.144          if name == "state":
   1.145 @@ -2869,12 +2823,6 @@ class XendDomainInfo:
   1.146                                    ignore_devices = ignore_store,
   1.147                                    legacy_only = legacy_only)
   1.148  
   1.149 -        #if not ignore_store and self.dompath:
   1.150 -        #    vnc_port = self.readDom('console/vnc-port')
   1.151 -        #    if vnc_port is not None:
   1.152 -        #        result.append(['device',
   1.153 -        #                       ['console', ['vnc-port', str(vnc_port)]]])
   1.154 -
   1.155          return result
   1.156  
   1.157      # Xen API
   1.158 @@ -3140,7 +3088,7 @@ class XendDomainInfo:
   1.159              if not config.has_key('device'):
   1.160                  devid = config.get('id')
   1.161                  if devid != None:
   1.162 -                    config['device'] = 'eth%d' % devid
   1.163 +                    config['device'] = 'eth%s' % devid
   1.164                  else:
   1.165                      config['device'] = ''
   1.166  
     2.1 --- a/tools/python/xen/xend/image.py	Wed Oct 01 09:31:13 2008 +0100
     2.2 +++ b/tools/python/xen/xend/image.py	Wed Oct 01 13:35:39 2008 +0100
     2.3 @@ -418,7 +418,7 @@ class ImageHandler:
     2.4              os.close(null)
     2.5              os.close(logfd)
     2.6          sentinel_write.close()
     2.7 -        self.vm.storeDom("image/device-model-pid", self.pid)
     2.8 +        self.vm.storeVm("image/device-model-pid", self.pid)
     2.9          log.info("device model pid: %d", self.pid)
    2.10          # we would very much prefer not to have a thread here and instead
    2.11          #  have a callback but sadly we don't have Twisted in xend
    2.12 @@ -502,7 +502,7 @@ class ImageHandler:
    2.13          if fifo_fd >= 0:
    2.14              self._openSentinel(sentinel_path_fifo)
    2.15              os.close(fifo_fd)
    2.16 -            self.pid = self.vm.gatherDom(('image/device-model-pid', int))
    2.17 +            self.pid = self.vm.gatherVm(('image/device-model-pid', int))
    2.18              log.debug("%s device model rediscovered, pid %s sentinel fifo %s",
    2.19                      name, self.pid, sentinel_path_fifo)
    2.20              self.sentinel_thread = thread.start_new_thread(self._sentinel_watch,())
     3.1 --- a/tools/python/xen/xend/server/DevController.py	Wed Oct 01 09:31:13 2008 +0100
     3.2 +++ b/tools/python/xen/xend/server/DevController.py	Wed Oct 01 13:35:39 2008 +0100
     3.3 @@ -126,8 +126,11 @@ class DevController:
     3.4                      log.debug(
     3.5                        'DevController: still waiting to write device entries.')
     3.6  
     3.7 +                devpath = self.devicePath(devid)
     3.8 +
     3.9                  t.remove(frontpath)
    3.10                  t.remove(backpath)
    3.11 +                t.remove(devpath)
    3.12  
    3.13                  t.mkdir(backpath)
    3.14                  t.set_permissions(backpath,
    3.15 @@ -142,6 +145,14 @@ class DevController:
    3.16                  t.write2(frontpath, front)
    3.17                  t.write2(backpath,  back)
    3.18  
    3.19 +                t.mkdir(devpath)
    3.20 +                t.write2(devpath, {
    3.21 +                    'backend' : backpath,
    3.22 +                    'backend-id' : "%i" % backdom,
    3.23 +                    'frontend' : frontpath,
    3.24 +                    'frontend-id' : "%i" % self.vm.getDomid()
    3.25 +                })
    3.26 +
    3.27                  if t.commit():
    3.28                      return devid
    3.29  
    3.30 @@ -246,11 +257,12 @@ class DevController:
    3.31  
    3.32          if force:
    3.33              frontpath = self.frontendPath(dev)
    3.34 -            backpath = xstransact.Read(frontpath, "backend")
    3.35 +            backpath = self.readVm(devid, "backend")
    3.36              if backpath:
    3.37                  xstransact.Remove(backpath)
    3.38              xstransact.Remove(frontpath)
    3.39  
    3.40 +        # xstransact.Remove(self.devicePath()) ?? Below is the same ?
    3.41          self.vm._removeVm("device/%s/%d" % (self.deviceClass, dev))
    3.42  
    3.43      def configurations(self, transaction = None):
    3.44 @@ -294,9 +306,10 @@ class DevController:
    3.45          @return: dict
    3.46          """
    3.47          if transaction is None:
    3.48 -            backdomid = xstransact.Read(self.frontendPath(devid), "backend-id")
    3.49 +            backdomid = xstransact.Read(self.devicePath(devid), "backend-id")
    3.50          else:
    3.51 -            backdomid = transaction.read(self.frontendPath(devid) + "/backend-id")
    3.52 +            backdomid = transaction.read(self.devicePath(devid) + "/backend-id")
    3.53 +
    3.54          if backdomid is None:
    3.55              raise VmError("Device %s not connected" % devid)
    3.56  
    3.57 @@ -438,17 +451,22 @@ class DevController:
    3.58          else:
    3.59              raise VmError("Device %s not connected" % devid)
    3.60  
    3.61 +    def readVm(self, devid, *args):
    3.62 +        devpath = self.devicePath(devid)
    3.63 +        if devpath:
    3.64 +            return xstransact.Read(devpath, *args)
    3.65 +        else:
    3.66 +            raise VmError("Device config %s not found" % devid)
    3.67 +
    3.68      def readBackend(self, devid, *args):
    3.69 -        frontpath = self.frontendPath(devid)
    3.70 -        backpath = xstransact.Read(frontpath, "backend")
    3.71 +        backpath = self.readVm(devid, "backend")
    3.72          if backpath:
    3.73              return xstransact.Read(backpath, *args)
    3.74          else:
    3.75              raise VmError("Device %s not connected" % devid)
    3.76  
    3.77      def readBackendTxn(self, transaction, devid, *args):
    3.78 -        frontpath = self.frontendPath(devid)
    3.79 -        backpath = transaction.read(frontpath + "/backend")
    3.80 +        backpath = self.readVm(devid, "backend")
    3.81          if backpath:
    3.82              paths = map(lambda x: backpath + "/" + x, args)
    3.83              return transaction.read(*paths)
    3.84 @@ -466,7 +484,7 @@ class DevController:
    3.85          """@return The IDs of each of the devices currently configured for
    3.86          this instance's deviceClass.
    3.87          """
    3.88 -        fe = self.backendRoot()
    3.89 +        fe = self.deviceRoot()
    3.90  
    3.91          if transaction:
    3.92              return map(lambda x: int(x.split('/')[-1]), transaction.list(fe))
    3.93 @@ -475,8 +493,7 @@ class DevController:
    3.94  
    3.95  
    3.96      def writeBackend(self, devid, *args):
    3.97 -        frontpath = self.frontendPath(devid)
    3.98 -        backpath = xstransact.Read(frontpath, "backend")
    3.99 +        backpath = self.readVm(devid, "backend")
   3.100  
   3.101          if backpath:
   3.102              xstransact.Write(backpath, *args)
   3.103 @@ -541,9 +558,8 @@ class DevController:
   3.104  
   3.105  
   3.106      def waitForBackend(self, devid):
   3.107 -
   3.108          frontpath = self.frontendPath(devid)
   3.109 -        # lookup a phantom 
   3.110 +        # lookup a phantom
   3.111          phantomPath = xstransact.Read(frontpath, 'phantom_vbd')
   3.112          if phantomPath is not None:
   3.113              log.debug("Waiting for %s's phantom %s.", devid, phantomPath)
   3.114 @@ -556,7 +572,7 @@ class DevController:
   3.115              if result['status'] != 'Connected':
   3.116                  return (result['status'], err)
   3.117              
   3.118 -        backpath = xstransact.Read(frontpath, "backend")
   3.119 +        backpath = self.readVm(devid, "backend")
   3.120  
   3.121  
   3.122          if backpath:
   3.123 @@ -621,17 +637,20 @@ class DevController:
   3.124      def frontendRoot(self):
   3.125          return "%s/device/%s" % (self.vm.getDomainPath(), self.deviceClass)
   3.126  
   3.127 -    def backendRoot(self):
   3.128 -        """Construct backend root path assuming backend is domain 0."""
   3.129 -        from xen.xend.XendDomain import DOM0_ID
   3.130 -        from xen.xend.xenstore.xsutil import GetDomainPath
   3.131 -        return "%s/backend/%s/%s" % (GetDomainPath(DOM0_ID),
   3.132 -                                     self.deviceClass, self.vm.getDomid())
   3.133 -
   3.134      def frontendMiscPath(self):
   3.135          return "%s/device-misc/%s" % (self.vm.getDomainPath(),
   3.136                                        self.deviceClass)
   3.137  
   3.138 +    def deviceRoot(self):
   3.139 +        """Return the /vm/device. Because backendRoot assumes the
   3.140 +        backend domain is 0"""
   3.141 +        return "%s/device/%s" % (self.vm.vmpath, self.deviceClass)
   3.142 +
   3.143 +    def devicePath(self, devid):
   3.144 +        """Return the /device entry of the given VM. We use it to store
   3.145 +        backend/frontend locations"""
   3.146 +        return "%s/device/%s/%s" % (self.vm.vmpath,
   3.147 +                                    self.deviceClass, devid)
   3.148  
   3.149  def hotplugStatusCallback(statusPath, ev, result):
   3.150      log.debug("hotplugStatusCallback %s.", statusPath)
     4.1 --- a/tools/python/xen/xend/server/netif.py	Wed Oct 01 09:31:13 2008 +0100
     4.2 +++ b/tools/python/xen/xend/server/netif.py	Wed Oct 01 13:35:39 2008 +0100
     4.3 @@ -142,10 +142,6 @@ class NetifController(DevController):
     4.4          if sec_lab:
     4.5              back['security_label'] = sec_lab
     4.6  
     4.7 -        config_path = "device/%s/%d/" % (self.deviceClass, devid)
     4.8 -        for x in back:
     4.9 -            self.vm._writeVm(config_path + x, back[x])
    4.10 -
    4.11          back['handle'] = "%i" % devid
    4.12          back['script'] = os.path.join(xoptions.network_script_dir, script)
    4.13          if rate:
    4.14 @@ -189,40 +185,14 @@ class NetifController(DevController):
    4.15  
    4.16          result = DevController.getDeviceConfiguration(self, devid, transaction)
    4.17  
    4.18 -        config_path = "device/%s/%d/" % (self.deviceClass, devid)
    4.19 -        devinfo = ()
    4.20          for x in ( 'script', 'ip', 'bridge', 'mac',
    4.21                     'type', 'vifname', 'rate', 'uuid', 'model', 'accel',
    4.22                     'security_label'):
    4.23              if transaction is None:
    4.24 -                y = self.vm._readVm(config_path + x)
    4.25 +                y = self.readBackend(devid, x)
    4.26              else:
    4.27 -                y = self.vm._readVmTxn(transaction, config_path + x)
    4.28 -            devinfo += (y,)
    4.29 -        (script, ip, bridge, mac, typ, vifname, rate, uuid,
    4.30 -         model, accel, security_label) = devinfo
    4.31 -
    4.32 -        if script:
    4.33 -            result['script'] = script
    4.34 -        if ip:
    4.35 -            result['ip'] = ip
    4.36 -        if bridge:
    4.37 -            result['bridge'] = bridge
    4.38 -        if mac:
    4.39 -            result['mac'] = mac
    4.40 -        if typ:
    4.41 -            result['type'] = typ
    4.42 -        if vifname:
    4.43 -            result['vifname'] = vifname
    4.44 -        if rate:
    4.45 -            result['rate'] = rate
    4.46 -        if uuid:
    4.47 -            result['uuid'] = uuid
    4.48 -        if model:
    4.49 -            result['model'] = model
    4.50 -        if accel:
    4.51 -            result['accel'] = accel
    4.52 -        if security_label:
    4.53 -            result['security_label'] = security_label
    4.54 +                y = self.readBackendTxn(transaction, devid, x)
    4.55 +            if y:
    4.56 +                result[x] = y
    4.57  
    4.58          return result