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>
This commit is contained in:
kfraser@localhost.localdomain committed 2007-05-24 15:21:29 +01:00
1 parent 26e96c98bc
commit be422ace19
1 file changed
+29 -20
+29 -20
View File
@@ -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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.