ia64/xen-unstable
changeset 15307:31ee1768e911
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@sun.com>
*-detach will wait till device is detached or time'ed out.
XendConfig will be updated, if detached.
Signed-off-by: Max Zhen <max.zhen@sun.com>
author | kfraser@localhost.localdomain |
---|---|
date | Mon Jun 11 10:21:11 2007 +0100 (2007-06-11) |
parents | 6f06bd06ef47 |
children | ebe4140fe4f8 |
files | tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/DevController.py |
line diff
1.1 --- a/tools/python/xen/xend/XendConfig.py Mon Jun 11 10:16:54 2007 +0100 1.2 +++ b/tools/python/xen/xend/XendConfig.py Mon Jun 11 10:21:11 2007 +0100 1.3 @@ -1268,6 +1268,21 @@ class XendConfig(dict): 1.4 1.5 return False 1.6 1.7 + def device_remove(self, dev_uuid): 1.8 + """Remove an existing device referred by dev_uuid. 1.9 + """ 1.10 + 1.11 + if dev_uuid in self['devices']: 1.12 + dev_config = self['devices'].get(dev_uuid) 1.13 + dev_type = dev_config[0] 1.14 + 1.15 + del self['devices'][dev_uuid] 1.16 + # Remove dev references for certain device types (see device_add) 1.17 + if dev_type in ('vif', 'vbd', 'vtpm'): 1.18 + param = '%s_refs' % dev_type 1.19 + if param in self: 1.20 + if dev_uuid in self[param]: 1.21 + self[param].remove(dev_uuid) 1.22 1.23 def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None): 1.24 """Get Device SXPR by either giving the device UUID or (type, config).
2.1 --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jun 11 10:16:54 2007 +0100 2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Jun 11 10:21:11 2007 +0100 2.3 @@ -557,7 +557,23 @@ class XendDomainInfo: 2.4 return None 2.5 2.6 log.debug("dev = %s", dev) 2.7 - return self.getDeviceController(deviceClass).destroyDevice(dev, force) 2.8 + 2.9 + dev_control = self.getDeviceController(deviceClass) 2.10 + dev_uuid = dev_control.readBackend(dev, 'uuid') 2.11 + 2.12 + ret = None 2.13 + 2.14 + try: 2.15 + ret = dev_control.destroyDevice(dev, force) 2.16 + except EnvironmentError: 2.17 + # We failed to detach the device 2.18 + raise VmError("Failed to detach device %d" % dev) 2.19 + 2.20 + # update XendConfig 2.21 + if dev_uuid: 2.22 + self.info.device_remove(dev_uuid) 2.23 + 2.24 + return ret 2.25 2.26 def getDeviceSxprs(self, deviceClass): 2.27 if self._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): 2.28 @@ -571,7 +587,6 @@ class XendDomainInfo: 2.29 dev_num += 1 2.30 return sxprs 2.31 2.32 - 2.33 def setMemoryTarget(self, target): 2.34 """Set the memory target of this domain. 2.35 @param target: In MiB.
3.1 --- a/tools/python/xen/xend/server/DevController.py Mon Jun 11 10:16:54 2007 +0100 3.2 +++ b/tools/python/xen/xend/server/DevController.py Mon Jun 11 10:21:11 2007 +0100 3.3 @@ -29,6 +29,7 @@ from xen.xend.xenstore.xswatch import xs 3.4 import os 3.5 3.6 DEVICE_CREATE_TIMEOUT = 100 3.7 +DEVICE_DESTROY_TIMEOUT = 10 3.8 HOTPLUG_STATUS_NODE = "hotplug-status" 3.9 HOTPLUG_ERROR_NODE = "hotplug-error" 3.10 HOTPLUG_STATUS_ERROR = "error" 3.11 @@ -211,17 +212,34 @@ class DevController: 3.12 3.13 devid = int(devid) 3.14 3.15 + frontpath = self.frontendPath(devid) 3.16 + if frontpath: 3.17 + backpath = xstransact.Read(frontpath, "backend") 3.18 + 3.19 # Modify online status /before/ updating state (latter is watched by 3.20 # drivers, so this ordering avoids a race). 3.21 self.writeBackend(devid, 'online', "0") 3.22 self.writeBackend(devid, 'state', str(xenbusState['Closing'])) 3.23 3.24 if force: 3.25 - frontpath = self.frontendPath(devid) 3.26 - backpath = xstransact.Read(frontpath, "backend") 3.27 if backpath: 3.28 xstransact.Remove(backpath) 3.29 - xstransact.Remove(frontpath) 3.30 + if frontpath: 3.31 + xstransact.Remove(frontpath) 3.32 + return 3.33 + 3.34 + # Wait till both frontpath and backpath are removed from 3.35 + # xenstore, or timed out 3.36 + if frontpath: 3.37 + status = self.waitUntilDestroyed(frontpath) 3.38 + if status == Timeout: 3.39 + # Exception will be caught by destroyDevice in XendDomainInfo.py 3.40 + raise EnvironmentError 3.41 + if backpath: 3.42 + status = self.waitUntilDestroyed(backpath) 3.43 + if status == Timeout: 3.44 + # Exception will be caught by destroyDevice in XendDomainInfo.py 3.45 + raise EnvironmentError 3.46 3.47 self.vm._removeVm("device/%s/%d" % (self.deviceClass, devid)) 3.48 3.49 @@ -508,6 +526,16 @@ class DevController: 3.50 return (Missing, None) 3.51 3.52 3.53 + def waitUntilDestroyed(self, path): 3.54 + ev = Event() 3.55 + result = { 'path': path, 'status': Timeout } 3.56 + 3.57 + xswatch(path, destroyCallback, ev, result) 3.58 + 3.59 + ev.wait(DEVICE_DESTROY_TIMEOUT) 3.60 + return result['status'] 3.61 + 3.62 + 3.63 def backendPath(self, backdom, devid): 3.64 """Construct backend path given the backend domain and device id. 3.65 3.66 @@ -537,6 +565,18 @@ class DevController: 3.67 self.deviceClass) 3.68 3.69 3.70 +def destroyCallback(devPath, ev, result): 3.71 + log.debug("destroyCallback %s.", devPath) 3.72 + 3.73 + list = xstransact.List(result['path']) 3.74 + if list: 3.75 + return 1 3.76 + 3.77 + result['status'] = Missing 3.78 + ev.set() 3.79 + log.debug("destroyCallback %s is destroyed", result['path']) 3.80 + return 0 3.81 + 3.82 def hotplugStatusCallback(statusPath, ev, result): 3.83 log.debug("hotplugStatusCallback %s.", statusPath) 3.84