[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Fix xm block/network-detach command.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1186672901 -3600 # Node ID 95f90f24f3b1f33f911d3e9a01cb1d7bce5b29e0 # Parent f0298301ba8b34ac3e5470cf953a3591f7730d26 Fix xm block/network-detach command. - To remove device info, it waits for the backend path of the device to be removed. - It removes device info from domain info. - It saves domain info to the config.sxp of the managed domain. Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx> --- tools/python/xen/xend/XendDomainInfo.py | 82 +++++++++++++++++++++++++- tools/python/xen/xend/server/DevController.py | 71 ++++++++++++++++++---- tools/python/xen/xend/server/blkif.py | 18 ++++- tools/python/xen/xm/main.py | 3 4 files changed, 155 insertions(+), 19 deletions(-) diff -r f0298301ba8b -r 95f90f24f3b1 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu Aug 09 16:14:56 2007 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu Aug 09 16:21:41 2007 +0100 @@ -558,9 +558,64 @@ class XendDomainInfo: for devclass in XendDevices.valid_devices(): self.getDeviceController(devclass).waitForDevices() - def destroyDevice(self, deviceClass, devid, force = False): - log.debug("dev = %s", devid) - return self.getDeviceController(deviceClass).destroyDevice(devid, force) + def destroyDevice(self, deviceClass, devid, force = False, rm_cfg = False): + log.debug("XendDomainInfo.destroyDevice: deviceClass = %s, device = %s", + deviceClass, devid) + + if rm_cfg: + # Convert devid to device number. A device number is + # needed to remove its configuration. + dev = self.getDeviceController(deviceClass).convertToDeviceNumber(devid) + + # Save current sxprs. A device number and a backend + # path are needed to remove its configuration but sxprs + # do not have those after calling destroyDevice. + sxprs = self.getDeviceSxprs(deviceClass) + + rc = None + if self.domid is not None: + rc = self.getDeviceController(deviceClass).destroyDevice(devid, force) + if not force and rm_cfg: + # The backend path, other than the device itself, + # has to be passed because its accompanied frontend + # path may be void until its removal is actually + # issued. It is probable because destroyDevice is + # issued first. + for dev_num, dev_info in sxprs: + dev_num = int(dev_num) + if dev_num == dev: + for x in dev_info: + if x[0] == 'backend': + backend = x[1] + break + break + self._waitForDevice_destroy(deviceClass, devid, backend) + + if rm_cfg: + if deviceClass == 'vif': + if self.domid is not None: + for dev_num, dev_info in sxprs: + dev_num = int(dev_num) + if dev_num == dev: + for x in dev_info: + if x[0] == 'mac': + mac = x[1] + break + break + dev_info = self.getDeviceInfo_vif(mac) + else: + _, dev_info = sxprs[dev] + else: # 'vbd' or 'tap' + dev_info = self.getDeviceInfo_vbd(dev) + if dev_info is None: + return rc + + dev_uuid = sxp.child_value(dev_info, 'uuid') + del self.info['devices'][dev_uuid] + self.info['%s_refs' % deviceClass].remove(dev_uuid) + xen.xend.XendDomain.instance().managed_config_save(self) + + return rc def getDeviceSxprs(self, deviceClass): if self._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): @@ -573,6 +628,23 @@ class XendDomainInfo: sxprs.append([dev_num, dev_info]) dev_num += 1 return sxprs + + def getDeviceInfo_vif(self, mac): + for dev_type, dev_info in self.info.all_devices_sxpr(): + if dev_type != 'vif': + continue + if mac == sxp.child_value(dev_info, 'mac'): + return dev_info + + def getDeviceInfo_vbd(self, devid): + for dev_type, dev_info in self.info.all_devices_sxpr(): + if dev_type != 'vbd' and dev_type != 'tap': + continue + dev = sxp.child_value(dev_info, 'dev') + dev = dev.split(':')[0] + dev = self.getDeviceController(dev_type).convertToDeviceNumber(dev) + if devid == dev: + return dev_info def setMemoryTarget(self, target): @@ -1321,6 +1393,10 @@ class XendDomainInfo: deviceClass, config = self.info['devices'].get(dev_uuid) self._waitForDevice(deviceClass, config['devid']) + def _waitForDevice_destroy(self, deviceClass, devid, backpath): + return self.getDeviceController(deviceClass).waitForDevice_destroy( + devid, backpath) + def _reconfigureDevice(self, deviceClass, devid, devconfig): return self.getDeviceController(deviceClass).reconfigureDevice( devid, devconfig) diff -r f0298301ba8b -r 95f90f24f3b1 tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py Thu Aug 09 16:14:56 2007 +0100 +++ b/tools/python/xen/xend/server/DevController.py Thu Aug 09 16:21:41 2007 +0100 @@ -28,17 +28,19 @@ from xen.xend.xenstore.xswatch import xs import os -DEVICE_CREATE_TIMEOUT = 100 +DEVICE_CREATE_TIMEOUT = 100 +DEVICE_DESTROY_TIMEOUT = 100 HOTPLUG_STATUS_NODE = "hotplug-status" HOTPLUG_ERROR_NODE = "hotplug-error" HOTPLUG_STATUS_ERROR = "error" HOTPLUG_STATUS_BUSY = "busy" -Connected = 1 -Error = 2 -Missing = 3 -Timeout = 4 -Busy = 5 +Connected = 1 +Error = 2 +Missing = 3 +Timeout = 4 +Busy = 5 +Disconnected = 6 xenbusState = { 'Unknown' : 0, @@ -185,6 +187,18 @@ class DevController: (devid, self.deviceClass, err)) + def waitForDevice_destroy(self, devid, backpath): + log.debug("Waiting for %s - destroyDevice.", devid) + + if not self.hotplug: + return + + status = self.waitForBackend_destroy(backpath) + + if status == Timeout: + raise VmError("Device %s (%s) could not be disconnected. " % + (devid, self.deviceClass)) + def reconfigureDevice(self, devid, config): """Reconfigure the specified device. @@ -209,12 +223,7 @@ class DevController: here. """ - try: - dev = int(devid) - except ValueError: - # Does devid contain devicetype/deviceid? - # Propogate exception if unable to find an integer devid - dev = int(type(devid) is str and devid.split('/')[-1] or None) + dev = self.convertToDeviceNumber(devid) # Modify online status /before/ updating state (latter is watched by # drivers, so this ordering avoids a race). @@ -282,6 +291,15 @@ class DevController: config_dict = self.getDeviceConfiguration(devid) all_configs[devid] = config_dict return all_configs + + + def convertToDeviceNumber(self, devid): + try: + return int(devid) + except ValueError: + # Does devid contain devicetype/deviceid? + # Propogate exception if unable to find an integer devid + return int(type(devid) is str and devid.split('/')[-1] or None) ## protected: @@ -513,6 +531,19 @@ class DevController: return (Missing, None) + def waitForBackend_destroy(self, backpath): + + statusPath = backpath + '/' + HOTPLUG_STATUS_NODE + ev = Event() + result = { 'status': Timeout } + + xswatch(statusPath, deviceDestroyCallback, 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. @@ -561,3 +592,19 @@ def hotplugStatusCallback(statusPath, ev ev.set() return 0 + + +def deviceDestroyCallback(statusPath, ev, result): + log.debug("deviceDestroyCallback %s.", statusPath) + + status = xstransact.Read(statusPath) + + if status is None: + result['status'] = Disconnected + else: + return 1 + + log.debug("deviceDestroyCallback %d.", result['status']) + + ev.set() + return 0 diff -r f0298301ba8b -r 95f90f24f3b1 tools/python/xen/xend/server/blkif.py --- a/tools/python/xen/xend/server/blkif.py Thu Aug 09 16:14:56 2007 +0100 +++ b/tools/python/xen/xend/server/blkif.py Thu Aug 09 16:21:41 2007 +0100 @@ -165,11 +165,23 @@ class BlkifController(DevController): try: DevController.destroyDevice(self, devid, force) except ValueError: - devid_end = type(devid) is str and devid.split('/')[-1] or None + dev = self.convertToDeviceNumber(devid) for i in self.deviceIDs(): - d = self.readBackend(i, 'dev') - if d == devid or (devid_end and d == devid_end): + if i == dev: DevController.destroyDevice(self, i, force) return raise VmError("Device %s not connected" % devid) + + def convertToDeviceNumber(self, devid): + try: + dev = int(devid) + except ValueError: + if type(devid) is not str: + raise VmError("devid %s is wrong type" % str(devid)) + try: + dev = devid.split('/')[-1] + dev = int(dev) + except ValueError: + dev = blkif.blkdev_name_to_number(dev) + return dev diff -r f0298301ba8b -r 95f90f24f3b1 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Thu Aug 09 16:14:56 2007 +0100 +++ b/tools/python/xen/xm/main.py Thu Aug 09 16:21:41 2007 +0100 @@ -2186,6 +2186,7 @@ def xm_network_attach(args): def detach(args, deviceClass): + rm_cfg = True dom = args[0] dev = args[1] try: @@ -2196,7 +2197,7 @@ def detach(args, deviceClass): except IndexError: force = None - server.xend.domain.destroyDevice(dom, deviceClass, dev, force) + server.xend.domain.destroyDevice(dom, deviceClass, dev, force, rm_cfg) def xm_block_detach(args): _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |