[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Move XendDomainInfo.{create, recreate, parseConfig} to the top level of the



# HG changeset patch
# User emellor@ewan
# Node ID 0e1838de9db844c4376336065f0bcf03e4f6f46c
# Parent  c70829a6edac6e64c0df5b94ada08b0ce8f7778e
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@xxxxxxxxxxxxx>

diff -r c70829a6edac -r 0e1838de9db8 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Mon Oct  3 23:57:34 2005
+++ b/tools/python/xen/xend/XendDomain.py       Tue Oct  4 01:21:28 2005
@@ -22,14 +22,16 @@
  Needs to be persistent for one uptime.
 """
 import os
+import string
 import threading
 
 import xen.lowlevel.xc
+
+import XendDomainInfo
 
 from xen.xend import sxp
 from xen.xend import XendRoot
 from xen.xend import XendCheckpoint
-from xen.xend.XendDomainInfo import XendDomainInfo
 from xen.xend import EventServer
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
@@ -45,20 +47,9 @@
 
 PRIV_DOMAIN = 0
 
-class XendDomainDict(dict):
-    def get_by_name(self, name):
-        try:
-            return filter(lambda d: d.getName() == name, self.values())[0]
-        except IndexError, err:
-            return None
-
 class XendDomain:
     """Index of all domains. Singleton.
     """
-
-    """Dict of domain info indexed by domain id."""
-    domains = None
-
 
     ## public:
     
@@ -68,19 +59,30 @@
         # to import XendDomain from XendDomainInfo causes unbounded recursion.
         # So we stuff the XendDomain instance (self) into xroot's components.
         xroot.add_component("xen.xend.XendDomain", self)
-        self.domains = XendDomainDict()
-        self.refresh_lock = threading.Condition()
+        self.domains = {}
+        self.domains_lock = threading.Condition()
         self.watchReleaseDomain()
-        self.refresh()
-        self.dom0_setup()
+
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            self.dom0_setup()
+        finally:
+            self.domains_lock.release()
+
 
     def list(self):
         """Get list of domain objects.
 
         @return: domain objects
         """
-        self.refresh()
-        return self.domains.values()
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            return self.domains.values()
+        finally:
+            self.domains_lock.release()
+
 
     def list_sorted(self):
         """Get list of domain objects, sorted by name.
@@ -103,7 +105,12 @@
     ## private:
 
     def onReleaseDomain(self):
-        self.refresh()
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+        finally:
+            self.domains_lock.release()
+            
 
     def watchReleaseDomain(self):
         from xen.xend.xenstore.xswatch import xswatch
@@ -133,16 +140,8 @@
         return dominfo
 
 
-    def recreate_domain(self, xeninfo):
-        """Refresh initial domain info from db."""
-
-        dominfo = XendDomainInfo.recreate(xeninfo)
-        self._add_domain(dominfo)
-        return dominfo
-
-
     def dom0_setup(self):
-        dom0 = self.domain_lookup(PRIV_DOMAIN)
+        dom0 = self.domains[PRIV_DOMAIN]
         dom0.dom0_enforce_vcpus()
 
 
@@ -179,50 +178,33 @@
     def refresh(self):
         """Refresh domain list from Xen.
         """
-        self.refresh_lock.acquire()
-        try:
-            doms = self.xen_domains()
-            for d in self.domains.values():
-                info = doms.get(d.getDomid())
-                if info:
-                    d.update(info)
-                else:
-                    self._delete_domain(d.getDomid())
-            for d in doms:
-                if d not in self.domains and not doms[d]['dying']:
-                    try:
-                        self.recreate_domain(doms[d])
-                    except:
-                        if d == PRIV_DOMAIN:
-                            log.exception(
-                                "Failed to recreate information for domain "
-                                "%d.  Doing nothing except crossing my "
-                                "fingers.", d)
-                        else:
-                            log.exception(
-                                "Failed to recreate information for domain "
-                                "%d.  Destroying it in the hope of "
-                                "recovery.", d)
-                            try:
-                                xc.domain_destroy(dom = d)
-                            except:
-                                log.exception('Destruction of %d failed.', d)
-        finally:
-            self.refresh_lock.release()
-
-
-    def update_domain(self, id):
-        """Update information for a single domain.
-
-        @param id: domain id
-        """
-        dominfo = self.xen_domain(id)
-        if dominfo:
-            d = self.domains.get(id)
-            if d:
-                d.update(dominfo)
-        else:
-            self._delete_domain(id)
+        doms = self.xen_domains()
+        for d in self.domains.values():
+            info = doms.get(d.getDomid())
+            if info:
+                d.update(info)
+            else:
+                self._delete_domain(d.getDomid())
+        for d in doms:
+            if d not in self.domains and not doms[d]['dying']:
+                try:
+                    dominfo = XendDomainInfo.recreate(doms[d])
+                    self._add_domain(dominfo)
+                except:
+                    if d == PRIV_DOMAIN:
+                        log.exception(
+                            "Failed to recreate information for domain "
+                            "%d.  Doing nothing except crossing my "
+                            "fingers.", d)
+                    else:
+                        log.exception(
+                            "Failed to recreate information for domain "
+                            "%d.  Destroying it in the hope of "
+                            "recovery.", d)
+                        try:
+                            xc.domain_destroy(dom = d)
+                        except:
+                            log.exception('Destruction of %d failed.', d)
 
 
     ## public:
@@ -233,9 +215,14 @@
         @param config: configuration
         @return: domain
         """
-        dominfo = XendDomainInfo.create(config)
-        self._add_domain(dominfo)
-        return dominfo
+        self.domains_lock.acquire()
+        try:
+            dominfo = XendDomainInfo.create(config)
+            self._add_domain(dominfo)
+            return dominfo
+        finally:
+            self.domains_lock.release()
+
 
     def domain_configure(self, config):
         """Configure an existing domain.
@@ -260,33 +247,72 @@
             raise XendError("can't read guest state file %s: %s" %
                             (src, ex[1]))
 
-    def domain_get(self, id):
-        """Get up-to-date info about a domain.
-
-        @param id: domain id
-        @return: domain object (or None)
-        """
-        self.update_domain(id)
-        return self.domains.get(id)
-
 
     def domain_lookup(self, id):
-        self.refresh()
-        return self.domains.get(id)
-
-    def domain_lookup_by_name(self, name):
-        dominfo = self.domains.get_by_name(name)
-        if not dominfo:
-            try:
-                id = int(name)
-                dominfo = self.domain_lookup(id)
-            except ValueError:
-                pass
-        return dominfo
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            return self.domains.get(id)
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_nr(self, id):
+        self.domains_lock.acquire()
+        try:
+            return self.domains.get(id)
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_by_name_or_id(self, name):
+        self.domains_lock.acquire()
+        try:
+            self.refresh()
+            return self.domain_lookup_by_name_or_id_nr(name)
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_by_name_or_id_nr(self, name):
+        self.domains_lock.acquire()
+        try:
+            dominfo = self.domain_lookup_by_name_nr(name)
+
+            if dominfo:
+                return dominfo
+            else:
+                try:
+                    return self.domains.get(int(name))
+                except ValueError:
+                    return None
+        finally:
+            self.domains_lock.release()
+
+
+    def domain_lookup_by_name_nr(self, name):
+        self.domains_lock.acquire()
+        try:
+            matching = filter(lambda d: d.getName() == name,
+                              self.domains.values())
+            n = len(matching)
+            if n == 1:
+                return matching[0]
+            elif n > 1:
+                raise XendError(
+                    'Name uniqueness has been violated for name %s' % name)
+            else:
+                return None
+        finally:
+            self.domains_lock.release()
 
 
     def privilegedDomain(self):
-        return self.domains[PRIV_DOMAIN]
+        self.domains_lock.acquire()
+        try:
+            return self.domains[PRIV_DOMAIN]
+        finally:
+            self.domains_lock.release()
 
  
     def domain_unpause(self, id):
@@ -321,12 +347,13 @@
 
         @param reason: shutdown reason: poweroff, reboot, suspend, halt
         """
-        self.callInfo(domid, XendDomainInfo.shutdown, reason)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.shutdown, reason)
 
 
     def domain_sysrq(self, domid, key):
         """Send a SysRq to the specified domain."""
-        return self.callInfo(domid, XendDomainInfo.send_sysrq, key)
+        return self.callInfo(domid, XendDomainInfo.XendDomainInfo.send_sysrq,
+                             key)
 
 
     def domain_destroy(self, domid):
@@ -449,32 +476,39 @@
     def domain_device_create(self, domid, devconfig):
         """Create a new device for the specified domain.
         """
-        return self.callInfo(domid, XendDomainInfo.device_create, devconfig)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.device_create,
+                             devconfig)
 
 
     def domain_device_configure(self, domid, devconfig, devid):
         """Configure an existing device in the specified domain.
         @return: updated device configuration
         """
-        return self.callInfo(domid, XendDomainInfo.device_configure,
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.device_configure,
                              devconfig, devid)
 
     
     def domain_device_refresh(self, domid, devtype, devid):
         """Refresh a device."""
-        return self.callInfo(domid, XendDomainInfo.device_refresh, devtype,
-                             devid)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.device_refresh,
+                             devtype, devid)
 
 
     def domain_device_destroy(self, domid, devtype, devid):
         """Destroy a device."""
-        return self.callInfo(domid, XendDomainInfo.destroyDevice, devtype,
-                             devid)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.destroyDevice,
+                             devtype, devid)
 
 
     def domain_devtype_ls(self, domid, devtype):
         """Get list of device sxprs for the specified domain."""
-        return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
+        return self.callInfo(domid,
+                             XendDomainInfo.XendDomainInfo.getDeviceSxprs,
+                             devtype)
 
 
     def domain_vif_limit_set(self, id, vif, credit, period):
@@ -518,7 +552,8 @@
 
         @param mem: memory target (in MiB)
         """
-        self.callInfo(domid, XendDomainInfo.setMemoryTarget, mem << 10)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.setMemoryTarget,
+                      mem << 10)
 
 
     def domain_vcpu_hotplug(self, domid, vcpu, state):
@@ -527,12 +562,13 @@
         @param vcpu: target VCPU in domain
         @param state: which state VCPU will become
         """
-        self.callInfo(domid, XendDomainInfo.vcpu_hotplug, vcpu, state)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.vcpu_hotplug, vcpu,
+                      state)
 
 
     def domain_dumpcore(self, domid):
         """Save a core dump for a crashed domain."""
-        self.callInfo(domid, XendDomainInfo.dumpCore)
+        self.callInfo(domid, XendDomainInfo.XendDomainInfo.dumpCore)
 
 
     ## private:
diff -r c70829a6edac -r 0e1838de9db8 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Oct  3 23:57:34 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Oct  4 01:21:28 2005
@@ -120,6 +120,68 @@
     ]
 
 
+def create(config):
+    """Create a VM from a configuration.
+
+    @param config    configuration
+    @raise: VmError for invalid configuration
+    """
+
+    log.debug("XendDomainInfo.create(%s)", config)
+
+    vm = XendDomainInfo(getUuid(), parseConfig(config))
+    vm.construct()
+    vm.refreshShutdown()
+    return vm
+
+
+def recreate(xeninfo):
+    """Create the VM object for an existing domain.  The domain must not
+    be dying, as the paths in the store should already have been removed,
+    and asking us to recreate them causes problems."""
+
+    log.debug("XendDomainInfo.recreate(%s)", xeninfo)
+
+    assert not xeninfo['dying']
+
+    domid = xeninfo['dom']
+    try:
+        dompath = GetDomainPath(domid)
+        if not dompath:
+            raise XendError(
+                'No domain path in store for existing domain %d' % domid)
+        vmpath = xstransact.Read(dompath, "vm")
+        if not vmpath:
+            raise XendError(
+                'No vm path in store for existing domain %d' % domid)
+        uuid = xstransact.Read(vmpath, "uuid")
+        if not uuid:
+            raise XendError(
+                'No vm/uuid path in store for existing domain %d' % domid)
+
+        log.info("Recreating domain %d, UUID %s.", domid, uuid)
+
+        vm = XendDomainInfo(uuid, xeninfo, domid, True)
+
+    except Exception, exn:
+        log.warn(str(exn))
+
+        uuid = getUuid()
+
+        log.info("Recreating domain %d with new UUID %s.", domid, uuid)
+
+        vm = XendDomainInfo(uuid, xeninfo, domid, True)
+        vm.storeVmDetails()
+        vm.storeDomDetails()
+
+    vm.create_channel()
+    if domid == 0:
+        vm.initStoreConnection()
+
+    vm.refreshShutdown(xeninfo)
+    return vm
+
+
 def restore(config):
     """Create a domain and a VM object to do a restore.
 
@@ -134,7 +196,7 @@
     except TypeError, exn:
         raise VmError('Invalid ssidref in config: %s' % exn)
 
-    vm = XendDomainInfo(uuid, XendDomainInfo.parseConfig(config),
+    vm = XendDomainInfo(uuid, parseConfig(config),
                         xc.domain_create(ssidref = ssidref))
     vm.storeVmDetails()
     vm.configure()
@@ -143,10 +205,87 @@
     return vm
 
 
-def domain_exists(name):
+def parseConfig(config):
+    def get_cfg(name, conv = None):
+        val = sxp.child_value(config, name)
+
+        if conv and not val is None:
+            try:
+                return conv(val)
+            except TypeError, exn:
+                raise VmError(
+                    'Invalid setting %s = %s in configuration: %s' %
+                    (name, val, str(exn)))
+        else:
+            return val
+
+
+    log.debug("parseConfig: config is %s" % str(config))
+
+    result = {}
+
+    for e in ROUNDTRIPPING_CONFIG_ENTRIES:
+        result[e[0]] = get_cfg(e[0], e[1])
+
+    result['memory']       = get_cfg('memory',     int)
+    result['mem_kb']       = get_cfg('mem_kb',     int)
+    result['maxmem']       = get_cfg('maxmem',     int)
+    result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
+    result['cpu']          = get_cfg('cpu',        int)
+    result['image']        = get_cfg('image')
+
+    try:
+        if result['image']:
+            result['vcpus'] = int(sxp.child_value(result['image'],
+                                                  'vcpus', 1))
+        else:
+            result['vcpus'] = 1
+    except TypeError, exn:
+        raise VmError(
+            'Invalid configuration setting: vcpus = %s: %s' %
+            (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
+
+    result['backend'] = []
+    for c in sxp.children(config, 'backend'):
+        result['backend'].append(sxp.name(sxp.child0(c)))
+
+    result['device'] = []
+    for d in sxp.children(config, 'device'):
+        c = sxp.child0(d)
+        result['device'].append((sxp.name(c), c))
+
+    # Configuration option "restart" is deprecated.  Parse it, but
+    # let on_xyz override it if they are present.
+    restart = get_cfg('restart')
+    if restart:
+        def handle_restart(event, val):
+            if not event in result:
+                result[event] = val
+
+        if restart == "onreboot":
+            handle_restart('on_poweroff', 'destroy')
+            handle_restart('on_reboot',   'restart')
+            handle_restart('on_crash',    'destroy')
+        elif restart == "always":
+            handle_restart('on_poweroff', 'restart')
+            handle_restart('on_reboot',   'restart')
+            handle_restart('on_crash',    'restart')
+        elif restart == "never":
+            handle_restart('on_poweroff', 'destroy')
+            handle_restart('on_reboot',   'destroy')
+            handle_restart('on_crash',    'destroy')
+        else:
+            log.warn("Ignoring malformed and deprecated config option "
+                     "restart = %s", restart)
+
+    log.debug("parseConfig: result is %s" % str(result))
+    return result
+
+
+def domain_by_name(name):
     # See comment in XendDomain constructor.
     xd = get_component('xen.xend.XendDomain')
-    return xd.domain_lookup_by_name(name)
+    return xd.domain_lookup_by_name_nr(name)
 
 def shutdown_reason(code):
     """Get a shutdown reason from a code.
@@ -181,152 +320,6 @@
     MINIMUM_RESTART_TIME = 20
 
 
-    def create(cls, config):
-        """Create a VM from a configuration.
-
-        @param config    configuration
-        @raise: VmError for invalid configuration
-        """
-
-        log.debug("XendDomainInfo.create(%s)", config)
-        
-        vm = cls(getUuid(), cls.parseConfig(config))
-        vm.construct()
-        vm.refreshShutdown()
-        return vm
-
-    create = classmethod(create)
-
-
-    def recreate(cls, xeninfo):
-        """Create the VM object for an existing domain.  The domain must not
-        be dying, as the paths in the store should already have been removed,
-        and asking us to recreate them causes problems."""
-
-        log.debug("XendDomainInfo.recreate(%s)", xeninfo)
-
-        assert not xeninfo['dying']
-
-        domid = xeninfo['dom']
-        try:
-            dompath = GetDomainPath(domid)
-            if not dompath:
-                raise XendError(
-                    'No domain path in store for existing domain %d' % domid)
-            vmpath = xstransact.Read(dompath, "vm")
-            if not vmpath:
-                raise XendError(
-                    'No vm path in store for existing domain %d' % domid)
-            uuid = xstransact.Read(vmpath, "uuid")
-            if not uuid:
-                raise XendError(
-                    'No vm/uuid path in store for existing domain %d' % domid)
-
-            log.info("Recreating domain %d, UUID %s.", domid, uuid)
-
-            vm = cls(uuid, xeninfo, domid, True)
-
-        except Exception, exn:
-            log.warn(str(exn))
-
-            uuid = getUuid()
-
-            log.info("Recreating domain %d with new UUID %s.", domid, uuid)
-
-            vm = cls(uuid, xeninfo, domid, True)
-            vm.storeVmDetails()
-            vm.storeDomDetails()
-
-        vm.create_channel()
-        if domid == 0:
-            vm.initStoreConnection()
-
-        vm.refreshShutdown(xeninfo)
-        return vm
-
-    recreate = classmethod(recreate)
-
-
-    def parseConfig(cls, config):
-        def get_cfg(name, conv = None):
-            val = sxp.child_value(config, name)
-
-            if conv and not val is None:
-                try:
-                    return conv(val)
-                except TypeError, exn:
-                    raise VmError(
-                        'Invalid setting %s = %s in configuration: %s' %
-                        (name, val, str(exn)))
-            else:
-                return val
-
-
-        log.debug("parseConfig: config is %s" % str(config))
-
-        result = {}
-
-        for e in ROUNDTRIPPING_CONFIG_ENTRIES:
-            result[e[0]] = get_cfg(e[0], e[1])
-
-        result['memory']       = get_cfg('memory',     int)
-        result['mem_kb']       = get_cfg('mem_kb',     int)
-        result['maxmem']       = get_cfg('maxmem',     int)
-        result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
-        result['cpu']          = get_cfg('cpu',        int)
-        result['image']        = get_cfg('image')
-
-        try:
-            if result['image']:
-                result['vcpus'] = int(sxp.child_value(result['image'],
-                                                      'vcpus', 1))
-            else:
-                result['vcpus'] = 1
-        except TypeError, exn:
-            raise VmError(
-                'Invalid configuration setting: vcpus = %s: %s' %
-                (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
-
-        result['backend'] = []
-        for c in sxp.children(config, 'backend'):
-            result['backend'].append(sxp.name(sxp.child0(c)))
-
-        result['device'] = []
-        for d in sxp.children(config, 'device'):
-            c = sxp.child0(d)
-            result['device'].append((sxp.name(c), c))
-
-        # Configuration option "restart" is deprecated.  Parse it, but
-        # let on_xyz override it if they are present.
-        restart = get_cfg('restart')
-        if restart:
-            def handle_restart(event, val):
-                if not event in result:
-                    result[event] = val
-
-            if restart == "onreboot":
-                handle_restart('on_poweroff', 'destroy')
-                handle_restart('on_reboot',   'restart')
-                handle_restart('on_crash',    'destroy')
-            elif restart == "always":
-                handle_restart('on_poweroff', 'restart')
-                handle_restart('on_reboot',   'restart')
-                handle_restart('on_crash',    'restart')
-            elif restart == "never":
-                handle_restart('on_poweroff', 'destroy')
-                handle_restart('on_reboot',   'destroy')
-                handle_restart('on_crash',    'destroy')
-            else:
-                log.warn("Ignoring malformed and deprecated config option "
-                         "restart = %s", restart)
-
-        log.debug("parseConfig: result is %s" % str(result))
-        return result
-
-
-    parseConfig = classmethod(parseConfig)
-
-    
     def __init__(self, uuid, info, domid = None, augment = False):
 
         self.uuid = uuid
@@ -957,10 +950,8 @@
             if c in '_-.:/+': continue
             if c in string.ascii_letters: continue
             raise VmError('invalid vm name')
-        dominfo = domain_exists(name)
-        # When creating or rebooting, a domain with my name should not exist.
-        # When restoring, a domain with my name will exist, but it should have
-        # my domain id.
+
+        dominfo = domain_by_name(name)
         if not dominfo:
             return
         if dominfo.is_terminated():
diff -r c70829a6edac -r 0e1838de9db8 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Mon Oct  3 23:57:34 2005
+++ b/tools/python/xen/xend/server/DevController.py     Tue Oct  4 01:21:28 2005
@@ -193,7 +193,7 @@
 
         backdom_name = sxp.child_value(config, 'backend')
         if backdom_name:
-            backdom = xd.domain_lookup_by_name(backdom_name)
+            backdom = xd.domain_lookup_by_name_or_id_nr(backdom_name)
         else:
             backdom = xd.privilegedDomain()
 
diff -r c70829a6edac -r 0e1838de9db8 
tools/python/xen/xend/server/SrvDomainDir.py
--- a/tools/python/xen/xend/server/SrvDomainDir.py      Mon Oct  3 23:57:34 2005
+++ b/tools/python/xen/xend/server/SrvDomainDir.py      Tue Oct  4 01:21:28 2005
@@ -38,7 +38,7 @@
         self.xd = XendDomain.instance()
 
     def domain(self, x):
-        dom = self.xd.domain_lookup_by_name(x)
+        dom = self.xd.domain_lookup_by_name_or_id(x)
         if not dom:
             raise XendError('No such domain ' + str(x))
         return SrvDomain(dom)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.