[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] XenAPI: Add Direct PCI Device (DPCI) Assignment Support
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1215077232 -3600 # Node ID 52a388ec09f852ffd7e42a71593c63f21a7b9fad # Parent e65fe28b52887ffe61750474835cbd0afe8ccd48 XenAPI: Add Direct PCI Device (DPCI) Assignment Support Signed-off-by: Yosuke Iwamatsu <y-iwamatsu@xxxxxxxxxxxxx> --- tools/python/xen/xend/XendAPI.py | 9 + tools/python/xen/xend/XendConfig.py | 159 ++++++++++++++++++++++------- tools/python/xen/xend/XendDPCI.py | 154 ++++++++++++++++++++++++++++ tools/python/xen/xend/XendDomain.py | 3 tools/python/xen/xend/XendDomainInfo.py | 171 +++++++++++++++++++++++--------- tools/python/xen/xend/XendError.py | 11 ++ tools/python/xen/xend/server/pciif.py | 12 ++ 7 files changed, 435 insertions(+), 84 deletions(-) diff -r e65fe28b5288 -r 52a388ec09f8 tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Thu Jul 03 10:26:16 2008 +0100 +++ b/tools/python/xen/xend/XendAPI.py Thu Jul 03 10:27:12 2008 +0100 @@ -41,6 +41,7 @@ from XendPIF import XendPIF from XendPIF import XendPIF from XendPBD import XendPBD from XendPPCI import XendPPCI +from XendDPCI import XendDPCI from XendXSPolicy import XendXSPolicy, XendACMPolicy from XendAPIConstants import * @@ -479,6 +480,7 @@ classes = { 'PBD' : valid_object("PBD"), 'PIF_metrics' : valid_object("PIF_metrics"), 'PPCI' : valid_object("PPCI"), + 'DPCI' : valid_object("DPCI") } autoplug_classes = { @@ -488,6 +490,7 @@ autoplug_classes = { 'PBD' : XendPBD, 'PIF_metrics' : XendPIFMetrics, 'PPCI' : XendPPCI, + 'DPCI' : XendDPCI, 'XSPolicy' : XendXSPolicy, 'ACMPolicy' : XendACMPolicy, } @@ -1154,6 +1157,7 @@ class XendAPI(object): 'VIFs', 'VBDs', 'VTPMs', + 'DPCIs', 'tools_version', 'domid', 'is_control_domain', @@ -1296,6 +1300,10 @@ class XendAPI(object): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_success(dom.get_consoles()) + def VM_get_DPCIs(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + return xen_api_success(dom.get_dpcis()) + def VM_get_tools_version(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return dom.get_tools_version() @@ -1675,6 +1683,7 @@ class XendAPI(object): 'VIFs': xeninfo.get_vifs(), 'VBDs': xeninfo.get_vbds(), 'VTPMs': xeninfo.get_vtpms(), + 'DPCIs': xeninfo.get_dpcis(), 'PV_bootloader': xeninfo.info.get('PV_bootloader'), 'PV_kernel': xeninfo.info.get('PV_kernel'), 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'), diff -r e65fe28b5288 -r 52a388ec09f8 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Thu Jul 03 10:26:16 2008 +0100 +++ b/tools/python/xen/xend/XendConfig.py Thu Jul 03 10:27:12 2008 +0100 @@ -24,6 +24,8 @@ from xen.xend import uuid from xen.xend import uuid from xen.xend import XendOptions from xen.xend import XendAPIStore +from xen.xend.XendPPCI import XendPPCI +from xen.xend.XendDPCI import XendDPCI from xen.xend.XendError import VmError from xen.xend.XendDevices import XendDevices from xen.xend.PrettyPrint import prettyprintstring @@ -773,6 +775,11 @@ class XendConfig(dict): """ log.debug('_sxp_to_xapi(%s)' % scrub_password(sxp_cfg)) + # _parse_sxp() below will call device_add() and construct devices. + # Some devices (currently only pci) may require VM's uuid, so + # setup self['uuid'] beforehand. + self['uuid'] = sxp.child_value(sxp_cfg, 'uuid', uuid.createString()) + cfg = self._parse_sxp(sxp_cfg) for key, typ in XENAPI_CFG_TYPES.items(): @@ -1209,42 +1216,35 @@ class XendConfig(dict): dev_type = sxp.name(config) dev_info = {} - # Parsing the device SXP's. In most cases, the SXP looks - # like this: - # - # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]] - # - # However, for PCI devices it looks like this: - # - # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1]]]] - # - # It seems the reasoning for this difference is because - # pciif.py needs all the PCI device configurations at - # the same time when creating the devices. - # - # To further complicate matters, Xen 2.0 configuration format - # uses the following for pci device configuration: - # - # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]] - if dev_type == 'pci': pci_devs_uuid = sxp.child_value(config, 'uuid', uuid.createString()) - pci_devs = [] - for pci_dev in sxp.children(config, 'dev'): - pci_dev_info = {} - for opt_val in pci_dev[1:]: - try: - opt, val = opt_val - pci_dev_info[opt] = val - except TypeError: - pass - pci_devs.append(pci_dev_info) + + pci_dict = self.pci_convert_sxp_to_dict(config) + pci_devs = pci_dict['devs'] + + # create XenAPI DPCI objects. + for pci_dev in pci_devs: + dpci_uuid = pci_dev.get('uuid') + ppci_uuid = XendPPCI.get_by_sbdf(pci_dev['domain'], + pci_dev['bus'], + pci_dev['slot'], + pci_dev['func']) + if ppci_uuid is None: + continue + dpci_record = { + 'VM': self['uuid'], + 'PPCI': ppci_uuid, + 'hotplug_slot': pci_dev.get('vslot', 0) + } + XendDPCI(dpci_uuid, dpci_record) + target['devices'][pci_devs_uuid] = (dev_type, {'devs': pci_devs, 'uuid': pci_devs_uuid}) log.debug("XendConfig: reading device: %s" % pci_devs) + return pci_devs_uuid for opt_val in config[1:]: @@ -1482,6 +1482,76 @@ class XendConfig(dict): return '' + def pci_convert_sxp_to_dict(self, dev_sxp): + """Convert pci device sxp to dict + @param dev_sxp: device configuration + @type dev_sxp: SXP object (parsed config) + @return: dev_config + @rtype: dictionary + """ + # Parsing the device SXP's. In most cases, the SXP looks + # like this: + # + # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]] + # + # However, for PCI devices it looks like this: + # + # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]] + # + # It seems the reasoning for this difference is because + # pciif.py needs all the PCI device configurations at + # the same time when creating the devices. + # + # To further complicate matters, Xen 2.0 configuration format + # uses the following for pci device configuration: + # + # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]] + + # For PCI device hotplug support, the SXP of PCI devices is + # extendend like this: + # + # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2], + # [vslt, 0]], + # [state, 'Initialising']]] + # + # 'vslt' shows the virtual hotplug slot number which the PCI device + # is inserted in. This is only effective for HVM domains. + # + # state 'Initialising' indicates that the device is being attached, + # while state 'Closing' indicates that the device is being detached. + # + # The Dict looks like this: + # + # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslt: 0}], + # states: ['Initialising'] } + + dev_config = {} + + pci_devs = [] + for pci_dev in sxp.children(dev_sxp, 'dev'): + pci_dev_info = {} + for opt_val in pci_dev[1:]: + try: + opt, val = opt_val + pci_dev_info[opt] = val + except TypeError: + pass + # append uuid for each pci device. + dpci_uuid = pci_dev_info.get('uuid', uuid.createString()) + pci_dev_info['uuid'] = dpci_uuid + pci_devs.append(pci_dev_info) + dev_config['devs'] = pci_devs + + pci_states = [] + for pci_state in sxp.children(dev_sxp, 'state'): + try: + pci_states.append(pci_state[1]) + except IndexError: + raise XendError("Error reading state while parsing pci sxp") + dev_config['states'] = pci_states + + return dev_config + def console_add(self, protocol, location, other_config = {}): dev_uuid = uuid.createString() if protocol == 'vt100': @@ -1556,16 +1626,29 @@ class XendConfig(dict): dev_type, dev_info = self['devices'][dev_uuid] if dev_type == 'pci': # Special case for pci - pci_devs = [] - for pci_dev in sxp.children(config, 'dev'): - pci_dev_info = {} - for opt_val in pci_dev[1:]: - try: - opt, val = opt_val - pci_dev_info[opt] = val - except TypeError: - pass - pci_devs.append(pci_dev_info) + pci_dict = self.pci_convert_sxp_to_dict(config) + pci_devs = pci_dict['devs'] + + # destroy existing XenAPI DPCI objects + for dpci_uuid in XendDPCI.get_by_VM(self['uuid']): + XendAPIStore.deregister(dpci_uuid, "DPCI") + + # create XenAPI DPCI objects. + for pci_dev in pci_devs: + dpci_uuid = pci_dev.get('uuid') + ppci_uuid = XendPPCI.get_by_sbdf(pci_dev['domain'], + pci_dev['bus'], + pci_dev['slot'], + pci_dev['func']) + if ppci_uuid is None: + continue + dpci_record = { + 'VM': self['uuid'], + 'PPCI': ppci_uuid, + 'hotplug_slot': pci_dev.get('vslot', 0) + } + XendDPCI(dpci_uuid, dpci_record) + self['devices'][dev_uuid] = (dev_type, {'devs': pci_devs, 'uuid': dev_uuid}) diff -r e65fe28b5288 -r 52a388ec09f8 tools/python/xen/xend/XendDPCI.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/xend/XendDPCI.py Thu Jul 03 10:27:12 2008 +0100 @@ -0,0 +1,154 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (c) 2008 NEC Corporation +# Yosuke Iwamatsu <y-iwamatsu at ab jp nec com> +#============================================================================ + +from xen.xend.XendBase import XendBase +from xen.xend.XendPPCI import XendPPCI +from xen.xend import XendAPIStore +from xen.xend import uuid as genuuid + +import XendDomain, XendNode + +from XendError import * +from XendTask import XendTask +from XendLogging import log + +class XendDPCI(XendBase): + """Representation of a passthrough PCI device.""" + + def getClass(self): + return "DPCI" + + def getAttrRO(self): + attrRO = ['virtual_domain', + 'virtual_bus', + 'virtual_slot', + 'virtual_func', + 'virtual_name', + 'VM', + 'PPCI', + 'hotplug_slot'] + return XendBase.getAttrRO() + attrRO + + def getAttrRW(self): + attrRW = [] + return XendBase.getAttrRW() + attrRW + + def getAttrInst(self): + attrInst = ['VM', + 'PPCI', + 'hotplug_slot'] + return XendBase.getAttrInst() + attrInst + + def getMethods(self): + methods = ['destroy'] + return XendBase.getMethods() + methods + + def getFuncs(self): + funcs = ['create'] + return XendBase.getFuncs() + funcs + + getClass = classmethod(getClass) + getAttrRO = classmethod(getAttrRO) + getAttrRW = classmethod(getAttrRW) + getAttrInst = classmethod(getAttrInst) + getMethods = classmethod(getMethods) + getFuncs = classmethod(getFuncs) + + def create(self, dpci_struct): + + # Check if VM is valid + xendom = XendDomain.instance() + if not xendom.is_valid_vm(dpci_struct['VM']): + raise InvalidHandleError('VM', dpci_struct['VM']) + dom = xendom.get_vm_by_uuid(dpci_struct['VM']) + + # Check if PPCI is valid + xennode = XendNode.instance() + ppci_uuid = xennode.get_ppci_by_uuid(dpci_struct['PPCI']) + if not ppci_uuid: + raise InvalidHandleError('PPCI', dpci_struct['PPCI']) + for existing_dpci in XendAPIStore.get_all('DPCI'): + if ppci_uuid == existing_dpci.get_PPCI(): + raise DirectPCIError("Device is in use") + + # Assign PPCI to VM + try: + dpci_ref = XendTask.log_progress(0, 100, dom.create_dpci, + dpci_struct) + except XendError, e: + raise DirectPCIError("Failed to assign device") + + # TODO: Retrive virtual pci device infomation. + + return dpci_ref + + create = classmethod(create) + + def get_by_VM(cls, VM_ref): + result = [] + for dpci in XendAPIStore.get_all("DPCI"): + if dpci.get_VM() == VM_ref: + result.append(dpci.get_uuid()) + return result + + get_by_VM = classmethod(get_by_VM) + + def __init__(self, uuid, record): + XendBase.__init__(self, uuid, record) + + self.virtual_domain = -1 + self.virtual_bus = -1 + self.virtual_slot = -1 + self.virtual_func = -1 + + self.VM = record['VM'] + self.PPCI = record['PPCI'] + self.hotplug_slot = record['hotplug_slot'] + + def destroy(self): + xendom = XendDomain.instance() + dom = xendom.get_vm_by_uuid(self.get_VM()) + if not dom: + raise InvalidHandleError("VM", self.get_VM()) + XendTask.log_progress(0, 100, dom.destroy_dpci, self.get_uuid()) + + def get_virtual_domain(self): + return self.virtual_domain + + def get_virtual_bus(self): + return self.virtual_bus + + def get_virtual_slot(self): + return self.virtual_slot + + def get_virtual_func(self): + return self.virtual_func + + def get_virtual_name(self): + return "%04x:%02x:%02x.%01x" % (self.virtual_domain, self.virtual_bus, + self.virtual_slot, self.virtual_func) + + def get_VM(self): + return self.VM + + def get_PPCI(self): + return self.PPCI + + def get_hotplug_slot(self): + return self.hotplug_slot + diff -r e65fe28b5288 -r 52a388ec09f8 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Thu Jul 03 10:26:16 2008 +0100 +++ b/tools/python/xen/xend/XendDomain.py Thu Jul 03 10:27:12 2008 +0100 @@ -478,6 +478,8 @@ class XendDomain: if domid in self.domains: del self.domains[domid] + + info.destroy_xapi_device_instances() else: log.warning("Attempted to remove non-existent domain.") @@ -1091,6 +1093,7 @@ class XendDomain: self._managed_domain_unregister(dominfo) self._remove_domain(dominfo) XendDevices.destroy_device_state(dominfo) + dominfo.destroy_xapi_device_instances() def domain_configure(self, config): diff -r e65fe28b5288 -r 52a388ec09f8 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu Jul 03 10:26:16 2008 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu Jul 03 10:27:12 2008 +0100 @@ -54,6 +54,10 @@ from xen.xend.XendAPIConstants import * from xen.xend.XendAPIConstants import * from xen.xend.XendVMMetrics import XendVMMetrics + +from xen.xend.XendPPCI import XendPPCI +from xen.xend.XendDPCI import XendDPCI +from xen.xend import XendAPIStore MIGRATE_TIMEOUT = 30.0 BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp' @@ -642,50 +646,7 @@ class XendDomainInfo: xen.xend.XendDomain.instance().managed_config_save(self) return self.getDeviceController(dev_type).sxpr(devid) - def pci_convert_sxp_to_dict(self, dev_sxp): - """Convert pci device sxp to dict - @param dev_sxp: device configuration - @type dev_sxp: SXP object (parsed config) - @return: dev_config - @rtype: dictionary - """ - # In reconfigure phase, config of PCI device looks like below: - # - # sxp: - # [device, [pci, [dev, [domain, '0x0'], [bus, '0x0'], [slot, '0x0'], - # [func, '0x0'], [vslt, '0x0']], - # [state, 'Initialising']]] - # - # dict: - # {devs: [{domain: '0x0', bus: '0x0', slot: '0x0', func: '0x0', - # vslt: '0x0'}], - # states: ['Initialising']} - # - # state 'Initialising' means the device is being attached. - # state 'Closing' means the device is being detached. - - dev_config = {} - pci_devs = [] - for pci_dev in sxp.children(dev_sxp, 'dev'): - pci_dev_info = {} - for opt_val in pci_dev[1:]: - try: - opt, val = opt_val - pci_dev_info[opt] = val - except TypeError: - pass - pci_devs.append(pci_dev_info) - dev_config['devs'] = pci_devs - pci_states = [] - for pci_state in sxp.children(dev_sxp, 'state'): - try: - pci_states.append(pci_state[1]) - except IndexError: - raise XendError("Error reading state while parsing pci sxp") - dev_config['states'] = pci_states - - return dev_config - + def pci_device_configure(self, dev_sxp, devid = 0): """Configure an existing pci device. @@ -711,7 +672,7 @@ class XendDomainInfo: raise XendError("Cannot detach when pci platform does not exist") pci_dev = sxp.children(dev_sxp, 'dev')[0] - dev_config = self.pci_convert_sxp_to_dict(dev_sxp) + dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp) dev = dev_config['devs'][0] # Do HVM specific processing @@ -785,6 +746,8 @@ class XendDomainInfo: self.destroyDevice('pci', devid) del self.info['devices'][dev_uuid] + xen.xend.XendDomain.instance().managed_config_save(self) + return True def device_configure(self, dev_sxp, devid = None): @@ -3169,6 +3132,9 @@ class XendDomainInfo: def get_vtpms(self): return self.info.get('vtpm_refs', []) + def get_dpcis(self): + return XendDPCI.get_by_VM(self.info.get('uuid')) + def create_vbd(self, xenapi_vbd, vdi_image_path): """Create a VBD using a VDI from XendStorageRepository. @@ -3291,6 +3257,64 @@ class XendDomainInfo: def set_console_other_config(self, console_uuid, other_config): self.info.console_update(console_uuid, 'other_config', other_config) + + def create_dpci(self, xenapi_pci): + """Create pci device from the passed struct in Xen API format. + + @param xenapi_pci: DPCI struct from Xen API + @rtype: bool + #@rtype: string + @return: True if successfully created device + #@return: UUID + """ + + dpci_uuid = uuid.createString() + + # Convert xenapi to sxp + ppci = XendAPIStore.get(xenapi_pci.get('PPCI'), 'PPCI') + + target_pci_sxp = \ + ['pci', + ['dev', + ['domain', '0x%02x' % ppci.get_domain()], + ['bus', '0x%02x' % ppci.get_bus()], + ['slot', '0x%02x' % ppci.get_slot()], + ['func', '0x%1x' % ppci.get_func()], + ['vslt', '0x%02x' % xenapi_pci.get('hotplug_slot')], + ['uuid', dpci_uuid] + ], + ['state', 'Initialising'] + ] + + if self._stateGet() != XEN_API_VM_POWER_STATE_RUNNING: + + old_pci_sxp = self._getDeviceInfo_pci(0) + + if old_pci_sxp is None: + dev_uuid = self.info.device_add('pci', cfg_sxp = target_pci_sxp) + if not dev_uuid: + raise XendError('Failed to create device') + + else: + new_pci_sxp = ['pci'] + for existing_dev in sxp.children(old_pci_sxp, 'dev'): + new_pci_sxp.append(existing_dev) + new_pci_sxp.append(sxp.child0(target_pci_sxp, 'dev')) + + dev_uuid = sxp.child_value(old_pci_sxp, 'uuid') + self.info.device_update(dev_uuid, new_pci_sxp) + + xen.xend.XendDomain.instance().managed_config_save(self) + + else: + try: + self.device_configure(target_pci_sxp) + + except Exception, exn: + raise XendError('Failed to create device') + + return dpci_uuid + def destroy_device_by_uuid(self, dev_type, dev_uuid): if dev_uuid not in self.info['devices']: @@ -3318,6 +3342,63 @@ class XendDomainInfo: def destroy_vtpm(self, dev_uuid): self.destroy_device_by_uuid('vtpm', dev_uuid) + + def destroy_dpci(self, dev_uuid): + + dpci = XendAPIStore.get(dev_uuid, 'DPCI') + ppci = XendAPIStore.get(dpci.get_PPCI(), 'PPCI') + + old_pci_sxp = self._getDeviceInfo_pci(0) + dev_uuid = sxp.child_value(old_pci_sxp, 'uuid') + target_dev = None + new_pci_sxp = ['pci'] + for dev in sxp.children(old_pci_sxp, 'dev'): + domain = int(sxp.child_value(dev, 'domain'), 16) + bus = int(sxp.child_value(dev, 'bus'), 16) + slot = int(sxp.child_value(dev, 'slot'), 16) + func = int(sxp.child_value(dev, 'func'), 16) + name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func) + if ppci.get_name() == name: + target_dev = dev + else: + new_pci_sxp.append(dev) + + if target_dev is None: + raise XendError('Failed to destroy device') + + target_pci_sxp = ['pci', target_dev, ['state', 'Closing']] + + if self._stateGet() != XEN_API_VM_POWER_STATE_RUNNING: + + self.info.device_update(dev_uuid, new_pci_sxp) + if len(sxp.children(new_pci_sxp, 'dev')) == 0: + del self.info['devices'][dev_uuid] + xen.xend.XendDomain.instance().managed_config_save(self) + + else: + try: + self.device_configure(target_pci_sxp) + + except Exception, exn: + raise XendError('Failed to destroy device') + + def destroy_xapi_device_instances(self): + """Destroy Xen-API device instances stored in XendAPIStore. + """ + # Xen-API classes based on XendBase have their instances stored + # in XendAPIStore. Cleanup these virtual device instances here + # if they are supposed to be destroyed when the parent domain is dead. + # + # Most of the virtual devices (vif, vbd, vfb, etc) are not based on + # XendBase and there's no need to remove them from XendAPIStore. + + from xen.xend import XendDomain + if XendDomain.instance().is_valid_vm(self.info.get('uuid')): + # domain still exists. + return + + for dpci_uuid in XendDPCI.get_by_VM(self.info.get('uuid')): + XendAPIStore.deregister(dpci_uuid, "DPCI") def has_device(self, dev_class, dev_uuid): return (dev_uuid in self.info['%s_refs' % dev_class.lower()]) diff -r e65fe28b5288 -r 52a388ec09f8 tools/python/xen/xend/XendError.py --- a/tools/python/xen/xend/XendError.py Thu Jul 03 10:26:16 2008 +0100 +++ b/tools/python/xen/xend/XendError.py Thu Jul 03 10:27:12 2008 +0100 @@ -174,6 +174,17 @@ class NetworkError(XendAPIError): def __str__(self): return 'NETWORK_ERROR: %s %s' % (self.error, self.network) + +class DirectPCIError(XendAPIError): + def __init__(self, error): + XendAPIError.__init__(self) + self.error = error + + def get_api_error(self): + return ['DIRECT_PCI_ERROR', self.error] + + def __str__(self): + return 'DIRECT_PCI_ERROR: %s' % self.error from xen.util.xsconstants import xserr2string diff -r e65fe28b5288 -r 52a388ec09f8 tools/python/xen/xend/server/pciif.py --- a/tools/python/xen/xend/server/pciif.py Thu Jul 03 10:26:16 2008 +0100 +++ b/tools/python/xen/xend/server/pciif.py Thu Jul 03 10:27:12 2008 +0100 @@ -76,6 +76,7 @@ class PciController(DevController): back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%02x" % \ (domain, bus, slot, func) + back['uuid-%i' % pcidevid] = pci_config.get('uuid', '') pcidevid += 1 if vslots != "": @@ -101,6 +102,7 @@ class PciController(DevController): try: dev = back['dev-%i' % i] state = states[i] + uuid = back['uuid-%i' %i] except: raise XendError('Error reading config') @@ -121,6 +123,7 @@ class PciController(DevController): self.writeBackend(devid, 'dev-%i' % (num_olddevs + i), dev) self.writeBackend(devid, 'state-%i' % (num_olddevs + i), str(xenbusState['Initialising'])) + self.writeBackend(devid, 'uuid-%i' % (num_olddevs + i), uuid) self.writeBackend(devid, 'num_devs', str(num_olddevs + i + 1)) # Update vslots @@ -141,7 +144,7 @@ class PciController(DevController): raise XendError('Device %s is not connected' % dev) # Update vslots - if back['vslots'] is not None: + if back.get('vslots') is not None: vslots = old_vslots for vslt in back['vslots'].split(';'): if vslt != '': @@ -185,6 +188,9 @@ class PciController(DevController): 'bus': '0x%(bus)s' % pci_dev_info, 'slot': '0x%(slot)s' % pci_dev_info, 'func': '0x%(func)s' % pci_dev_info} + + # Per device uuid info + dev_dict['uuid'] = self.readBackend(devid, 'uuid-%d' % i) #append vslot info if vslots is not None: @@ -442,6 +448,7 @@ class PciController(DevController): self.removeBackend(devid, 'dev-%i' % i) self.removeBackend(devid, 'vdev-%i' % i) self.removeBackend(devid, 'state-%i' % i) + self.removeBackend(devid, 'uuid-%i' % i) else: if new_num_devs != i: tmpdev = self.readBackend(devid, 'dev-%i' % i) @@ -455,6 +462,9 @@ class PciController(DevController): tmpstate = self.readBackend(devid, 'state-%i' % i) self.writeBackend(devid, 'state-%i' % new_num_devs, tmpstate) self.removeBackend(devid, 'state-%i' % i) + tmpuuid = self.readBackend(devid, 'uuid-%i' % i) + self.writeBackend(devid, 'uuid-%i' % new_num_devs, tmpuuid) + self.removeBackend(devid, 'uuid-%i' % i) new_num_devs = new_num_devs + 1 self.writeBackend(devid, 'num_devs', str(new_num_devs)) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |