[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xend: Fix xm pci-attach/detach for inactive managed domains
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1239273314 -3600 # Node ID 72d4c5c83508a21293a52dfe987fcd988e3376d1 # Parent 0b9b6d5a61c1822452fbf370e1e2fa936adf2213 xend: Fix xm pci-attach/detach for inactive managed domains Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx> --- tools/python/xen/xend/XendDomainInfo.py | 154 ++++++++++++++++++++++---------- 1 files changed, 106 insertions(+), 48 deletions(-) diff -r 0b9b6d5a61c1 -r 72d4c5c83508 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu Apr 09 09:59:16 2009 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu Apr 09 11:35:14 2009 +0100 @@ -685,31 +685,39 @@ class XendDomainInfo: # co-assignment devices hasn't been assigned, or has been assigned to # domN. coassignment_list = pci_device.find_coassigned_devices() - assigned_pci_device_str_list = get_assigned_pci_devices(self.domid) + assigned_pci_device_str_list = self._get_assigned_pci_devices() for pci_str in coassignment_list: (domain, bus, dev, func) = parse_pci_name(pci_str) dev_str = '0x%x,0x%x,0x%x,0x%x' % (domain, bus, dev, func) if xc.test_assign_device(0, dev_str) == 0: continue if not pci_str in assigned_pci_device_str_list: - raise VmError(('pci: failed to pci-attach %s to dom%d" + \ + raise VmError(("pci: failed to pci-attach %s to domain %s" + \ " because one of its co-assignment device %s has been" + \ - " assigned to other domain.' \ - )% (pci_device.name, self.domid, pci_str)) - - opts = '' - if 'opts' in new_dev and len(new_dev['opts']) > 0: - config_opts = new_dev['opts'] - config_opts = map(lambda (x, y): x+'='+y, config_opts) - opts = ',' + reduce(lambda x, y: x+','+y, config_opts) - - bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'], + " assigned to other domain." \ + )% (pci_device.name, self.info['name_label'], pci_str)) + + if self.domid is not None: + opts = '' + if 'opts' in new_dev and len(new_dev['opts']) > 0: + config_opts = new_dev['opts'] + config_opts = map(lambda (x, y): x+'='+y, config_opts) + opts = ',' + reduce(lambda x, y: x+','+y, config_opts) + + bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'], new_dev['bus'], new_dev['slot'], new_dev['func'], opts, new_dev['vslot']) - self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str) + self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str) + + vslot = xstransact.Read("/local/domain/0/device-model/%i/parameter" + % self.getDomid()) + else: + vslot = new_dev['vslot'] + + return vslot def device_create(self, dev_config): @@ -788,10 +796,8 @@ class XendDomainInfo: if self.info.is_hvm(): if pci_state == 'Initialising': # HVM PCI device attachment - self.hvm_pci_device_create(dev_config) + vslot = self.hvm_pci_device_create(dev_config) # Update vslot - vslot = xstransact.Read("/local/domain/0/device-model/%i/parameter" - % self.getDomid()) dev['vslot'] = vslot for n in sxp.children(pci_dev): if(n[0] == 'vslot'): @@ -825,35 +831,66 @@ class XendDomainInfo: self.device_create(dev_sxp) return True - # use DevController.reconfigureDevice to change device config - dev_control = self.getDeviceController(dev_class) - dev_uuid = dev_control.reconfigureDevice(devid, dev_config) - if not self.info.is_hvm(): - # in PV case, wait until backend state becomes connected. - dev_control.waitForDevice_reconfigure(devid) - num_devs = dev_control.cleanupDevice(devid) - - # update XendConfig with new device info - if dev_uuid: - new_dev_sxp = dev_control.configuration(devid) + if self.domid is not None: + # use DevController.reconfigureDevice to change device config + dev_control = self.getDeviceController(dev_class) + dev_uuid = dev_control.reconfigureDevice(devid, dev_config) + if not self.info.is_hvm(): + # in PV case, wait until backend state becomes connected. + dev_control.waitForDevice_reconfigure(devid) + num_devs = dev_control.cleanupDevice(devid) + + # update XendConfig with new device info + if dev_uuid: + new_dev_sxp = dev_control.configuration(devid) + self.info.device_update(dev_uuid, new_dev_sxp) + + # If there is no device left, destroy pci and remove config. + if num_devs == 0: + if self.info.is_hvm(): + self.destroyDevice('pci', devid, True) + del self.info['devices'][dev_uuid] + platform = self.info['platform'] + orig_dev_num = len(platform['pci']) + # TODO: can use this to keep some info to ask high level + # management tools to hot insert a new passthrough dev + # after migration + if orig_dev_num != 0: + #platform['pci'] = ["%dDEVs" % orig_dev_num] + platform['pci'] = [] + else: + self.destroyDevice('pci', devid) + del self.info['devices'][dev_uuid] + else: + new_dev_sxp = ['pci'] + for cur_dev in sxp.children(existing_dev_info, 'dev'): + if pci_state == 'Closing': + if int(dev['domain'], 16) == int(sxp.child_value(cur_dev, 'domain'), 16) and \ + int(dev['bus'], 16) == int(sxp.child_value(cur_dev, 'bus'), 16) and \ + int(dev['slot'], 16) == int(sxp.child_value(cur_dev, 'slot'), 16) and \ + int(dev['func'], 16) == int(sxp.child_value(cur_dev, 'func'), 16): + continue + new_dev_sxp.append(cur_dev) + + if pci_state == 'Initialising': + for new_dev in sxp.children(dev_sxp, 'dev'): + new_dev_sxp.append(new_dev) + + dev_uuid = sxp.child_value(existing_dev_info, 'uuid') self.info.device_update(dev_uuid, new_dev_sxp) - # If there is no device left, destroy pci and remove config. - if num_devs == 0: - if self.info.is_hvm(): - self.destroyDevice('pci', devid, True) + # If there is only 'vscsi' in new_dev_sxp, remove the config. + if len(sxp.children(new_dev_sxp, 'dev')) == 0: del self.info['devices'][dev_uuid] - platform = self.info['platform'] - orig_dev_num = len(platform['pci']) - # TODO: can use this to keep some info to ask high level - # management tools to hot insert a new passthrough dev - # after migration - if orig_dev_num != 0: - #platform['pci'] = ["%dDEVs" % orig_dev_num] - platform['pci'] = [] - else: - self.destroyDevice('pci', devid) - del self.info['devices'][dev_uuid] + if self.info.is_hvm(): + platform = self.info['platform'] + orig_dev_num = len(platform['pci']) + # TODO: can use this to keep some info to ask high level + # management tools to hot insert a new passthrough dev + # after migration + if orig_dev_num != 0: + #platform['pci'] = ["%dDEVs" % orig_dev_num] + platform['pci'] = [] xen.xend.XendDomain.instance().managed_config_save(self) @@ -1054,7 +1091,7 @@ class XendDomainInfo: raise VmError("Device @ vslot 0x%x doesn't exist." % (vslot)) if vslot == AUTO_PHP_SLOT: - raise VmError("Device @ vslot 0x%x do not support hotplug." % (vslot)) + raise VmError("Device @ vslot 0x%x doesn't support hotplug." % (vslot)) # Check the co-assignment. # To pci-detach a device D from domN, we should ensure: for each DD in the @@ -1072,19 +1109,20 @@ class XendDomainInfo: "parse it's resources - "+str(e)) coassignment_list = pci_device.find_coassigned_devices() coassignment_list.remove(pci_device.name) - assigned_pci_device_str_list = get_assigned_pci_devices(self.domid) + assigned_pci_device_str_list = self._get_assigned_pci_devices() for pci_str in coassignment_list: if pci_str in assigned_pci_device_str_list: - raise VmError(('pci: failed to pci-detach %s from dom%d" + \ + raise VmError(("pci: failed to pci-detach %s from domain %s" + \ " because one of its co-assignment device %s is still " + \ - " assigned to the domain.' \ - )% (pci_device.name, self.domid, pci_str)) + " assigned to the domain." \ + )% (pci_device.name, self.info['name_label'], pci_str)) bdf_str = "%s:%s:%s.%s" % (x['domain'], x['bus'], x['slot'], x['func']) log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str) - self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str) + if self.domid is not None: + self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str) return 0 @@ -1233,6 +1271,26 @@ class XendDomainInfo: if devid == int(sxp.child_value(devs[0], 'devid')): return dev_info return None + + def _get_assigned_pci_devices(self, devid = 0): + if self.domid is not None: + return get_assigned_pci_devices(self.domid) + + dev_str_list = [] + dev_info = self._getDeviceInfo_pci(devid) + if dev_info is None: + return dev_str_list + dev_uuid = sxp.child_value(dev_info, 'uuid') + pci_conf = self.info['devices'][dev_uuid][1] + pci_devs = pci_conf['devs'] + for pci_dev in pci_devs: + domain = int(pci_dev['domain'], 16) + bus = int(pci_dev['bus'], 16) + slot = int(pci_dev['slot'], 16) + func = int(pci_dev['func'], 16) + dev_str = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func) + dev_str_list = dev_str_list + [dev_str] + return dev_str_list def setMemoryTarget(self, target): """Set the memory target of this domain. _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |