diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-05-24 15:21:29 +0100 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-05-24 15:21:29 +0100 |
commit | be422ace19118d2bf8415bfcaeda9fdf06b50bd4 (patch) | |
tree | 83de32092d8532a4462e981303ac64fef4f7a4f7 | |
parent | 26e96c98bc70466a5f366d4baf9b58f0b0365fb8 (diff) | |
download | xen-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.py | 49 |
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 |