diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 54ef911a91..8c6a4e182f 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -347,6 +347,19 @@ class XendDomain: self.domains_lock.release() + def domain_lookup_by_uuid_nr(self, uuid): + self.domains_lock.acquire() + try: + matching = filter(lambda d: d.getUuid() == uuid, + self.domains.values()) + n = len(matching) + if n == 1: + return matching[0] + return None + finally: + self.domains_lock.release() + + def privilegedDomain(self): self.domains_lock.acquire() try: diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 665eb927d3..b100a7d557 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -396,6 +396,10 @@ def domain_by_name(name): return XendDomain.instance().domain_lookup_by_name_nr(name) +def domain_by_uuid(uuid): + return XendDomain.instance().domain_lookup_by_uuid_nr(uuid) + + def shutdown_reason(code): """Get a shutdown reason from a code. @@ -581,6 +585,7 @@ class XendDomainInfo: defaultInfo('security', lambda: None) self.check_name(self.info['name']) + self.check_uuid(self.info['uuid']) if isinstance(self.info['image'], str): self.info['image'] = sxp.from_string(self.info['image']) @@ -778,6 +783,9 @@ class XendDomainInfo: def getName(self): return self.info['name'] + def getUuid(self): + return self.info['uuid'] + def getDomainPath(self): return self.dompath @@ -1207,6 +1215,23 @@ class XendDomainInfo: (name, self.domid, dominfo.domid)) + def check_uuid(self, uuid): + """The same uuid cannot be used for more than one vm at the same time. + + @param uuid: uuid + @raise: VmError if same uuid is used + """ + dominfo = domain_by_uuid(uuid) + if not dominfo: + return + if self.domid is None: + raise VmError("uuid '%s' already in use by domain %d" % + (uuid, dominfo.domid)) + if dominfo.domid != self.domid: + raise VmError("uuid '%s' is used in both domains %d and %d" % + (uuid, self.domid, dominfo.domid)) + + def construct(self): """Construct the domain.