Subject: [patch v3] xend: pass-through: Move pci conversion functions to pci.py From: Simon Horman Move dev_dict_to_sxp() into XendSXPDev.py. Move pci_convert_dict_to_sxp() and pci_convert_sxp_to_dict() to pci.py, where other similar functions live. This makes these functions accessible outside of the XendConfig class. Cc: Dexuan Cui Cc: Masaki Kanno Signed-off-by: Simon Horman --- Mon, 15 Jun 2009 11:55:26 +1000 * Initial posting Mon, 15 Jun 2009 20:39:43 +1000 * Miss-post - XendSXPDev.py change was omitted Tue, 16 Jun 2009 09:33:17 +1000 * Move dev_dict_to_sxp into XendSXPDev.py. As pointed out by Masaki Kanno, it is used by non-pci as well as pci devices. Index: xen-unstable.hg/tools/python/xen/util/pci.py =================================================================== --- xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-16 22:53:39.000000000 +1000 +++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-16 22:53:41.000000000 +1000 @@ -14,8 +14,10 @@ import struct import time import threading from xen.util import utils +from xen.xend import uuid from xen.xend import sxp from xen.xend.XendConstants import AUTO_PHP_SLOT +from xen.xend.XendSXPDev import dev_dict_to_sxp PROC_PCI_PATH = '/proc/bus/pci/devices' PROC_PCI_NUM_RESOURCES = 7 @@ -139,6 +141,79 @@ def pci_opts_list_to_sxp(list): def pci_opts_list_from_sxp(dev): return map(lambda x: sxp.children(x)[0], sxp.children(dev, 'opts')) +def pci_convert_dict_to_sxp(dev, state, sub_state = None): + pci_sxp = ['pci', dev_dict_to_sxp(dev), ['state', state]] + if sub_state != None: + pci_sxp.append(['sub_state', sub_state]) + return pci_sxp + +def pci_convert_sxp_to_dict(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], + # [vslot, 0]], + # [state, 'Initialising']]] + # + # 'vslot' 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, vslot: 0}], + # states: ['Initialising'] } + + dev_config = {} + + pci_devs = [] + for pci_dev in sxp.children(dev_sxp, 'dev'): + pci_dev_info = dict(pci_dev[1:]) + if 'opts' in pci_dev_info: + pci_dev_info['opts'] = pci_opts_list_from_sxp(pci_dev) + # append uuid to each pci device that does't already have one. + if not pci_dev_info.has_key('uuid'): + 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 parse_hex(val): try: if isinstance(val, types.StringTypes): Index: xen-unstable.hg/tools/python/xen/xend/XendConfig.py =================================================================== --- xen-unstable.hg.orig/tools/python/xen/xend/XendConfig.py 2009-06-16 22:46:20.000000000 +1000 +++ xen-unstable.hg/tools/python/xen/xend/XendConfig.py 2009-06-16 22:53:41.000000000 +1000 @@ -36,7 +36,8 @@ from xen.xend.xenstore.xstransact import from xen.xend.server.BlktapController import blktap_disk_types from xen.xend.server.netif import randomMAC from xen.util.blkif import blkdev_name_to_number, blkdev_uname_to_file -from xen.util.pci import pci_opts_list_from_sxp +from xen.util.pci import pci_opts_list_from_sxp, pci_convert_sxp_to_dict +from xen.xend.XendSXPDev import dev_dict_to_sxp from xen.util import xsconstants import xen.util.auxbin @@ -1295,7 +1296,7 @@ class XendConfig(dict): pci_devs_uuid = sxp.child_value(config, 'uuid', uuid.createString()) - pci_dict = self.pci_convert_sxp_to_dict(config) + pci_dict = pci_convert_sxp_to_dict(config) pci_devs = pci_dict['devs'] # create XenAPI DPCI objects. @@ -1605,79 +1606,6 @@ class XendConfig(dict): return '' - def pci_convert_dict_to_sxp(self, dev, state, sub_state = None): - pci_sxp = ['pci', self.dev_dict_to_sxp(dev), ['state', state]] - if sub_state != None: - pci_sxp.append(['sub_state', sub_state]) - return pci_sxp - - 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], - # [vslot, 0]], - # [state, 'Initialising']]] - # - # 'vslot' 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, vslot: 0}], - # states: ['Initialising'] } - - dev_config = {} - - pci_devs = [] - for pci_dev in sxp.children(dev_sxp, 'dev'): - pci_dev_info = dict(pci_dev[1:]) - if 'opts' in pci_dev_info: - pci_dev_info['opts'] = pci_opts_list_from_sxp(pci_dev) - # append uuid to each pci device that does't already have one. - if not pci_dev_info.has_key('uuid'): - 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 vscsi_convert_sxp_to_dict(self, dev_sxp): """Convert vscsi device sxp to dict @param dev_sxp: device configuration @@ -1848,7 +1776,7 @@ class XendConfig(dict): dev_type, dev_info = self['devices'][dev_uuid] if dev_type == 'pci': # Special case for pci - pci_dict = self.pci_convert_sxp_to_dict(config) + pci_dict = pci_convert_sxp_to_dict(config) pci_devs = pci_dict['devs'] # destroy existing XenAPI DPCI objects @@ -1971,15 +1899,6 @@ class XendConfig(dict): result.extend([u for u in target['devices'].keys() if u not in result]) return result - # This includes a generic equivalent of pci_opts_list_to_sxp() - def dev_dict_to_sxp(self, dev): - def f((key, val)): - if isinstance(val, types.ListType): - return map(lambda x: [key, x], val) - return [[key, val]] - dev_sxp = ['dev'] + reduce(lambda x, y: x + y, map(f, dev.items())) - return dev_sxp - def all_devices_sxpr(self, target = None): """Returns the SXPR for all devices in the current configuration.""" sxprs = [] @@ -2002,7 +1921,7 @@ class XendConfig(dict): if dev_info.has_key('backend'): sxpr.append(['backend', dev_info['backend']]) for pci_dev_info in dev_info['devs']: - sxpr.append(self.dev_dict_to_sxp(pci_dev_info)) + sxpr.append(dev_dict_to_sxp(pci_dev_info)) sxprs.append((dev_type, sxpr)) else: sxpr = self.device_sxpr(dev_type = dev_type, Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py 2009-06-16 22:53:39.000000000 +1000 +++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-16 22:53:41.000000000 +1000 @@ -40,7 +40,9 @@ from xen.util.blkif import blkdev_uname_ import xen.util.xsm.xsm as security from xen.util import xsconstants from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \ - pci_dict_to_bdf_str, pci_dict_to_xc_str, pci_dict_cmp + pci_dict_to_bdf_str, pci_dict_to_xc_str, \ + pci_convert_sxp_to_dict, pci_convert_dict_to_sxp, \ + pci_dict_cmp from xen.xend import balloon, sxp, uuid, image, arch from xen.xend import XendOptions, XendNode, XendConfig @@ -616,8 +618,8 @@ class XendDomainInfo: pci_conf = self.info['devices'][dev_uuid][1] pci_devs = pci_conf['devs'] request = map(lambda x: - self.info.pci_convert_dict_to_sxp(x, 'Initialising', - 'Booting'), pci_devs) + pci_convert_dict_to_sxp(x, 'Initialising', 'Booting'), + pci_devs) for i in request: self.pci_device_configure(i) @@ -815,7 +817,7 @@ class XendDomainInfo: raise XendError("Cannot detach when pci platform does not exist") pci_dev = sxp.children(dev_sxp, 'dev')[0] - dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp) + dev_config = pci_convert_sxp_to_dict(dev_sxp) dev = dev_config['devs'][0] # Do HVM specific processing Index: xen-unstable.hg/tools/python/xen/xend/XendSXPDev.py =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ xen-unstable.hg/tools/python/xen/xend/XendSXPDev.py 2009-06-16 22:53:41.000000000 +1000 @@ -0,0 +1,14 @@ +#!/usr/bin/env python +# +# Helper functions for dealing with the sxp representation of devices + +import types + +# This includes a generic equivalent of pci_opts_list_to_sxp() +def dev_dict_to_sxp(dev): + def f((key, val)): + if isinstance(val, types.ListType): + return map(lambda x: [key, x], val) + return [[key, val]] + dev_sxp = ['dev'] + reduce(lambda x, y: x + y, map(f, dev.items())) + return dev_sxp