ia64/xen-unstable

changeset 19669:e95c4611a0ae

xend: Update info['platform']['pci']

This patch updates info['platform']['pci'] for PCI devices
assignment to domains.

When a domain is started, xend confirms by using xc.test_assign_device
whether PCI devices can be assigned to the domain. For the
confirmation, info['platform']['pci'] must be an appropriate value.
However, info['platform']['pci'] may be not appropriate. Because
info['platform']['pci'] isn't almost always updated even if the PCI
device configuration of the domain was changed by using xm
pci-attach/detach. This patch updates info['platform']['pci'] to the
appropriate value when domains are started.

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 28 10:06:01 2009 +0100 (2009-05-28)
parents 56d00bbc21e2
children 0e111bfd22d0
files tools/python/xen/util/pci.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/pciif.py
line diff
     1.1 --- a/tools/python/xen/util/pci.py	Thu May 28 10:03:29 2009 +0100
     1.2 +++ b/tools/python/xen/util/pci.py	Thu May 28 10:06:01 2009 +0100
     1.3 @@ -14,6 +14,7 @@ import struct
     1.4  import time
     1.5  import threading
     1.6  from xen.util import utils
     1.7 +from xen.xend import sxp
     1.8  
     1.9  PROC_PCI_PATH = '/proc/bus/pci/devices'
    1.10  PROC_PCI_NUM_RESOURCES = 7
    1.11 @@ -140,10 +141,17 @@ def parse_pci_name(pci_name_string):
    1.12      return (domain, bus, slot, func)
    1.13  
    1.14  def assigned_or_requested_vslot(dev):
    1.15 -    if dev.has_key("vslot"):
    1.16 -        return dev["vslot"]
    1.17 -    if dev.has_key("requested_vslot"):
    1.18 -        return dev["requested_vslot"]
    1.19 +    if isinstance(dev, types.DictType):
    1.20 +        if dev.has_key("vslot"):
    1.21 +            return dev["vslot"]
    1.22 +        if dev.has_key("requested_vslot"):
    1.23 +            return dev["requested_vslot"]
    1.24 +    elif isinstance(dev, (types.ListType, types.TupleType)):
    1.25 +        vslot = sxp.child_value(dev, 'vslot', None)
    1.26 +        if not vslot:
    1.27 +            vslot = sxp.child_value(dev, 'requested_vslot', None)
    1.28 +        if vslot:
    1.29 +            return vslot
    1.30      raise PciDeviceVslotMissing("%s" % dev)
    1.31  
    1.32  def find_sysfs_mnt():
     2.1 --- a/tools/python/xen/xend/XendConfig.py	Thu May 28 10:03:29 2009 +0100
     2.2 +++ b/tools/python/xen/xend/XendConfig.py	Thu May 28 10:06:01 2009 +0100
     2.3 @@ -37,6 +37,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 assigned_or_requested_vslot
     2.8  from xen.util import xsconstants
     2.9  import xen.util.auxbin
    2.10  
    2.11 @@ -2186,3 +2187,26 @@ class XendConfig(dict):
    2.12  
    2.13      def is_hap(self):
    2.14          return self['platform'].get('hap', 0)
    2.15 +
    2.16 +    def update_platform_pci(self):
    2.17 +        if not self.is_hvm():
    2.18 +            return
    2.19 +
    2.20 +        pci = []
    2.21 +        for dev_type, dev_info in self.all_devices_sxpr():
    2.22 +            if dev_type != 'pci':
    2.23 +                continue
    2.24 +            for dev in sxp.children(dev_info, 'dev'):
    2.25 +                domain = sxp.child_value(dev, 'domain')
    2.26 +                bus = sxp.child_value(dev, 'bus')
    2.27 +                slot = sxp.child_value(dev, 'slot')
    2.28 +                func = sxp.child_value(dev, 'func')
    2.29 +                vslot = assigned_or_requested_vslot(dev) 
    2.30 +                opts = ''
    2.31 +                for opt in sxp.child_value(dev, 'opts', []):
    2.32 +                    if opts:
    2.33 +                        opts += ','
    2.34 +                    opts += '%s=%s' % (opt[0], str(opt[1]))
    2.35 +                pci.append([domain, bus, slot, func, vslot, opts])
    2.36 +        self['platform']['pci'] = pci
    2.37 +
     3.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu May 28 10:03:29 2009 +0100
     3.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu May 28 10:06:01 2009 +0100
     3.3 @@ -893,18 +893,9 @@ class XendDomainInfo:
     3.4              if num_devs == 0:
     3.5                  if self.info.is_hvm():
     3.6                      self.destroyDevice('pci', devid, True)
     3.7 -                    del self.info['devices'][dev_uuid]
     3.8 -                    platform = self.info['platform']
     3.9 -                    orig_dev_num = len(platform['pci'])
    3.10 -                    # TODO: can use this to keep some info to ask high level
    3.11 -                    # management tools to hot insert a new passthrough dev
    3.12 -                    # after migration
    3.13 -                    if orig_dev_num != 0:
    3.14 -                        #platform['pci'] = ["%dDEVs" % orig_dev_num]
    3.15 -                        platform['pci'] = []
    3.16                  else:
    3.17                      self.destroyDevice('pci', devid)
    3.18 -                    del self.info['devices'][dev_uuid]
    3.19 +                del self.info['devices'][dev_uuid]
    3.20          else:
    3.21              new_dev_sxp = ['pci']
    3.22              for cur_dev in sxp.children(existing_dev_info, 'dev'):
    3.23 @@ -923,18 +914,9 @@ class XendDomainInfo:
    3.24              dev_uuid = sxp.child_value(existing_dev_info, 'uuid')
    3.25              self.info.device_update(dev_uuid, new_dev_sxp)
    3.26  
    3.27 -            # If there is only 'vscsi' in new_dev_sxp, remove the config.
    3.28 +            # If there is no device left, remove config.
    3.29              if len(sxp.children(new_dev_sxp, 'dev')) == 0:
    3.30                  del self.info['devices'][dev_uuid]
    3.31 -                if self.info.is_hvm():
    3.32 -                    platform = self.info['platform']
    3.33 -                    orig_dev_num = len(platform['pci'])
    3.34 -                    # TODO: can use this to keep some info to ask high level
    3.35 -                    # management tools to hot insert a new passthrough dev
    3.36 -                    # after migration
    3.37 -                    if orig_dev_num != 0:
    3.38 -                        #platform['pci'] = ["%dDEVs" % orig_dev_num]
    3.39 -                        platform['pci'] = []
    3.40  
    3.41          xen.xend.XendDomain.instance().managed_config_save(self)
    3.42  
    3.43 @@ -2463,6 +2445,7 @@ class XendDomainInfo:
    3.44                                (self.getVCpuCount() * 100))
    3.45  
    3.46          # Test whether the devices can be assigned with VT-d
    3.47 +        self.info.update_platform_pci()
    3.48          pci = self.info["platform"].get("pci")
    3.49          pci_str = ''
    3.50          if pci and len(pci) > 0:
     4.1 --- a/tools/python/xen/xend/server/pciif.py	Thu May 28 10:03:29 2009 +0100
     4.2 +++ b/tools/python/xen/xend/server/pciif.py	Thu May 28 10:06:01 2009 +0100
     4.3 @@ -223,6 +223,11 @@ class PciController(DevController):
     4.4                      except IndexError:
     4.5                          dev_dict['vslot'] = AUTO_PHP_SLOT_STR
     4.6  
     4.7 +                #append opts info
     4.8 +                opts = self.readBackend(devid, 'opts-%d' % i)
     4.9 +                if opts is not None:
    4.10 +                    dev_dict['opts'] = opts
    4.11 +
    4.12                  pci_devs.append(dev_dict)
    4.13  
    4.14          result['devs'] = pci_devs
    4.15 @@ -243,8 +248,14 @@ class PciController(DevController):
    4.16          
    4.17          for dev in devs:
    4.18              dev_sxpr = ['dev']
    4.19 -            for dev_item in dev.items():
    4.20 -                dev_sxpr.append(list(dev_item))
    4.21 +            for dev_key, dev_val in dev.items():
    4.22 +                if dev_key == 'opts':
    4.23 +                    opts = []
    4.24 +                    for opt in dev_val.split(','):
    4.25 +                        opts.append(opt.split('='))
    4.26 +                    dev_sxpr.append(['opts', opts])
    4.27 +                else:
    4.28 +                    dev_sxpr.append([dev_key, dev_val])
    4.29              sxpr.append(dev_sxpr)
    4.30          
    4.31          for key, val in configDict.items():