ia64/xen-unstable

changeset 19758:0573bbe19499

xend: pass-through: sxp.merge() cant deal with values being a list

sxp.merge() can't deal with values being a list so instead
of storing pci options as:

[ 'opts', [ 'key1' 'value1'], [ 'key2', 'value2'], ...]

store them as:

[ 'opts', [ 'key1' 'value1'], ['opts', [ 'key2', 'value2']], ...

Signed-off-by: Simon Horman <horms@verge.net.au>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 16 11:37:41 2009 +0100 (2009-06-16)
parents c7fabc081498
children 11c3f4e786b3
files tools/python/xen/util/pci.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/server/pciif.py tools/python/xen/xm/create.py tools/python/xen/xm/main.py tools/python/xen/xm/xenapi_create.py
line diff
     1.1 --- a/tools/python/xen/util/pci.py	Tue Jun 16 11:36:40 2009 +0100
     1.2 +++ b/tools/python/xen/util/pci.py	Tue Jun 16 11:37:41 2009 +0100
     1.3 @@ -118,14 +118,26 @@ def PCI_BDF(domain, bus, slot, func):
     1.4      return (((domain & 0xffff) << 16) | ((bus & 0xff) << 8) |
     1.5              PCI_DEVFN(slot, func))
     1.6  
     1.7 +def check_pci_opts(opts):
     1.8 +    def f((k, v)):
     1.9 +        if k not in ['msitranslate', 'power_mgmt'] or \
    1.10 +           not v.lower() in ['0', '1', 'yes', 'no']:
    1.11 +            raise PciDeviceParseError('Invalid pci option %s=%s: ' % (k, v))
    1.12 +
    1.13 +    map(f, opts)
    1.14 +
    1.15  def serialise_pci_opts(opts):
    1.16 -    return reduce(lambda x, y: x+','+y, map(lambda (x, y): x+'='+y, opts))
    1.17 +    return ','.join(map(lambda x: '='.join(x), opts))
    1.18  
    1.19  def split_pci_opts(opts):
    1.20 -    return map(lambda x: x.split('='), opts.split(','))
    1.21 +    return map(lambda x: x.split('='),
    1.22 +               filter(lambda x: x != '', opts.split(',')))
    1.23  
    1.24  def pci_opts_list_to_sxp(list):
    1.25 -    ['dev'] + map(lambda x: ['opts', x], list)
    1.26 +    return ['dev'] + map(lambda x: ['opts', x], list)
    1.27 +
    1.28 +def pci_opts_list_from_sxp(dev):
    1.29 +    return map(lambda x: sxp.children(x)[0], sxp.children(dev, 'opts'))
    1.30  
    1.31  def parse_hex(val):
    1.32      try:
     2.1 --- a/tools/python/xen/xend/XendConfig.py	Tue Jun 16 11:36:40 2009 +0100
     2.2 +++ b/tools/python/xen/xend/XendConfig.py	Tue Jun 16 11:37:41 2009 +0100
     2.3 @@ -36,6 +36,7 @@ from xen.xend.xenstore.xstransact import
     2.4  from xen.xend.server.BlktapController import blktap_disk_types
     2.5  from xen.xend.server.netif import randomMAC
     2.6  from xen.util.blkif import blkdev_name_to_number, blkdev_uname_to_file
     2.7 +from xen.util.pci import pci_opts_list_from_sxp
     2.8  from xen.util import xsconstants
     2.9  import xen.util.auxbin
    2.10  
    2.11 @@ -1605,11 +1606,10 @@ class XendConfig(dict):
    2.12          return ''
    2.13  
    2.14      def pci_convert_dict_to_sxp(self, dev, state, sub_state = None):
    2.15 -        sxp =  ['pci', ['dev'] + map(lambda (x, y): [x, y], dev.items()),
    2.16 -                ['state', state]]
    2.17 +        pci_sxp = ['pci', self.dev_dict_to_sxp(dev), ['state', state]]
    2.18          if sub_state != None:
    2.19 -            sxp.append(['sub_state', sub_state])
    2.20 -        return sxp
    2.21 +            pci_sxp.append(['sub_state', sub_state])
    2.22 +        return pci_sxp
    2.23  
    2.24      def pci_convert_sxp_to_dict(self, dev_sxp):
    2.25          """Convert pci device sxp to dict
    2.26 @@ -1658,13 +1658,9 @@ class XendConfig(dict):
    2.27  
    2.28          pci_devs = []
    2.29          for pci_dev in sxp.children(dev_sxp, 'dev'):
    2.30 -            pci_dev_info = {}
    2.31 -            for opt_val in pci_dev[1:]:
    2.32 -                try:
    2.33 -                    opt, val = opt_val
    2.34 -                    pci_dev_info[opt] = val
    2.35 -                except (TypeError, ValueError):
    2.36 -                    pass
    2.37 +            pci_dev_info = dict(pci_dev[1:])
    2.38 +            if 'opts' in pci_dev_info:
    2.39 +                pci_dev_info['opts'] = pci_opts_list_from_sxp(pci_dev)
    2.40              # append uuid to each pci device that does't already have one.
    2.41              if not pci_dev_info.has_key('uuid'):
    2.42                  dpci_uuid = pci_dev_info.get('uuid', uuid.createString())
    2.43 @@ -1975,6 +1971,15 @@ class XendConfig(dict):
    2.44          result.extend([u for u in target['devices'].keys() if u not in result])
    2.45          return result
    2.46  
    2.47 +    # This includes a generic equivalent of pci_opts_list_to_sxp()
    2.48 +    def dev_dict_to_sxp(self, dev):
    2.49 +        def f((key, val)):
    2.50 +            if isinstance(val, types.ListType):
    2.51 +                return map(lambda x: [key, x], val)
    2.52 +            return [[key, val]]
    2.53 +        dev_sxp = ['dev'] + reduce(lambda x, y: x + y, map(f, dev.items()))
    2.54 +        return dev_sxp
    2.55 +
    2.56      def all_devices_sxpr(self, target = None):
    2.57          """Returns the SXPR for all devices in the current configuration."""
    2.58          sxprs = []
    2.59 @@ -1997,10 +2002,7 @@ class XendConfig(dict):
    2.60                      if dev_info.has_key('backend'):
    2.61                          sxpr.append(['backend', dev_info['backend']])
    2.62                  for pci_dev_info in dev_info['devs']:
    2.63 -                    pci_dev_sxpr = ['dev']
    2.64 -                    for opt, val in pci_dev_info.items():
    2.65 -                        pci_dev_sxpr.append([opt, val])
    2.66 -                    sxpr.append(pci_dev_sxpr)
    2.67 +                    sxpr.append(self.dev_dict_to_sxp(pci_dev_info))
    2.68                  sxprs.append((dev_type, sxpr))
    2.69              else:
    2.70                  sxpr = self.device_sxpr(dev_type = dev_type,
    2.71 @@ -2127,11 +2129,7 @@ class XendConfig(dict):
    2.72                  slot = sxp.child_value(dev, 'slot')
    2.73                  func = sxp.child_value(dev, 'func')
    2.74                  vslot = sxp.child_value(dev, 'vslot')
    2.75 -                opts = ''
    2.76 -                for opt in sxp.child_value(dev, 'opts', []):
    2.77 -                    if opts:
    2.78 -                        opts += ','
    2.79 -                    opts += '%s=%s' % (opt[0], str(opt[1]))
    2.80 +                opts = pci_opts_list_from_sxp(dev)
    2.81                  pci.append([domain, bus, slot, func, vslot, opts])
    2.82          self['platform']['pci'] = pci
    2.83  
     3.1 --- a/tools/python/xen/xend/server/pciif.py	Tue Jun 16 11:36:40 2009 +0100
     3.2 +++ b/tools/python/xen/xend/server/pciif.py	Tue Jun 16 11:37:41 2009 +0100
     3.3 @@ -222,7 +222,8 @@ class PciController(DevController):
     3.4              dev_sxpr = ['dev']
     3.5              for dev_key, dev_val in dev.items():
     3.6                  if dev_key == 'opts':
     3.7 -                    dev_sxpr.append(['opts', split_pci_opts(dev_val)])
     3.8 +                    opts_sxpr = pci_opts_list_to_sxp(split_pci_opts(dev_val))
     3.9 +                    dev_sxpr = sxp.merge(dev_sxpr, opts_sxpr)
    3.10                  else:
    3.11                      dev_sxpr.append([dev_key, dev_val])
    3.12              sxpr.append(dev_sxpr)
     4.1 --- a/tools/python/xen/xm/create.py	Tue Jun 16 11:36:40 2009 +0100
     4.2 +++ b/tools/python/xen/xm/create.py	Tue Jun 16 11:37:41 2009 +0100
     4.3 @@ -38,6 +38,8 @@ from xen.util import vscsi_util
     4.4  import xen.util.xsm.xsm as security
     4.5  from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
     4.6  from xen.util import utils, auxbin
     4.7 +from xen.util.pci import split_pci_opts, check_pci_opts, \
     4.8 +                         pci_opts_list_to_sxp
     4.9  
    4.10  from xen.xm.opts import *
    4.11  
    4.12 @@ -706,23 +708,18 @@ def configure_pci(config_devs, vals):
    4.13      """
    4.14      config_pci = []
    4.15      for (domain, bus, slot, func, vslot, opts) in vals.pci:
    4.16 -        config_pci_opts = []
    4.17 -        d = comma_sep_kv_to_dict(opts)
    4.18 -
    4.19 -        def f(k):
    4.20 -            if k not in ['msitranslate', 'power_mgmt']:
    4.21 -                err('Invalid pci option: ' + k)
    4.22 -
    4.23 -            config_pci_opts.append([k, d[k]])
    4.24 -
    4.25          config_pci_bdf = ['dev', ['domain', domain], ['bus', bus], \
    4.26                            ['slot', slot], ['func', func],
    4.27                            ['vslot', vslot]]
    4.28 -        map(f, d.keys())
    4.29 -        if len(config_pci_opts)>0:
    4.30 -            config_pci_bdf.append(['opts', config_pci_opts])
    4.31  
    4.32 -        config_pci.append(config_pci_bdf)
    4.33 +        opts_list = split_pci_opts(opts)
    4.34 +        try:
    4.35 +            check_pci_opts(opts_list)
    4.36 +        except PciDeviceParseError, ex:
    4.37 +            err(str(ex))
    4.38 +
    4.39 +        config_opts = pci_opts_list_to_sxp(split_pci_opts(opts))
    4.40 +        config_pci.append(sxp.merge(config_pci_bdf, config_opts))
    4.41  
    4.42      if len(config_pci)>0:
    4.43          config_pci.insert(0, 'pci')
     5.1 --- a/tools/python/xen/xm/main.py	Tue Jun 16 11:36:40 2009 +0100
     5.2 +++ b/tools/python/xen/xm/main.py	Tue Jun 16 11:37:41 2009 +0100
     5.3 @@ -2507,12 +2507,15 @@ def parse_pci_configuration(args, state,
     5.4                  ['slot', '0x'+ pci_dev_info['slot']],
     5.5                  ['func', '0x'+ pci_dev_info['func']],
     5.6                  ['vslot', '0x%x' % int(vslot, 16)]]
     5.7 -        if len(opts) > 0:
     5.8 -            pci_bdf.append(['opts', opts])
     5.9 -        pci.append(pci_bdf)
    5.10 -
    5.11      except:
    5.12          raise OptionError("Invalid argument: %s %s" % (pci_dev_str, vslot))
    5.13 +
    5.14 +    try:
    5.15 +        check_pci_opts(opts)
    5.16 +    except PciDeviceParseError, ex:
    5.17 +        raise OptionError(str(ex))
    5.18 +
    5.19 +    pci.append(sxp.merge(pci_bdf, pci_opts_list_to_sxp(opts)))
    5.20      pci.append(['state', state])
    5.21  
    5.22      return (dom, pci)
     6.1 --- a/tools/python/xen/xm/xenapi_create.py	Tue Jun 16 11:36:40 2009 +0100
     6.2 +++ b/tools/python/xen/xm/xenapi_create.py	Tue Jun 16 11:37:41 2009 +0100
     6.3 @@ -26,6 +26,7 @@ from xen.xend.XendAPIConstants import XE
     6.4       XEN_API_ON_CRASH_BEHAVIOUR
     6.5  from xen.xm.opts import OptionError
     6.6  from xen.util import xsconstants
     6.7 +from xen.util.pci import pci_opts_list_from_sxp
     6.8  from xen.util.path import SHAREDIR
     6.9  import xen.util.xsm.xsm as security
    6.10  
    6.11 @@ -945,12 +946,11 @@ class sxp2xml:
    6.12                      = get_child_by_name(dev_sxp, "func", "0")
    6.13                  pci.attributes["vslot"] \
    6.14                      = get_child_by_name(dev_sxp, "vslot", "0")
    6.15 -                for opt in get_child_by_name(dev_sxp, "opts", ""):
    6.16 -                    if len(opt) > 0:
    6.17 -                        pci_opt = document.createElement("pci_opt")
    6.18 -                        pci_opt.attributes["key"] = opt[0]
    6.19 -                        pci_opt.attributes["value"] = opt[1]
    6.20 -                        pci.appendChild(pci_opt)
    6.21 +                for opt in pci_opts_list_from_sxp(dev_sxp):
    6.22 +                    pci_opt = document.createElement("pci_opt")
    6.23 +                    pci_opt.attributes["key"] = opt[0]
    6.24 +                    pci_opt.attributes["value"] = opt[1]
    6.25 +                    pci.appendChild(pci_opt)
    6.26  
    6.27                  pcis.append(pci)
    6.28