105 lines
4.7 KiB
Diff
105 lines
4.7 KiB
Diff
# HG changeset patch
|
|
# User kfraser@localhost.localdomain
|
|
# Date 1180016489 -3600
|
|
# Node ID 3ef4a4d8213061fe14d905e89594c99d0b9cb605
|
|
# Parent 6a4af9502b4da269388a60416a7cca0ecadb3bb3
|
|
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>
|
|
|
|
Index: xen-3.1-testing/tools/python/xen/xend/XendDomainInfo.py
|
|
===================================================================
|
|
--- xen-3.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
|
|
+++ xen-3.1-testing/tools/python/xen/xend/XendDomainInfo.py
|
|
@@ -544,20 +544,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):
|
|
@@ -1330,20 +1340,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
|