aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-05-24 15:21:29 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-05-24 15:21:29 +0100
commitbe422ace19118d2bf8415bfcaeda9fdf06b50bd4 (patch)
tree83de32092d8532a4462e981303ac64fef4f7a4f7
parent26e96c98bc70466a5f366d4baf9b58f0b0365fb8 (diff)
downloadxen-be422ace19118d2bf8415bfcaeda9fdf06b50bd4.tar.gz
xen-be422ace19118d2bf8415bfcaeda9fdf06b50bd4.tar.bz2
xen-be422ace19118d2bf8415bfcaeda9fdf06b50bd4.zip
xend: Fix for removing devices at save/destroy domain.
The function XendDomainInfo:_releaseDevices() is called during the save/destroy phase of a domain. It made some attempt to clean up the devices, but wasn't complete, leaving dangling devices in the xenstore. Not a big problem with normal use of Xen, but a buildup over a large number of save/destroy instances, it would make the xenstore database grow quite large, which in turn meant swap-thrashing in Dom0. This patch makes use of the destroyDevices() function in XendDomainInfo. This function needed some re-writing to make it work correctly - I think it had some old code (not sure how old, as xm annotate says that it's changeset 12071, but that, I think, is when it was split out from XendDomain.py, rather than when it was created). I have tested this over a few hundred save/restore cycles [two domains constantly saved/restored with a short sleep to let them process some work] combined with a loop of "xenstore-ls|wc". The output of the latter is pretty much constant (it obviously varies a bit depending on when in the save/restore cycle it hits). Previously, it would increase by some 10 lines or so per save/restore cycle. Signed-off-by: Mats Petersson <mats.petersson@amd.com>
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py49
1 files changed, 29 insertions, 20 deletions
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index 7bb71bc93d..800bdbe6d6 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -546,20 +546,30 @@ class XendDomainInfo:
self.getDeviceController(devclass).waitForDevices()
def destroyDevice(self, deviceClass, devid, force = False):
+ found = True # Assume devid is an integer.
try:
devid = int(devid)
except ValueError:
# devid is not a number, let's search for it in xenstore.
devicePath = '%s/device/%s' % (self.dompath, deviceClass)
+ found = False
for entry in xstransact.List(devicePath):
+ log.debug("Attempting to find devid at %s/%s", devicePath, entry)
backend = xstransact.Read('%s/%s' % (devicePath, entry),
"backend")
- devName = xstransact.Read(backend, "dev")
- if devName == devid:
- # We found the integer matching our devid, use it instead
- devid = entry
- break
-
+ if backend != None:
+ devName = '%s/%s' % (deviceClass, entry)
+ log.debug("devName=%s", devName)
+ if devName == devid:
+ # We found the integer matching our devid, use it instead
+ devid = int(entry)
+ found = True
+ break
+
+ if not found:
+ log.debug("Could not find the device %s", devid)
+ return None
+ log.debug("devid = %s", devid)
return self.getDeviceController(deviceClass).destroyDevice(devid, force)
def getDeviceSxprs(self, deviceClass):
@@ -1338,20 +1348,19 @@ class XendDomainInfo:
self.image.destroy(suspend)
return
- while True:
- t = xstransact("%s/device" % self.dompath)
- for devclass in XendDevices.valid_devices():
- for dev in t.list(devclass):
- try:
- t.remove(dev)
- except:
- # Log and swallow any exceptions in removal --
- # there's nothing more we can do.
- log.exception(
- "Device release failed: %s; %s; %s",
- self.info['name_label'], devclass, dev)
- if t.commit():
- break
+ t = xstransact("%s/device" % self.dompath)
+ for devclass in XendDevices.valid_devices():
+ for dev in t.list(devclass):
+ try:
+ log.debug("Removing %s", dev);
+ self.destroyDevice(devclass, dev, False);
+ except:
+ # Log and swallow any exceptions in removal --
+ # there's nothing more we can do.
+ log.exception("Device release failed: %s; %s; %s",
+ self.info['name_label'], devclass, dev)
+
+
def getDeviceController(self, name):
"""Get the device controller for this domain, and if it