[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xend: Make device detach wait for detach to complete.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1181553671 -3600 # Node ID 31ee1768e911336c227d13fd1519961d07cdc562 # Parent 6f06bd06ef473726b4132e6fe95309fce6963fd5 xend: Make device detach wait for detach to complete. *-detach will wait till device is detached or time'ed out. XendConfig will be updated, if detached. Signed-off-by: Max Zhen <max.zhen@xxxxxxx> --- tools/python/xen/xend/XendConfig.py | 15 ++++++++ tools/python/xen/xend/XendDomainInfo.py | 19 +++++++++- tools/python/xen/xend/server/DevController.py | 46 ++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 5 deletions(-) diff -r 6f06bd06ef47 -r 31ee1768e911 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Mon Jun 11 10:16:54 2007 +0100 +++ b/tools/python/xen/xend/XendConfig.py Mon Jun 11 10:21:11 2007 +0100 @@ -1268,6 +1268,21 @@ class XendConfig(dict): return False + def device_remove(self, dev_uuid): + """Remove an existing device referred by dev_uuid. + """ + + if dev_uuid in self['devices']: + dev_config = self['devices'].get(dev_uuid) + dev_type = dev_config[0] + + del self['devices'][dev_uuid] + # Remove dev references for certain device types (see device_add) + if dev_type in ('vif', 'vbd', 'vtpm'): + param = '%s_refs' % dev_type + if param in self: + if dev_uuid in self[param]: + self[param].remove(dev_uuid) def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None): """Get Device SXPR by either giving the device UUID or (type, config). diff -r 6f06bd06ef47 -r 31ee1768e911 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jun 11 10:16:54 2007 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Jun 11 10:21:11 2007 +0100 @@ -557,7 +557,23 @@ class XendDomainInfo: return None log.debug("dev = %s", dev) - return self.getDeviceController(deviceClass).destroyDevice(dev, force) + + dev_control = self.getDeviceController(deviceClass) + dev_uuid = dev_control.readBackend(dev, 'uuid') + + ret = None + + try: + ret = dev_control.destroyDevice(dev, force) + except EnvironmentError: + # We failed to detach the device + raise VmError("Failed to detach device %d" % dev) + + # update XendConfig + if dev_uuid: + self.info.device_remove(dev_uuid) + + return ret def getDeviceSxprs(self, deviceClass): if self._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): @@ -570,7 +586,6 @@ class XendDomainInfo: sxprs.append([dev_num, dev_info]) dev_num += 1 return sxprs - def setMemoryTarget(self, target): """Set the memory target of this domain. diff -r 6f06bd06ef47 -r 31ee1768e911 tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py Mon Jun 11 10:16:54 2007 +0100 +++ b/tools/python/xen/xend/server/DevController.py Mon Jun 11 10:21:11 2007 +0100 @@ -29,6 +29,7 @@ import os import os DEVICE_CREATE_TIMEOUT = 100 +DEVICE_DESTROY_TIMEOUT = 10 HOTPLUG_STATUS_NODE = "hotplug-status" HOTPLUG_ERROR_NODE = "hotplug-error" HOTPLUG_STATUS_ERROR = "error" @@ -211,17 +212,34 @@ class DevController: devid = int(devid) + frontpath = self.frontendPath(devid) + if frontpath: + backpath = xstransact.Read(frontpath, "backend") + # Modify online status /before/ updating state (latter is watched by # drivers, so this ordering avoids a race). self.writeBackend(devid, 'online', "0") self.writeBackend(devid, 'state', str(xenbusState['Closing'])) if force: - frontpath = self.frontendPath(devid) - backpath = xstransact.Read(frontpath, "backend") if backpath: xstransact.Remove(backpath) - xstransact.Remove(frontpath) + if frontpath: + xstransact.Remove(frontpath) + return + + # Wait till both frontpath and backpath are removed from + # xenstore, or timed out + if frontpath: + status = self.waitUntilDestroyed(frontpath) + if status == Timeout: + # Exception will be caught by destroyDevice in XendDomainInfo.py + raise EnvironmentError + if backpath: + status = self.waitUntilDestroyed(backpath) + if status == Timeout: + # Exception will be caught by destroyDevice in XendDomainInfo.py + raise EnvironmentError self.vm._removeVm("device/%s/%d" % (self.deviceClass, devid)) @@ -508,6 +526,16 @@ class DevController: return (Missing, None) + def waitUntilDestroyed(self, path): + ev = Event() + result = { 'path': path, 'status': Timeout } + + xswatch(path, destroyCallback, ev, result) + + ev.wait(DEVICE_DESTROY_TIMEOUT) + return result['status'] + + def backendPath(self, backdom, devid): """Construct backend path given the backend domain and device id. @@ -537,6 +565,18 @@ class DevController: self.deviceClass) +def destroyCallback(devPath, ev, result): + log.debug("destroyCallback %s.", devPath) + + list = xstransact.List(result['path']) + if list: + return 1 + + result['status'] = Missing + ev.set() + log.debug("destroyCallback %s is destroyed", result['path']) + return 0 + def hotplugStatusCallback(statusPath, ev, result): log.debug("hotplugStatusCallback %s.", statusPath) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |