Mailing List Archive

Fix deadlock in XendDomainInfo when a domain is cleaned up. We are renaming
# HG changeset patch
# User emellor@ewan
# Node ID 067b9aacb6c2c0920829f925352d66b4783b8f2c
# Parent 00a24908057f3b5db5669be346ba41cb10367362
Fix deadlock in XendDomainInfo when a domain is cleaned up. We are renaming
the domain, to make it clear that it is a zombie, but this renaming cannot
check the uniqueness of the new name, because this causes a deadlock with
XendDomain. Instead, we allow the name to be non-unique for the case of
zombie domains.

Change the locking in waitForShutdown and state_set to be robust in the face of
exceptions.

Rename the STATE_VM_ constants to STATE_DOM_.

Signed-off-by: Ewan Mellor <ewan@xensource.com>

diff -r 00a24908057f -r 067b9aacb6c2 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Wed Oct 12 09:08:01 2005
+++ b/tools/python/xen/xend/XendDomain.py Wed Oct 12 09:11:35 2005
@@ -57,7 +57,7 @@
# So we stuff the XendDomain instance (self) into xroot's components.
xroot.add_component("xen.xend.XendDomain", self)
self.domains = {}
- self.domains_lock = threading.Condition()
+ self.domains_lock = threading.RLock()
self.watchReleaseDomain()

self.domains_lock.acquire()
@@ -318,7 +318,7 @@
n = len(matching)
if n == 1:
return matching[0]
- elif n > 1:
+ elif n > 1 and not d.isTerminated():
log.error('Name uniqueness has been violated for name %s! '
'Recovering by renaming:', name)
for d in matching:
diff -r 00a24908057f -r 067b9aacb6c2 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Wed Oct 12 09:08:01 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Wed Oct 12 09:11:35 2005
@@ -78,8 +78,8 @@
"rename-restart"
]

-STATE_VM_OK = "ok"
-STATE_VM_TERMINATED = "terminated"
+STATE_DOM_OK = 1
+STATE_DOM_SHUTDOWN = 2

"""Flag for a block device backend domain."""
SIF_BLK_BE_DOMAIN = (1<<4)
@@ -293,7 +293,7 @@
restart = get_cfg('restart')
if restart:
def handle_restart(event, val):
- if not event in result:
+ if result[event] is None:
result[event] = val

if restart == "onreboot":
@@ -384,7 +384,7 @@
self.console_channel = None
self.console_mfn = None

- self.state = STATE_VM_OK
+ self.state = STATE_DOM_OK
self.state_updated = threading.Condition()
self.refresh_shutdown_lock = threading.Condition()

@@ -708,7 +708,7 @@
self.clearRestart()

if reason == 'suspend':
- self.state_set(STATE_VM_TERMINATED)
+ self.state_set(STATE_DOM_SHUTDOWN)
# Don't destroy the domain. XendCheckpoint will do
# this once it has finished.
elif reason in ['poweroff', 'reboot']:
@@ -821,19 +821,31 @@

def state_set(self, state):
self.state_updated.acquire()
- if self.state != state:
- self.state = state
- self.state_updated.notifyAll()
- self.state_updated.release()
+ try:
+ if self.state != state:
+ self.state = state
+ self.state_updated.notifyAll()
+ finally:
+ self.state_updated.release()


## public:

def waitForShutdown(self):
self.state_updated.acquire()
- while self.state == STATE_VM_OK:
- self.state_updated.wait()
- self.state_updated.release()
+ try:
+ while self.state == STATE_DOM_OK:
+ self.state_updated.wait()
+ finally:
+ self.state_updated.release()
+
+
+ def isShutdown(self):
+ self.state_updated.acquire()
+ try:
+ return self.state == STATE_DOM_SHUTDOWN
+ finally:
+ self.state_updated.release()


def __str__(self):
@@ -1065,11 +1077,11 @@

try:
if not self.info['name'].startswith(ZOMBIE_PREFIX):
- self.info['name'] = self.generateZombieName()
+ self.info['name'] = ZOMBIE_PREFIX + self.info['name']
except:
log.exception("Renaming Zombie failed.")

- self.state_set(STATE_VM_TERMINATED)
+ self.state_set(STATE_DOM_SHUTDOWN)


def cleanupVm(self):
@@ -1274,7 +1286,7 @@
log.info("Preserving dead domain %s (%d).", self.info['name'],
self.domid)
self.storeDom('xend/shutdown_completed', 'True')
- self.state_set(STATE_VM_TERMINATED)
+ self.state_set(STATE_DOM_SHUTDOWN)


## public:
@@ -1302,18 +1314,6 @@
return name
except VmError:
n += 1
-
-
- def generateZombieName(self):
- n = 0
- name = ZOMBIE_PREFIX + self.info['name']
- while True:
- try:
- self.check_name(name)
- return name
- except VmError:
- n += 1
- name = "%s%d-%s" % (ZOMBIE_PREFIX, n, self.info['name'])


def configure_bootloader(self):

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