ia64/xen-unstable

changeset 6805:c2558a2fe658

Switch to IntroduceDomain, move xend info into xend subdirectory in store.
Also switch store/console event channel and page reference store
entries over to xstransact.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Tue Sep 13 15:21:53 2005 +0000 (2005-09-13)
parents 68c4eb06a6aa
children 4ad19fe76d50
files tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py
line diff
     1.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Tue Sep 13 15:19:39 2005 +0000
     1.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Tue Sep 13 15:21:53 2005 +0000
     1.3 @@ -13,6 +13,7 @@ from string import join
     1.4  from struct import pack, unpack, calcsize
     1.5  from xen.util.xpopen import xPopen3
     1.6  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
     1.7 +from xen.xend.xenstore.xsutil import IntroduceDomain
     1.8  
     1.9  from XendError import XendError
    1.10  from XendLogging import log
    1.11 @@ -72,14 +73,6 @@ def save(xd, fd, dominfo, live):
    1.12                      xd.domain_shutdown(dominfo.id, reason='suspend')
    1.13                      dominfo.state_wait("suspended")
    1.14                      log.info("suspend %d done" % dominfo.id)
    1.15 -                    if dominfo.store_channel:
    1.16 -                        try:
    1.17 -                            dominfo.db.releaseDomain(dominfo.id)
    1.18 -                        except Exception, ex:
    1.19 -                            log.warning(
    1.20 -                                "error in domain release on xenstore: %s",
    1.21 -                                ex)
    1.22 -                            pass
    1.23                      child.tochild.write("done\n")
    1.24                      child.tochild.flush()
    1.25          if filter(lambda (fd, event): event & select.POLLHUP, r):
    1.26 @@ -90,11 +83,7 @@ def save(xd, fd, dominfo, live):
    1.27      if child.wait() != 0:
    1.28          raise XendError("xc_save failed: %s" % lasterr)
    1.29  
    1.30 -    if dominfo.store_channel:
    1.31 -        dominfo.store_channel.close()
    1.32 -        dominfo.db['store_channel'].delete()
    1.33 -        dominfo.db.saveDB(save=True)
    1.34 -        dominfo.store_channel = None
    1.35 +    dominfo.setStoreChannel(None)
    1.36      xd.domain_destroy(dominfo.id)
    1.37      return None
    1.38  
    1.39 @@ -163,16 +152,15 @@ def restore(xd, fd):
    1.40                      m = re.match(r"^(store-mfn) (\d+)\n$", l)
    1.41                      if m:
    1.42                          if dominfo.store_channel:
    1.43 -                            dominfo.store_mfn = int(m.group(2))
    1.44 +                            dominfo.setStoreRef(int(m.group(2)))
    1.45                              if dominfo.store_mfn >= 0:
    1.46 -                                dominfo.db.introduceDomain(dominfo.id,
    1.47 -                                                           dominfo.store_mfn,
    1.48 -                                                           dominfo.store_channel)
    1.49 -                            dominfo.exportToDB(save=True, sync=True)
    1.50 +                                IntroduceDomain(dominfo.id,
    1.51 +                                                dominfo.store_mfn,
    1.52 +                                                dominfo.store_channel.port1,
    1.53 +                                                dominfo.path)
    1.54                      m = re.match(r"^(console-mfn) (\d+)\n$", l)
    1.55                      if m:
    1.56 -                        dominfo.console_mfn = int(m.group(2))
    1.57 -                        dominfo.exportToDB(save=True, sync=True)
    1.58 +                        dominfo.setConsoleRef(int(m.group(2)))
    1.59                      try:
    1.60                          l = child.fromchild.readline()
    1.61                      except:
     2.1 --- a/tools/python/xen/xend/XendDomain.py	Tue Sep 13 15:19:39 2005 +0000
     2.2 +++ b/tools/python/xen/xend/XendDomain.py	Tue Sep 13 15:21:53 2005 +0000
     2.3 @@ -139,7 +139,7 @@ class XendDomain:
     2.4                  domdb.delete()
     2.5              elif domid in doms:
     2.6                  try:
     2.7 -                    self._new_domain(domdb, doms[domid]) 
     2.8 +                    self._new_domain(domdb['uuid'], domdb, doms[domid]) 
     2.9                  except Exception, ex:
    2.10                      log.exception("Error recreating domain info: id=%d", domid)
    2.11                      self._delete_domain(domid)
    2.12 @@ -155,14 +155,14 @@ class XendDomain:
    2.13      def close(self):
    2.14          pass
    2.15  
    2.16 -    def _new_domain(self, db, info):
    2.17 +    def _new_domain(self, uuid, db, info):
    2.18          """Create a domain entry from saved info.
    2.19  
    2.20          @param db:   saved info from the db
    2.21          @param info: domain info from xen
    2.22          @return: domain
    2.23          """
    2.24 -        dominfo = XendDomainInfo.recreate(db, info)
    2.25 +        dominfo = XendDomainInfo.recreate(uuid, db, info)
    2.26          self.domains[dominfo.id] = dominfo
    2.27          return dominfo
    2.28  
    2.29 @@ -355,8 +355,8 @@ class XendDomain:
    2.30                  log.info(
    2.31                      "Creating entry for unknown domain: id=%d uuid=%s",
    2.32                      id, uuid)
    2.33 -                db = self.dbmap.addChild(uuid)
    2.34 -                dominfo = XendDomainInfo.recreate(db, info)
    2.35 +                db = self.dbmap.addChild("%s/xend" % uuid)
    2.36 +                dominfo = XendDomainInfo.recreate(uuid, db, info)
    2.37                  dominfo.setdom(id)
    2.38                  self._add_domain(dominfo)
    2.39                  return dominfo
     3.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Sep 13 15:19:39 2005 +0000
     3.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Sep 13 15:21:53 2005 +0000
     3.3 @@ -48,6 +48,7 @@ from xen.xend.XendRoot import get_compon
     3.4  from xen.xend.uuid import getUuid
     3.5  from xen.xend.xenstore import DBVar, XenNode, DBMap
     3.6  from xen.xend.xenstore.xstransact import xstransact
     3.7 +from xen.xend.xenstore.xsutil import IntroduceDomain
     3.8  
     3.9  """Shutdown code for poweroff."""
    3.10  DOMAIN_POWEROFF = 0
    3.11 @@ -156,7 +157,7 @@ class XendDomainInfo:
    3.12          @raise: VmError for invalid configuration
    3.13          """
    3.14          uuid = getUuid()
    3.15 -        db = parentdb.addChild(uuid)
    3.16 +        db = parentdb.addChild("%s/xend" % uuid)
    3.17          path = parentdb.getPath()
    3.18          vm = cls(uuid, path, db)
    3.19          vm.construct(config)
    3.20 @@ -166,17 +167,19 @@ class XendDomainInfo:
    3.21  
    3.22      create = classmethod(create)
    3.23  
    3.24 -    def recreate(cls, db, info):
    3.25 +    def recreate(cls, uuid, db, info):
    3.26          """Create the VM object for an existing domain.
    3.27  
    3.28          @param db:        domain db
    3.29          @param info:      domain info from xc
    3.30          """
    3.31          dom = info['dom']
    3.32 -        path = "/".join(db.getPath().split("/")[0:-1])
    3.33 -        vm = cls(db.getName(), path, db)
    3.34 +        path = "/".join(db.getPath().split("/")[0:-2])
    3.35 +        vm = cls(uuid, path, db)
    3.36          vm.setdom(dom)
    3.37 -        db.readDB()
    3.38 +        try:
    3.39 +            db.readDB()
    3.40 +        except: pass
    3.41          vm.importFromDB()
    3.42          config = vm.config
    3.43          log.debug('info=' + str(info))
    3.44 @@ -208,7 +211,7 @@ class XendDomainInfo:
    3.45          """
    3.46          if not uuid:
    3.47              uuid = getUuid()
    3.48 -        db = parentdb.addChild(uuid)
    3.49 +        db = parentdb.addChild("%s/xend" % uuid)
    3.50          path = parentdb.getPath()
    3.51          vm = cls(uuid, path, db)
    3.52          ssidref = int(sxp.child_value(config, 'ssidref'))
    3.53 @@ -233,8 +236,6 @@ class XendDomainInfo:
    3.54          DBVar('config',        ty='sxpr'),
    3.55          DBVar('start_time',    ty='float'),
    3.56          DBVar('state',         ty='str'),
    3.57 -        DBVar('store_mfn',     ty='long'),
    3.58 -        DBVar('console_mfn',   ty='long', path="console/ring-ref"),
    3.59          DBVar('restart_mode',  ty='str'),
    3.60          DBVar('restart_state', ty='str'),
    3.61          DBVar('restart_time',  ty='float'),
    3.62 @@ -299,18 +300,13 @@ class XendDomainInfo:
    3.63          self.db.saveDB(save=save, sync=sync)
    3.64  
    3.65      def exportToDB(self, save=False, sync=False):
    3.66 -        if self.store_channel:
    3.67 -            self.store_channel.saveToDB(self.db.addChild("store_channel"),
    3.68 -                                        save=save)
    3.69 -        if self.console_channel:
    3.70 -            self.db['console/port'] = "%i" % self.console_channel.port1
    3.71          if self.image:
    3.72              self.image.exportToDB(save=save, sync=sync)
    3.73          self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync)
    3.74  
    3.75      def importFromDB(self):
    3.76          self.db.importFromDB(self, fields=self.__exports__)
    3.77 -        self.store_channel = self.eventChannelOld("store_channel")
    3.78 +        self.store_channel = self.eventChannel("store/port")
    3.79  
    3.80      def setdom(self, dom):
    3.81          """Set the domain id.
    3.82 @@ -330,11 +326,28 @@ class XendDomainInfo:
    3.83      def getName(self):
    3.84          return self.name
    3.85  
    3.86 -    def getStoreChannel(self):
    3.87 -        return self.store_channel
    3.88 +    def setStoreRef(self, ref):
    3.89 +        self.store_mfn = ref
    3.90 +        if ref:
    3.91 +            xstransact.Write(self.path, "store/ring-ref", "%i" % ref)
    3.92 +        else:
    3.93 +            xstransact.Remove(self.path, "store/ring-ref")
    3.94  
    3.95 -    def getConsoleChannel(self):
    3.96 -        return self.console_channel
    3.97 +    def setStoreChannel(self, channel):
    3.98 +        if self.store_channel and self.store_channel != channel:
    3.99 +            self.store_channel.close()
   3.100 +        self.store_channel = channel
   3.101 +        if channel:
   3.102 +            xstransact.Write(self.path, "store/port", "%i" % channel.port1)
   3.103 +        else:
   3.104 +            xstransact.Remove(self.path, "store/port")
   3.105 +
   3.106 +    def setConsoleRef(self, ref):
   3.107 +        self.console_mfn = ref
   3.108 +        if ref:
   3.109 +            xstransact.Write(self.path, "console/ring-ref", "%i" % ref)
   3.110 +        else:
   3.111 +            xstransact.Remove(self.path, "console/ring-ref")
   3.112  
   3.113      def update(self, info=None):
   3.114          """Update with  info from xc.domain_getinfo().
   3.115 @@ -702,9 +715,8 @@ class XendDomainInfo:
   3.116          self.image.createImage()
   3.117          self.exportToDB()
   3.118          if self.store_channel and self.store_mfn >= 0:
   3.119 -            self.db.introduceDomain(self.id,
   3.120 -                                    self.store_mfn,
   3.121 -                                    self.store_channel)
   3.122 +            IntroduceDomain(self.id, self.store_mfn, self.store_channel.port1,
   3.123 +                            self.path)
   3.124          # get the configured value of vcpus and update store
   3.125          self.exportVCPUSToDB(self.vcpus)
   3.126  
   3.127 @@ -742,16 +754,7 @@ class XendDomainInfo:
   3.128          self.state = STATE_VM_TERMINATED
   3.129          self.release_devices()
   3.130          if self.store_channel:
   3.131 -            try:
   3.132 -                self.store_channel.close()
   3.133 -                self.store_channel = None
   3.134 -            except:
   3.135 -                pass
   3.136 -            try:
   3.137 -                self.db.releaseDomain(self.id)
   3.138 -            except Exception, ex:
   3.139 -                log.warning("error in domain release on xenstore: %s", ex)
   3.140 -                pass
   3.141 +            self.setStoreChannel(None)
   3.142          if self.console_channel:
   3.143              # notify processes using this cosole?
   3.144              try:
   3.145 @@ -820,36 +823,27 @@ class XendDomainInfo:
   3.146                    id, self.name, self.memory)
   3.147          self.setdom(id)
   3.148  
   3.149 -    def eventChannelOld(self, key):
   3.150 -        """Create an event channel to the domain.
   3.151 -        If saved info is available recreate the channel.
   3.152 -        
   3.153 -        @param key db key for the saved data (if any)
   3.154 -        """
   3.155 -        db = self.db.addChild(key)
   3.156 -        return EventChannel.restoreFromDB(db, 0, self.id)
   3.157 -        
   3.158 -    def eventChannel(self, path=None, key=None):
   3.159 +    def eventChannel(self, path=None):
   3.160          """Create an event channel to the domain.
   3.161          
   3.162          @param path under which port is stored in db
   3.163          """
   3.164          port = 0
   3.165 -        try:
   3.166 -            if path and key:
   3.167 -                if path:
   3.168 -                    db = self.db.addChild(path)
   3.169 -                else:
   3.170 -                    db = self.db
   3.171 -                port = int(db[key].getData())
   3.172 -        except: pass
   3.173 -        return EventChannel.interdomain(0, self.id, port1=port, port2=0)
   3.174 +        if path:
   3.175 +            try:
   3.176 +                port = int(xstransact.Read(self.path, path))
   3.177 +            except:
   3.178 +                # if anything goes wrong, assume the port was not yet set
   3.179 +                pass
   3.180 +        ret = EventChannel.interdomain(0, self.id, port1=port, port2=0)
   3.181 +        xstransact.Write(self.path, path, "%i" % ret.port1)
   3.182 +        return ret
   3.183          
   3.184      def create_channel(self):
   3.185          """Create the channels to the domain.
   3.186          """
   3.187 -        self.store_channel = self.eventChannelOld("store_channel")
   3.188 -        self.console_channel = self.eventChannel("console", "port")
   3.189 +        self.store_channel = self.eventChannel("store/port")
   3.190 +        self.console_channel = self.eventChannel("console/port")
   3.191  
   3.192      def create_configured_devices(self):
   3.193          devices = sxp.children(self.config, 'device')
   3.194 @@ -1129,12 +1123,11 @@ class XendDomainInfo:
   3.195  
   3.196      def dom0_init_store(self):
   3.197          if not self.store_channel:
   3.198 -            self.store_channel = self.eventChannelOld("store_channel")
   3.199 +            self.store_channel = self.eventChannel("store/port")
   3.200          self.store_mfn = xc.init_store(self.store_channel.port2)
   3.201          if self.store_mfn >= 0:
   3.202 -            self.db.introduceDomain(self.id, self.store_mfn,
   3.203 -                                    self.store_channel)
   3.204 -        self.exportToDB(save=True, sync=True)
   3.205 +            IntroduceDomain(self.id, self.store_mfn, self.store_channel.port1,
   3.206 +                            self.path)
   3.207          # get run-time value of vcpus and update store
   3.208          self.exportVCPUSToDB(dom_get(self.id)['vcpus'])
   3.209  
     4.1 --- a/tools/python/xen/xend/image.py	Tue Sep 13 15:19:39 2005 +0000
     4.2 +++ b/tools/python/xen/xend/image.py	Tue Sep 13 15:21:53 2005 +0000
     4.3 @@ -23,6 +23,7 @@ from xen.xend import sxp
     4.4  from xen.xend.XendError import VmError
     4.5  from xen.xend.XendLogging import log
     4.6  from xen.xend.xenstore import DBVar
     4.7 +from xen.xend.xenstore.xstransact import xstransact
     4.8  
     4.9  from xen.xend.server import channel
    4.10  
    4.11 @@ -236,6 +237,12 @@ class ImageHandler:
    4.12          """Extra cleanup on domain destroy (define in subclass if needed)."""
    4.13          pass
    4.14  
    4.15 +    def set_vminfo(self, d):
    4.16 +        if d.has_key('store_mfn'):
    4.17 +            self.vm.setStoreRef(d.get('store_mfn'))
    4.18 +        if d.has_key('console_mfn'):
    4.19 +            self.vm.setConsoleRef(d.get('console_mfn'))
    4.20 +
    4.21  addImageHandlerClass = ImageHandler.addImageHandlerClass
    4.22  
    4.23  class LinuxImageHandler(ImageHandler):
    4.24 @@ -270,8 +277,7 @@ class LinuxImageHandler(ImageHandler):
    4.25                               flags          = self.flags,
    4.26                               vcpus          = self.vm.vcpus)
    4.27          if isinstance(ret, dict):
    4.28 -            self.vm.store_mfn = ret.get('store_mfn')
    4.29 -            self.vm.console_mfn = ret.get('console_mfn')
    4.30 +            self.set_vminfo(ret)
    4.31              return 0
    4.32          return ret
    4.33  
    4.34 @@ -314,7 +320,7 @@ class VmxImageHandler(ImageHandler):
    4.35                              flags          = self.flags,
    4.36                              vcpus          = self.vm.vcpus)
    4.37          if isinstance(ret, dict):
    4.38 -            self.vm.store_mfn = ret.get('store_mfn')
    4.39 +            self.set_vminfo(ret)
    4.40              return 0
    4.41          return ret
    4.42