ia64/xen-unstable

changeset 7176:0e1838de9db8

Move XendDomainInfo.{create,recreate,parseConfig} to the top level of the
domain. This allows us to refer to them using an import statement, rather than
a from .. import. This is a step towards getting rid of the xroot hack. All
other references to XendDomainInfo methods need to be doubly qualified (once
for the module, once for the class).

Remove XendDomainDict, replacing it with a simple dictionary, folding the
get_by_name method into XendDomain.

Replace XendDomain.refresh_lock with a domains_lock which goes around any
reference to XendDomain.domains or anything that will create or destroy a
domain. This serialises most accesses through XendDomain, ensuring that we will
not return stale state when racing against the watches fired in separate
threads. This should have fixed bugs #270 and #234.

Added a number of domain_get_xyz methods. Those named xyz_nr are to allow
components internal to XendDomain (XendDomainInfo, XendCheckpoint) to call back
into XendDomain without triggering further calls to XendDomain.refresh. The
other methods simply make it clear which fallback behaviour is expected.

Replace XendDomainInfo.domain_exists with XendDomainInfo.domain_by_name; the
internals of this method needed to change to match those changes above, and it
has been a misnomer for some time.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@ewan
date Tue Oct 04 02:21:28 2005 +0100 (2005-10-04)
parents c70829a6edac
children 7f42935cb4b0
files tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/DevController.py tools/python/xen/xend/server/SrvDomainDir.py
line diff
     1.1 --- a/tools/python/xen/xend/XendDomain.py	Tue Oct 04 00:57:34 2005 +0100
     1.2 +++ b/tools/python/xen/xend/XendDomain.py	Tue Oct 04 02:21:28 2005 +0100
     1.3 @@ -22,14 +22,16 @@
     1.4   Needs to be persistent for one uptime.
     1.5  """
     1.6  import os
     1.7 +import string
     1.8  import threading
     1.9  
    1.10  import xen.lowlevel.xc
    1.11  
    1.12 +import XendDomainInfo
    1.13 +
    1.14  from xen.xend import sxp
    1.15  from xen.xend import XendRoot
    1.16  from xen.xend import XendCheckpoint
    1.17 -from xen.xend.XendDomainInfo import XendDomainInfo
    1.18  from xen.xend import EventServer
    1.19  from xen.xend.XendError import XendError
    1.20  from xen.xend.XendLogging import log
    1.21 @@ -45,21 +47,10 @@ eserver = EventServer.instance()
    1.22  
    1.23  PRIV_DOMAIN = 0
    1.24  
    1.25 -class XendDomainDict(dict):
    1.26 -    def get_by_name(self, name):
    1.27 -        try:
    1.28 -            return filter(lambda d: d.getName() == name, self.values())[0]
    1.29 -        except IndexError, err:
    1.30 -            return None
    1.31 -
    1.32  class XendDomain:
    1.33      """Index of all domains. Singleton.
    1.34      """
    1.35  
    1.36 -    """Dict of domain info indexed by domain id."""
    1.37 -    domains = None
    1.38 -
    1.39 -
    1.40      ## public:
    1.41      
    1.42      def __init__(self):
    1.43 @@ -68,19 +59,30 @@ class XendDomain:
    1.44          # to import XendDomain from XendDomainInfo causes unbounded recursion.
    1.45          # So we stuff the XendDomain instance (self) into xroot's components.
    1.46          xroot.add_component("xen.xend.XendDomain", self)
    1.47 -        self.domains = XendDomainDict()
    1.48 -        self.refresh_lock = threading.Condition()
    1.49 +        self.domains = {}
    1.50 +        self.domains_lock = threading.Condition()
    1.51          self.watchReleaseDomain()
    1.52 -        self.refresh()
    1.53 -        self.dom0_setup()
    1.54 +
    1.55 +        self.domains_lock.acquire()
    1.56 +        try:
    1.57 +            self.refresh()
    1.58 +            self.dom0_setup()
    1.59 +        finally:
    1.60 +            self.domains_lock.release()
    1.61 +
    1.62  
    1.63      def list(self):
    1.64          """Get list of domain objects.
    1.65  
    1.66          @return: domain objects
    1.67          """
    1.68 -        self.refresh()
    1.69 -        return self.domains.values()
    1.70 +        self.domains_lock.acquire()
    1.71 +        try:
    1.72 +            self.refresh()
    1.73 +            return self.domains.values()
    1.74 +        finally:
    1.75 +            self.domains_lock.release()
    1.76 +
    1.77  
    1.78      def list_sorted(self):
    1.79          """Get list of domain objects, sorted by name.
    1.80 @@ -103,7 +105,12 @@ class XendDomain:
    1.81      ## private:
    1.82  
    1.83      def onReleaseDomain(self):
    1.84 -        self.refresh()
    1.85 +        self.domains_lock.acquire()
    1.86 +        try:
    1.87 +            self.refresh()
    1.88 +        finally:
    1.89 +            self.domains_lock.release()
    1.90 +            
    1.91  
    1.92      def watchReleaseDomain(self):
    1.93          from xen.xend.xenstore.xswatch import xswatch
    1.94 @@ -133,16 +140,8 @@ class XendDomain:
    1.95          return dominfo
    1.96  
    1.97  
    1.98 -    def recreate_domain(self, xeninfo):
    1.99 -        """Refresh initial domain info from db."""
   1.100 -
   1.101 -        dominfo = XendDomainInfo.recreate(xeninfo)
   1.102 -        self._add_domain(dominfo)
   1.103 -        return dominfo
   1.104 -
   1.105 -
   1.106      def dom0_setup(self):
   1.107 -        dom0 = self.domain_lookup(PRIV_DOMAIN)
   1.108 +        dom0 = self.domains[PRIV_DOMAIN]
   1.109          dom0.dom0_enforce_vcpus()
   1.110  
   1.111  
   1.112 @@ -179,50 +178,33 @@ class XendDomain:
   1.113      def refresh(self):
   1.114          """Refresh domain list from Xen.
   1.115          """
   1.116 -        self.refresh_lock.acquire()
   1.117 -        try:
   1.118 -            doms = self.xen_domains()
   1.119 -            for d in self.domains.values():
   1.120 -                info = doms.get(d.getDomid())
   1.121 -                if info:
   1.122 -                    d.update(info)
   1.123 -                else:
   1.124 -                    self._delete_domain(d.getDomid())
   1.125 -            for d in doms:
   1.126 -                if d not in self.domains and not doms[d]['dying']:
   1.127 -                    try:
   1.128 -                        self.recreate_domain(doms[d])
   1.129 -                    except:
   1.130 -                        if d == PRIV_DOMAIN:
   1.131 -                            log.exception(
   1.132 -                                "Failed to recreate information for domain "
   1.133 -                                "%d.  Doing nothing except crossing my "
   1.134 -                                "fingers.", d)
   1.135 -                        else:
   1.136 -                            log.exception(
   1.137 -                                "Failed to recreate information for domain "
   1.138 -                                "%d.  Destroying it in the hope of "
   1.139 -                                "recovery.", d)
   1.140 -                            try:
   1.141 -                                xc.domain_destroy(dom = d)
   1.142 -                            except:
   1.143 -                                log.exception('Destruction of %d failed.', d)
   1.144 -        finally:
   1.145 -            self.refresh_lock.release()
   1.146 -
   1.147 -
   1.148 -    def update_domain(self, id):
   1.149 -        """Update information for a single domain.
   1.150 -
   1.151 -        @param id: domain id
   1.152 -        """
   1.153 -        dominfo = self.xen_domain(id)
   1.154 -        if dominfo:
   1.155 -            d = self.domains.get(id)
   1.156 -            if d:
   1.157 -                d.update(dominfo)
   1.158 -        else:
   1.159 -            self._delete_domain(id)
   1.160 +        doms = self.xen_domains()
   1.161 +        for d in self.domains.values():
   1.162 +            info = doms.get(d.getDomid())
   1.163 +            if info:
   1.164 +                d.update(info)
   1.165 +            else:
   1.166 +                self._delete_domain(d.getDomid())
   1.167 +        for d in doms:
   1.168 +            if d not in self.domains and not doms[d]['dying']:
   1.169 +                try:
   1.170 +                    dominfo = XendDomainInfo.recreate(doms[d])
   1.171 +                    self._add_domain(dominfo)
   1.172 +                except:
   1.173 +                    if d == PRIV_DOMAIN:
   1.174 +                        log.exception(
   1.175 +                            "Failed to recreate information for domain "
   1.176 +                            "%d.  Doing nothing except crossing my "
   1.177 +                            "fingers.", d)
   1.178 +                    else:
   1.179 +                        log.exception(
   1.180 +                            "Failed to recreate information for domain "
   1.181 +                            "%d.  Destroying it in the hope of "
   1.182 +                            "recovery.", d)
   1.183 +                        try:
   1.184 +                            xc.domain_destroy(dom = d)
   1.185 +                        except:
   1.186 +                            log.exception('Destruction of %d failed.', d)
   1.187  
   1.188  
   1.189      ## public:
   1.190 @@ -233,9 +215,14 @@ class XendDomain:
   1.191          @param config: configuration
   1.192          @return: domain
   1.193          """
   1.194 -        dominfo = XendDomainInfo.create(config)
   1.195 -        self._add_domain(dominfo)
   1.196 -        return dominfo
   1.197 +        self.domains_lock.acquire()
   1.198 +        try:
   1.199 +            dominfo = XendDomainInfo.create(config)
   1.200 +            self._add_domain(dominfo)
   1.201 +            return dominfo
   1.202 +        finally:
   1.203 +            self.domains_lock.release()
   1.204 +
   1.205  
   1.206      def domain_configure(self, config):
   1.207          """Configure an existing domain.
   1.208 @@ -260,33 +247,72 @@ class XendDomain:
   1.209              raise XendError("can't read guest state file %s: %s" %
   1.210                              (src, ex[1]))
   1.211  
   1.212 -    def domain_get(self, id):
   1.213 -        """Get up-to-date info about a domain.
   1.214 -
   1.215 -        @param id: domain id
   1.216 -        @return: domain object (or None)
   1.217 -        """
   1.218 -        self.update_domain(id)
   1.219 -        return self.domains.get(id)
   1.220 -
   1.221  
   1.222      def domain_lookup(self, id):
   1.223 -        self.refresh()
   1.224 -        return self.domains.get(id)
   1.225 +        self.domains_lock.acquire()
   1.226 +        try:
   1.227 +            self.refresh()
   1.228 +            return self.domains.get(id)
   1.229 +        finally:
   1.230 +            self.domains_lock.release()
   1.231  
   1.232 -    def domain_lookup_by_name(self, name):
   1.233 -        dominfo = self.domains.get_by_name(name)
   1.234 -        if not dominfo:
   1.235 -            try:
   1.236 -                id = int(name)
   1.237 -                dominfo = self.domain_lookup(id)
   1.238 -            except ValueError:
   1.239 -                pass
   1.240 -        return dominfo
   1.241 +
   1.242 +    def domain_lookup_nr(self, id):
   1.243 +        self.domains_lock.acquire()
   1.244 +        try:
   1.245 +            return self.domains.get(id)
   1.246 +        finally:
   1.247 +            self.domains_lock.release()
   1.248 +
   1.249 +
   1.250 +    def domain_lookup_by_name_or_id(self, name):
   1.251 +        self.domains_lock.acquire()
   1.252 +        try:
   1.253 +            self.refresh()
   1.254 +            return self.domain_lookup_by_name_or_id_nr(name)
   1.255 +        finally:
   1.256 +            self.domains_lock.release()
   1.257 +
   1.258 +
   1.259 +    def domain_lookup_by_name_or_id_nr(self, name):
   1.260 +        self.domains_lock.acquire()
   1.261 +        try:
   1.262 +            dominfo = self.domain_lookup_by_name_nr(name)
   1.263 +
   1.264 +            if dominfo:
   1.265 +                return dominfo
   1.266 +            else:
   1.267 +                try:
   1.268 +                    return self.domains.get(int(name))
   1.269 +                except ValueError:
   1.270 +                    return None
   1.271 +        finally:
   1.272 +            self.domains_lock.release()
   1.273 +
   1.274 +
   1.275 +    def domain_lookup_by_name_nr(self, name):
   1.276 +        self.domains_lock.acquire()
   1.277 +        try:
   1.278 +            matching = filter(lambda d: d.getName() == name,
   1.279 +                              self.domains.values())
   1.280 +            n = len(matching)
   1.281 +            if n == 1:
   1.282 +                return matching[0]
   1.283 +            elif n > 1:
   1.284 +                raise XendError(
   1.285 +                    'Name uniqueness has been violated for name %s' % name)
   1.286 +            else:
   1.287 +                return None
   1.288 +        finally:
   1.289 +            self.domains_lock.release()
   1.290  
   1.291  
   1.292      def privilegedDomain(self):
   1.293 -        return self.domains[PRIV_DOMAIN]
   1.294 +        self.domains_lock.acquire()
   1.295 +        try:
   1.296 +            return self.domains[PRIV_DOMAIN]
   1.297 +        finally:
   1.298 +            self.domains_lock.release()
   1.299  
   1.300   
   1.301      def domain_unpause(self, id):
   1.302 @@ -321,12 +347,13 @@ class XendDomain:
   1.303  
   1.304          @param reason: shutdown reason: poweroff, reboot, suspend, halt
   1.305          """
   1.306 -        self.callInfo(domid, XendDomainInfo.shutdown, reason)
   1.307 +        self.callInfo(domid, XendDomainInfo.XendDomainInfo.shutdown, reason)
   1.308  
   1.309  
   1.310      def domain_sysrq(self, domid, key):
   1.311          """Send a SysRq to the specified domain."""
   1.312 -        return self.callInfo(domid, XendDomainInfo.send_sysrq, key)
   1.313 +        return self.callInfo(domid, XendDomainInfo.XendDomainInfo.send_sysrq,
   1.314 +                             key)
   1.315  
   1.316  
   1.317      def domain_destroy(self, domid):
   1.318 @@ -449,32 +476,39 @@ class XendDomain:
   1.319      def domain_device_create(self, domid, devconfig):
   1.320          """Create a new device for the specified domain.
   1.321          """
   1.322 -        return self.callInfo(domid, XendDomainInfo.device_create, devconfig)
   1.323 +        return self.callInfo(domid,
   1.324 +                             XendDomainInfo.XendDomainInfo.device_create,
   1.325 +                             devconfig)
   1.326  
   1.327  
   1.328      def domain_device_configure(self, domid, devconfig, devid):
   1.329          """Configure an existing device in the specified domain.
   1.330          @return: updated device configuration
   1.331          """
   1.332 -        return self.callInfo(domid, XendDomainInfo.device_configure,
   1.333 +        return self.callInfo(domid,
   1.334 +                             XendDomainInfo.XendDomainInfo.device_configure,
   1.335                               devconfig, devid)
   1.336  
   1.337      
   1.338      def domain_device_refresh(self, domid, devtype, devid):
   1.339          """Refresh a device."""
   1.340 -        return self.callInfo(domid, XendDomainInfo.device_refresh, devtype,
   1.341 -                             devid)
   1.342 +        return self.callInfo(domid,
   1.343 +                             XendDomainInfo.XendDomainInfo.device_refresh,
   1.344 +                             devtype, devid)
   1.345  
   1.346  
   1.347      def domain_device_destroy(self, domid, devtype, devid):
   1.348          """Destroy a device."""
   1.349 -        return self.callInfo(domid, XendDomainInfo.destroyDevice, devtype,
   1.350 -                             devid)
   1.351 +        return self.callInfo(domid,
   1.352 +                             XendDomainInfo.XendDomainInfo.destroyDevice,
   1.353 +                             devtype, devid)
   1.354  
   1.355  
   1.356      def domain_devtype_ls(self, domid, devtype):
   1.357          """Get list of device sxprs for the specified domain."""
   1.358 -        return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
   1.359 +        return self.callInfo(domid,
   1.360 +                             XendDomainInfo.XendDomainInfo.getDeviceSxprs,
   1.361 +                             devtype)
   1.362  
   1.363  
   1.364      def domain_vif_limit_set(self, id, vif, credit, period):
   1.365 @@ -518,7 +552,8 @@ class XendDomain:
   1.366  
   1.367          @param mem: memory target (in MiB)
   1.368          """
   1.369 -        self.callInfo(domid, XendDomainInfo.setMemoryTarget, mem << 10)
   1.370 +        self.callInfo(domid, XendDomainInfo.XendDomainInfo.setMemoryTarget,
   1.371 +                      mem << 10)
   1.372  
   1.373  
   1.374      def domain_vcpu_hotplug(self, domid, vcpu, state):
   1.375 @@ -527,12 +562,13 @@ class XendDomain:
   1.376          @param vcpu: target VCPU in domain
   1.377          @param state: which state VCPU will become
   1.378          """
   1.379 -        self.callInfo(domid, XendDomainInfo.vcpu_hotplug, vcpu, state)
   1.380 +        self.callInfo(domid, XendDomainInfo.XendDomainInfo.vcpu_hotplug, vcpu,
   1.381 +                      state)
   1.382  
   1.383  
   1.384      def domain_dumpcore(self, domid):
   1.385          """Save a core dump for a crashed domain."""
   1.386 -        self.callInfo(domid, XendDomainInfo.dumpCore)
   1.387 +        self.callInfo(domid, XendDomainInfo.XendDomainInfo.dumpCore)
   1.388  
   1.389  
   1.390      ## private:
     2.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Oct 04 00:57:34 2005 +0100
     2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Oct 04 02:21:28 2005 +0100
     2.3 @@ -120,6 +120,68 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [
     2.4      ]
     2.5  
     2.6  
     2.7 +def create(config):
     2.8 +    """Create a VM from a configuration.
     2.9 +
    2.10 +    @param config    configuration
    2.11 +    @raise: VmError for invalid configuration
    2.12 +    """
    2.13 +
    2.14 +    log.debug("XendDomainInfo.create(%s)", config)
    2.15 +
    2.16 +    vm = XendDomainInfo(getUuid(), parseConfig(config))
    2.17 +    vm.construct()
    2.18 +    vm.refreshShutdown()
    2.19 +    return vm
    2.20 +
    2.21 +
    2.22 +def recreate(xeninfo):
    2.23 +    """Create the VM object for an existing domain.  The domain must not
    2.24 +    be dying, as the paths in the store should already have been removed,
    2.25 +    and asking us to recreate them causes problems."""
    2.26 +
    2.27 +    log.debug("XendDomainInfo.recreate(%s)", xeninfo)
    2.28 +
    2.29 +    assert not xeninfo['dying']
    2.30 +
    2.31 +    domid = xeninfo['dom']
    2.32 +    try:
    2.33 +        dompath = GetDomainPath(domid)
    2.34 +        if not dompath:
    2.35 +            raise XendError(
    2.36 +                'No domain path in store for existing domain %d' % domid)
    2.37 +        vmpath = xstransact.Read(dompath, "vm")
    2.38 +        if not vmpath:
    2.39 +            raise XendError(
    2.40 +                'No vm path in store for existing domain %d' % domid)
    2.41 +        uuid = xstransact.Read(vmpath, "uuid")
    2.42 +        if not uuid:
    2.43 +            raise XendError(
    2.44 +                'No vm/uuid path in store for existing domain %d' % domid)
    2.45 +
    2.46 +        log.info("Recreating domain %d, UUID %s.", domid, uuid)
    2.47 +
    2.48 +        vm = XendDomainInfo(uuid, xeninfo, domid, True)
    2.49 +
    2.50 +    except Exception, exn:
    2.51 +        log.warn(str(exn))
    2.52 +
    2.53 +        uuid = getUuid()
    2.54 +
    2.55 +        log.info("Recreating domain %d with new UUID %s.", domid, uuid)
    2.56 +
    2.57 +        vm = XendDomainInfo(uuid, xeninfo, domid, True)
    2.58 +        vm.storeVmDetails()
    2.59 +        vm.storeDomDetails()
    2.60 +
    2.61 +    vm.create_channel()
    2.62 +    if domid == 0:
    2.63 +        vm.initStoreConnection()
    2.64 +
    2.65 +    vm.refreshShutdown(xeninfo)
    2.66 +    return vm
    2.67 +
    2.68 +
    2.69  def restore(config):
    2.70      """Create a domain and a VM object to do a restore.
    2.71  
    2.72 @@ -134,7 +196,7 @@ def restore(config):
    2.73      except TypeError, exn:
    2.74          raise VmError('Invalid ssidref in config: %s' % exn)
    2.75  
    2.76 -    vm = XendDomainInfo(uuid, XendDomainInfo.parseConfig(config),
    2.77 +    vm = XendDomainInfo(uuid, parseConfig(config),
    2.78                          xc.domain_create(ssidref = ssidref))
    2.79      vm.storeVmDetails()
    2.80      vm.configure()
    2.81 @@ -143,10 +205,87 @@ def restore(config):
    2.82      return vm
    2.83  
    2.84  
    2.85 -def domain_exists(name):
    2.86 +def parseConfig(config):
    2.87 +    def get_cfg(name, conv = None):
    2.88 +        val = sxp.child_value(config, name)
    2.89 +
    2.90 +        if conv and not val is None:
    2.91 +            try:
    2.92 +                return conv(val)
    2.93 +            except TypeError, exn:
    2.94 +                raise VmError(
    2.95 +                    'Invalid setting %s = %s in configuration: %s' %
    2.96 +                    (name, val, str(exn)))
    2.97 +        else:
    2.98 +            return val
    2.99 +
   2.100 +
   2.101 +    log.debug("parseConfig: config is %s" % str(config))
   2.102 +
   2.103 +    result = {}
   2.104 +
   2.105 +    for e in ROUNDTRIPPING_CONFIG_ENTRIES:
   2.106 +        result[e[0]] = get_cfg(e[0], e[1])
   2.107 +
   2.108 +    result['memory']       = get_cfg('memory',     int)
   2.109 +    result['mem_kb']       = get_cfg('mem_kb',     int)
   2.110 +    result['maxmem']       = get_cfg('maxmem',     int)
   2.111 +    result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
   2.112 +    result['cpu']          = get_cfg('cpu',        int)
   2.113 +    result['image']        = get_cfg('image')
   2.114 +
   2.115 +    try:
   2.116 +        if result['image']:
   2.117 +            result['vcpus'] = int(sxp.child_value(result['image'],
   2.118 +                                                  'vcpus', 1))
   2.119 +        else:
   2.120 +            result['vcpus'] = 1
   2.121 +    except TypeError, exn:
   2.122 +        raise VmError(
   2.123 +            'Invalid configuration setting: vcpus = %s: %s' %
   2.124 +            (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
   2.125 +
   2.126 +    result['backend'] = []
   2.127 +    for c in sxp.children(config, 'backend'):
   2.128 +        result['backend'].append(sxp.name(sxp.child0(c)))
   2.129 +
   2.130 +    result['device'] = []
   2.131 +    for d in sxp.children(config, 'device'):
   2.132 +        c = sxp.child0(d)
   2.133 +        result['device'].append((sxp.name(c), c))
   2.134 +
   2.135 +    # Configuration option "restart" is deprecated.  Parse it, but
   2.136 +    # let on_xyz override it if they are present.
   2.137 +    restart = get_cfg('restart')
   2.138 +    if restart:
   2.139 +        def handle_restart(event, val):
   2.140 +            if not event in result:
   2.141 +                result[event] = val
   2.142 +
   2.143 +        if restart == "onreboot":
   2.144 +            handle_restart('on_poweroff', 'destroy')
   2.145 +            handle_restart('on_reboot',   'restart')
   2.146 +            handle_restart('on_crash',    'destroy')
   2.147 +        elif restart == "always":
   2.148 +            handle_restart('on_poweroff', 'restart')
   2.149 +            handle_restart('on_reboot',   'restart')
   2.150 +            handle_restart('on_crash',    'restart')
   2.151 +        elif restart == "never":
   2.152 +            handle_restart('on_poweroff', 'destroy')
   2.153 +            handle_restart('on_reboot',   'destroy')
   2.154 +            handle_restart('on_crash',    'destroy')
   2.155 +        else:
   2.156 +            log.warn("Ignoring malformed and deprecated config option "
   2.157 +                     "restart = %s", restart)
   2.158 +
   2.159 +    log.debug("parseConfig: result is %s" % str(result))
   2.160 +    return result
   2.161 +
   2.162 +
   2.163 +def domain_by_name(name):
   2.164      # See comment in XendDomain constructor.
   2.165      xd = get_component('xen.xend.XendDomain')
   2.166 -    return xd.domain_lookup_by_name(name)
   2.167 +    return xd.domain_lookup_by_name_nr(name)
   2.168  
   2.169  def shutdown_reason(code):
   2.170      """Get a shutdown reason from a code.
   2.171 @@ -181,152 +320,6 @@ class XendDomainInfo:
   2.172      MINIMUM_RESTART_TIME = 20
   2.173  
   2.174  
   2.175 -    def create(cls, config):
   2.176 -        """Create a VM from a configuration.
   2.177 -
   2.178 -        @param config    configuration
   2.179 -        @raise: VmError for invalid configuration
   2.180 -        """
   2.181 -
   2.182 -        log.debug("XendDomainInfo.create(%s)", config)
   2.183 -        
   2.184 -        vm = cls(getUuid(), cls.parseConfig(config))
   2.185 -        vm.construct()
   2.186 -        vm.refreshShutdown()
   2.187 -        return vm
   2.188 -
   2.189 -    create = classmethod(create)
   2.190 -
   2.191 -
   2.192 -    def recreate(cls, xeninfo):
   2.193 -        """Create the VM object for an existing domain.  The domain must not
   2.194 -        be dying, as the paths in the store should already have been removed,
   2.195 -        and asking us to recreate them causes problems."""
   2.196 -
   2.197 -        log.debug("XendDomainInfo.recreate(%s)", xeninfo)
   2.198 -
   2.199 -        assert not xeninfo['dying']
   2.200 -
   2.201 -        domid = xeninfo['dom']
   2.202 -        try:
   2.203 -            dompath = GetDomainPath(domid)
   2.204 -            if not dompath:
   2.205 -                raise XendError(
   2.206 -                    'No domain path in store for existing domain %d' % domid)
   2.207 -            vmpath = xstransact.Read(dompath, "vm")
   2.208 -            if not vmpath:
   2.209 -                raise XendError(
   2.210 -                    'No vm path in store for existing domain %d' % domid)
   2.211 -            uuid = xstransact.Read(vmpath, "uuid")
   2.212 -            if not uuid:
   2.213 -                raise XendError(
   2.214 -                    'No vm/uuid path in store for existing domain %d' % domid)
   2.215 -
   2.216 -            log.info("Recreating domain %d, UUID %s.", domid, uuid)
   2.217 -
   2.218 -            vm = cls(uuid, xeninfo, domid, True)
   2.219 -
   2.220 -        except Exception, exn:
   2.221 -            log.warn(str(exn))
   2.222 -
   2.223 -            uuid = getUuid()
   2.224 -
   2.225 -            log.info("Recreating domain %d with new UUID %s.", domid, uuid)
   2.226 -
   2.227 -            vm = cls(uuid, xeninfo, domid, True)
   2.228 -            vm.storeVmDetails()
   2.229 -            vm.storeDomDetails()
   2.230 -
   2.231 -        vm.create_channel()
   2.232 -        if domid == 0:
   2.233 -            vm.initStoreConnection()
   2.234 -
   2.235 -        vm.refreshShutdown(xeninfo)
   2.236 -        return vm
   2.237 -
   2.238 -    recreate = classmethod(recreate)
   2.239 -
   2.240 -
   2.241 -    def parseConfig(cls, config):
   2.242 -        def get_cfg(name, conv = None):
   2.243 -            val = sxp.child_value(config, name)
   2.244 -
   2.245 -            if conv and not val is None:
   2.246 -                try:
   2.247 -                    return conv(val)
   2.248 -                except TypeError, exn:
   2.249 -                    raise VmError(
   2.250 -                        'Invalid setting %s = %s in configuration: %s' %
   2.251 -                        (name, val, str(exn)))
   2.252 -            else:
   2.253 -                return val
   2.254 -
   2.255 -
   2.256 -        log.debug("parseConfig: config is %s" % str(config))
   2.257 -
   2.258 -        result = {}
   2.259 -
   2.260 -        for e in ROUNDTRIPPING_CONFIG_ENTRIES:
   2.261 -            result[e[0]] = get_cfg(e[0], e[1])
   2.262 -
   2.263 -        result['memory']       = get_cfg('memory',     int)
   2.264 -        result['mem_kb']       = get_cfg('mem_kb',     int)
   2.265 -        result['maxmem']       = get_cfg('maxmem',     int)
   2.266 -        result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
   2.267 -        result['cpu']          = get_cfg('cpu',        int)
   2.268 -        result['image']        = get_cfg('image')
   2.269 -
   2.270 -        try:
   2.271 -            if result['image']:
   2.272 -                result['vcpus'] = int(sxp.child_value(result['image'],
   2.273 -                                                      'vcpus', 1))
   2.274 -            else:
   2.275 -                result['vcpus'] = 1
   2.276 -        except TypeError, exn:
   2.277 -            raise VmError(
   2.278 -                'Invalid configuration setting: vcpus = %s: %s' %
   2.279 -                (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
   2.280 -
   2.281 -        result['backend'] = []
   2.282 -        for c in sxp.children(config, 'backend'):
   2.283 -            result['backend'].append(sxp.name(sxp.child0(c)))
   2.284 -
   2.285 -        result['device'] = []
   2.286 -        for d in sxp.children(config, 'device'):
   2.287 -            c = sxp.child0(d)
   2.288 -            result['device'].append((sxp.name(c), c))
   2.289 -
   2.290 -        # Configuration option "restart" is deprecated.  Parse it, but
   2.291 -        # let on_xyz override it if they are present.
   2.292 -        restart = get_cfg('restart')
   2.293 -        if restart:
   2.294 -            def handle_restart(event, val):
   2.295 -                if not event in result:
   2.296 -                    result[event] = val
   2.297 -
   2.298 -            if restart == "onreboot":
   2.299 -                handle_restart('on_poweroff', 'destroy')
   2.300 -                handle_restart('on_reboot',   'restart')
   2.301 -                handle_restart('on_crash',    'destroy')
   2.302 -            elif restart == "always":
   2.303 -                handle_restart('on_poweroff', 'restart')
   2.304 -                handle_restart('on_reboot',   'restart')
   2.305 -                handle_restart('on_crash',    'restart')
   2.306 -            elif restart == "never":
   2.307 -                handle_restart('on_poweroff', 'destroy')
   2.308 -                handle_restart('on_reboot',   'destroy')
   2.309 -                handle_restart('on_crash',    'destroy')
   2.310 -            else:
   2.311 -                log.warn("Ignoring malformed and deprecated config option "
   2.312 -                         "restart = %s", restart)
   2.313 -
   2.314 -        log.debug("parseConfig: result is %s" % str(result))
   2.315 -        return result
   2.316 -
   2.317 -
   2.318 -    parseConfig = classmethod(parseConfig)
   2.319 -
   2.320 -    
   2.321      def __init__(self, uuid, info, domid = None, augment = False):
   2.322  
   2.323          self.uuid = uuid
   2.324 @@ -957,10 +950,8 @@ class XendDomainInfo:
   2.325              if c in '_-.:/+': continue
   2.326              if c in string.ascii_letters: continue
   2.327              raise VmError('invalid vm name')
   2.328 -        dominfo = domain_exists(name)
   2.329 -        # When creating or rebooting, a domain with my name should not exist.
   2.330 -        # When restoring, a domain with my name will exist, but it should have
   2.331 -        # my domain id.
   2.332 +
   2.333 +        dominfo = domain_by_name(name)
   2.334          if not dominfo:
   2.335              return
   2.336          if dominfo.is_terminated():
     3.1 --- a/tools/python/xen/xend/server/DevController.py	Tue Oct 04 00:57:34 2005 +0100
     3.2 +++ b/tools/python/xen/xend/server/DevController.py	Tue Oct 04 02:21:28 2005 +0100
     3.3 @@ -193,7 +193,7 @@ class DevController:
     3.4  
     3.5          backdom_name = sxp.child_value(config, 'backend')
     3.6          if backdom_name:
     3.7 -            backdom = xd.domain_lookup_by_name(backdom_name)
     3.8 +            backdom = xd.domain_lookup_by_name_or_id_nr(backdom_name)
     3.9          else:
    3.10              backdom = xd.privilegedDomain()
    3.11  
     4.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Tue Oct 04 00:57:34 2005 +0100
     4.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Tue Oct 04 02:21:28 2005 +0100
     4.3 @@ -38,7 +38,7 @@ class SrvDomainDir(SrvDir):
     4.4          self.xd = XendDomain.instance()
     4.5  
     4.6      def domain(self, x):
     4.7 -        dom = self.xd.domain_lookup_by_name(x)
     4.8 +        dom = self.xd.domain_lookup_by_name_or_id(x)
     4.9          if not dom:
    4.10              raise XendError('No such domain ' + str(x))
    4.11          return SrvDomain(dom)