ia64/xen-unstable

changeset 15212:3ef4a4d82130

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>
author kfraser@localhost.localdomain
date Thu May 24 15:21:29 2007 +0100 (2007-05-24)
parents 6a4af9502b4d
children 588bd40872ec
files tools/python/xen/xend/XendDomainInfo.py
line diff
     1.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu May 24 15:13:13 2007 +0100
     1.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu May 24 15:21:29 2007 +0100
     1.3 @@ -546,20 +546,30 @@ class XendDomainInfo:
     1.4              self.getDeviceController(devclass).waitForDevices()
     1.5  
     1.6      def destroyDevice(self, deviceClass, devid, force = False):
     1.7 +        found = True                    # Assume devid is an integer.
     1.8          try:
     1.9              devid = int(devid)
    1.10          except ValueError:
    1.11              # devid is not a number, let's search for it in xenstore.
    1.12              devicePath = '%s/device/%s' % (self.dompath, deviceClass)
    1.13 +            found = False
    1.14              for entry in xstransact.List(devicePath):
    1.15 +                log.debug("Attempting to find devid at %s/%s", devicePath, entry)
    1.16                  backend = xstransact.Read('%s/%s' % (devicePath, entry),
    1.17                                            "backend")
    1.18 -                devName = xstransact.Read(backend, "dev")
    1.19 -                if devName == devid:
    1.20 -                    # We found the integer matching our devid, use it instead
    1.21 -                    devid = entry
    1.22 -                    break
    1.23 -                
    1.24 +                if backend != None:
    1.25 +                    devName = '%s/%s' % (deviceClass, entry)
    1.26 +                    log.debug("devName=%s", devName)
    1.27 +                    if devName == devid:
    1.28 +                        # We found the integer matching our devid, use it instead
    1.29 +                        devid = int(entry)
    1.30 +                        found = True
    1.31 +                        break
    1.32 +
    1.33 +        if not found:
    1.34 +            log.debug("Could not find the device %s", devid)
    1.35 +            return None
    1.36 +        log.debug("devid = %s", devid)
    1.37          return self.getDeviceController(deviceClass).destroyDevice(devid, force)
    1.38  
    1.39      def getDeviceSxprs(self, deviceClass):
    1.40 @@ -1338,20 +1348,19 @@ class XendDomainInfo:
    1.41              self.image.destroy(suspend)
    1.42              return
    1.43  
    1.44 -        while True:
    1.45 -            t = xstransact("%s/device" % self.dompath)
    1.46 -            for devclass in XendDevices.valid_devices():
    1.47 -                for dev in t.list(devclass):
    1.48 -                    try:
    1.49 -                        t.remove(dev)
    1.50 -                    except:
    1.51 -                        # Log and swallow any exceptions in removal --
    1.52 -                        # there's nothing more we can do.
    1.53 -                        log.exception(
    1.54 -                           "Device release failed: %s; %s; %s",
    1.55 -                           self.info['name_label'], devclass, dev)
    1.56 -            if t.commit():
    1.57 -                break
    1.58 +        t = xstransact("%s/device" % self.dompath)
    1.59 +        for devclass in XendDevices.valid_devices():
    1.60 +            for dev in t.list(devclass):
    1.61 +                try:
    1.62 +                    log.debug("Removing %s", dev);
    1.63 +                    self.destroyDevice(devclass, dev, False);
    1.64 +                except:
    1.65 +                    # Log and swallow any exceptions in removal --
    1.66 +                    # there's nothing more we can do.
    1.67 +                        log.exception("Device release failed: %s; %s; %s",
    1.68 +                                      self.info['name_label'], devclass, dev)
    1.69 +
    1.70 +            
    1.71  
    1.72      def getDeviceController(self, name):
    1.73          """Get the device controller for this domain, and if it