diff -Nura xen-unstable.orig/tools/examples/xend-config.sxp xen-unstable/tools/examples/xend-config.sxp --- xen-unstable.orig/tools/examples/xend-config.sxp 2008-08-06 17:26:37.000000000 +0800 +++ xen-unstable/tools/examples/xend-config.sxp 2008-08-06 17:28:45.000000000 +0800 @@ -63,6 +63,12 @@ #(xend-unix-path /var/lib/xend/xend-socket) +# External locking utility for get/release domain running lock. By default, +# no utility is specified. Thus there will be no lock as VM running. +# The locking utility should accept: +# <--lock | --unlock> --name --uuid +# command line options, and returns zero on success, others on error. +#(xend-domains-lock-path '') # Address and port xend should use for the legacy TCP XMLRPC interface, # if xend-tcp-xmlrpc-server is set. diff -Nura xen-unstable.orig/tools/python/xen/xend/XendDomainInfo.py xen-unstable/tools/python/xen/xend/XendDomainInfo.py --- xen-unstable.orig/tools/python/xen/xend/XendDomainInfo.py 2008-08-06 17:26:39.000000000 +0800 +++ xen-unstable/tools/python/xen/xend/XendDomainInfo.py 2008-08-06 17:31:27.000000000 +0800 @@ -328,6 +328,8 @@ @type state_updated: threading.Condition @ivar refresh_shutdown_lock: lock for polling shutdown state @type refresh_shutdown_lock: threading.Condition + @ivar running_lock: lock for running VM + @type running_lock: bool or None @ivar _deviceControllers: device controller cache for this domain @type _deviceControllers: dict 'string' to DevControllers """ @@ -395,6 +397,8 @@ self.refresh_shutdown_lock = threading.Condition() self._stateSet(DOM_STATE_HALTED) + self.running_lock = None + self._deviceControllers = {} for state in DOM_STATES_OLD: @@ -421,6 +425,7 @@ if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED, XEN_API_VM_POWER_STATE_SUSPENDED, XEN_API_VM_POWER_STATE_CRASHED): try: + self.acquire_running_lock(); XendTask.log_progress(0, 30, self._constructDomain) XendTask.log_progress(31, 60, self._initDomain) @@ -453,6 +458,7 @@ state = self._stateGet() if state in (DOM_STATE_SUSPENDED, DOM_STATE_HALTED): try: + self.acquire_running_lock(); self._constructDomain() self._storeVmDetails() self._createDevices() @@ -2292,6 +2298,11 @@ self._stateSet(DOM_STATE_HALTED) self.domid = None # Do not push into _stateSet()! + + try: + self.release_running_lock() + except: + log.exception("Release running lock failed: %s" % status) finally: self.refresh_shutdown_lock.release() @@ -3520,6 +3531,28 @@ def has_device(self, dev_class, dev_uuid): return (dev_uuid in self.info['%s_refs' % dev_class.lower()]) + def acquire_running_lock(self): + if not self.running_lock: + lock_path = xoptions.get_xend_domains_lock_path() + if lock_path: + status = os.system('%s --lock --name %s --uuid %s' % \ + (lock_path, self.info['name_label'], self.info['uuid'])) + if status == 0: + self.running_lock = True + else: + raise XendError('Acquire running lock failed: %s' % status) + + def release_running_lock(self): + if self.running_lock: + lock_path = xoptions.get_xend_domains_lock_path() + if lock_path: + status = os.system('%s --unlock --name %s --uuid %s' % \ + (lock_path, self.info['name_label'], self.info['uuid'])) + if status == 0: + self.running_lock = False + else: + raise XendError('Release running lock failed: %s' % status) + def __str__(self): return '' % \ (str(self.domid), self.info['name_label'], diff -Nura xen-unstable.orig/tools/python/xen/xend/XendDomain.py xen-unstable/tools/python/xen/xend/XendDomain.py --- xen-unstable.orig/tools/python/xen/xend/XendDomain.py 2008-08-06 17:26:39.000000000 +0800 +++ xen-unstable/tools/python/xen/xend/XendDomain.py 2008-08-06 17:30:23.000000000 +0800 @@ -1295,6 +1295,7 @@ POWER_STATE_NAMES[dominfo._stateGet()]) """ The following call may raise a XendError exception """ + dominfo.release_running_lock(); dominfo.testMigrateDevices(True, dst) if live: diff -Nura xen-unstable.orig/tools/python/xen/xend/XendOptions.py xen-unstable/tools/python/xen/xend/XendOptions.py --- xen-unstable.orig/tools/python/xen/xend/XendOptions.py 2008-08-06 17:26:39.000000000 +0800 +++ xen-unstable/tools/python/xen/xend/XendOptions.py 2008-08-06 17:28:45.000000000 +0800 @@ -271,6 +271,11 @@ """ return self.get_config_string("xend-domains-path", self.xend_domains_path_default) + def get_xend_domains_lock_path(self): + """ Get the path of the lock utility for running domains. + """ + return self.get_config_string("xend-domains-lock-path") + def get_xend_state_path(self): """ Get the path for persistent domain configuration storage """