ia64/xen-unstable

changeset 19448:2ef77b4bdf58

xend: Fix 'xm pci_list_assignable_devices'

The current implementation of 'xm pci-list-assignable-devices' command
has a problem that it directly invokes hypercall using
xen.lowlevel.xc.
This is probably based on an assumption that the command is executed
on the host itself, but in fact there are cases xm commands can be
executed on a remote server through xmlrpc.
So this patch makes the xm command just inquire of xend about the
information of available devices.

Signed-off-by: Yosuke Iwamatsu <y-iwamatsu@ab.jp.nec.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 31 11:28:08 2009 +0100 (2009-03-31)
parents 2d19139c1c9c
children 46188402c2d9
files tools/python/xen/xend/XendNode.py tools/python/xen/xend/server/XMLRPCServer.py tools/python/xen/xm/main.py
line diff
     1.1 --- a/tools/python/xen/xend/XendNode.py	Tue Mar 31 11:27:10 2009 +0100
     1.2 +++ b/tools/python/xen/xend/XendNode.py	Tue Mar 31 11:28:08 2009 +0100
     1.3 @@ -806,6 +806,43 @@ class XendNode:
     1.4  
     1.5          return [[k, info[k]] for k in ITEM_ORDER]
     1.6  
     1.7 +
     1.8 +    def pciinfo(self):
     1.9 +        # Each element of dev_list is a PciDevice
    1.10 +        dev_list = PciUtil.find_all_devices_owned_by_pciback()
    1.11 + 
    1.12 +        # Each element of devs_list is a list of PciDevice
    1.13 +        devs_list = PciUtil.check_FLR_capability(dev_list)
    1.14 + 
    1.15 +        devs_list = PciUtil.check_mmio_bar(devs_list)
    1.16 + 
    1.17 +        # Check if the devices have been assigned to guests.
    1.18 +        final_devs_list = []
    1.19 +        for dev_list in devs_list:
    1.20 +            available = True
    1.21 +            for d in dev_list:
    1.22 +                pci_str = '0x%x,0x%x,0x%x,0x%x' %(d.domain, d.bus, d.slot, d.func)
    1.23 +                # Xen doesn't care what the domid is, so we pass 0 here...
    1.24 +                domid = 0
    1.25 +                bdf = self.xc.test_assign_device(domid, pci_str)
    1.26 +                if bdf != 0:
    1.27 +                    available = False
    1.28 +                    break
    1.29 +            if available:
    1.30 +                final_devs_list = final_devs_list + [dev_list]
    1.31 +
    1.32 +        pci_sxp_list = []
    1.33 +        for dev_list in final_devs_list:
    1.34 +            for d in dev_list:
    1.35 +                pci_sxp = ['dev', ['domain', '0x%04x' % d.domain],
    1.36 +                                  ['bus', '0x%02x' % d.bus],
    1.37 +                                  ['slot', '0x%02x' % d.slot],
    1.38 +                                  ['func', '0x%x' % d.func]]
    1.39 +                pci_sxp_list.append(pci_sxp)
    1.40 +
    1.41 +        return pci_sxp_list
    1.42 + 
    1.43 +
    1.44      def xenschedinfo(self):
    1.45          sched_id = self.xc.sched_id_get()
    1.46          if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
     2.1 --- a/tools/python/xen/xend/server/XMLRPCServer.py	Tue Mar 31 11:27:10 2009 +0100
     2.2 +++ b/tools/python/xen/xend/server/XMLRPCServer.py	Tue Mar 31 11:28:08 2009 +0100
     2.3 @@ -198,7 +198,8 @@ class XMLRPCServer:
     2.4                      self.server.register_function(fn, "xend.domain.%s" % name[7:])
     2.5  
     2.6          # Functions in XendNode and XendDmesg
     2.7 -        for type, lst, n in [(XendNode, ['info', 'send_debug_keys'], 'node'),
     2.8 +        for type, lst, n in [(XendNode, ['info', 'pciinfo', 'send_debug_keys'],
     2.9 +                             'node'),
    2.10                               (XendDmesg, ['info', 'clear'], 'node.dmesg')]:
    2.11              inst = type.instance()
    2.12              for name in lst:
     3.1 --- a/tools/python/xen/xm/main.py	Tue Mar 31 11:27:10 2009 +0100
     3.2 +++ b/tools/python/xen/xm/main.py	Tue Mar 31 11:28:08 2009 +0100
     3.3 @@ -58,13 +58,6 @@ from xen.util.acmpolicy import ACM_LABEL
     3.4  
     3.5  import XenAPI
     3.6  
     3.7 -import xen.lowlevel.xc
     3.8 -try:
     3.9 -    xc = xen.lowlevel.xc.xc()
    3.10 -except Exception, ex:
    3.11 -    print >>sys.stderr, ("Is xen kernel running?")
    3.12 -    sys.exit(1)
    3.13 -
    3.14  import inspect
    3.15  from xen.xend import XendOptions
    3.16  xoptions = XendOptions.instance()
    3.17 @@ -2188,34 +2181,28 @@ def xm_pci_list(args):
    3.18              hdr = 1
    3.19          print ( fmt_str % x )
    3.20  
    3.21 +
    3.22 +def parse_pci_info(info):
    3.23 +    def get_info(n, t, d):
    3.24 +        return t(sxp.child_value(info, n, d))
    3.25 +    return {
    3.26 +        'domain' : get_info('domain', parse_hex, 0),
    3.27 +        'bus'    : get_info('bus', parse_hex, -1),
    3.28 +        'slot'   : get_info('slot', parse_hex, -1),
    3.29 +        'func'   : get_info('func', parse_hex, -1)
    3.30 +        }
    3.31 +
    3.32  def xm_pci_list_assignable_devices(args):
    3.33 -    # Each element of dev_list is a PciDevice
    3.34 -    dev_list = find_all_devices_owned_by_pciback()
    3.35 -
    3.36 -    # Each element of devs_list is a list of PciDevice
    3.37 -    devs_list = check_FLR_capability(dev_list)
    3.38 -
    3.39 -    devs_list = check_mmio_bar(devs_list)
    3.40 -
    3.41 -    # Check if the devices have been assigned to guests.
    3.42 -    final_devs_list = []
    3.43 -    for dev_list in devs_list:
    3.44 -        available = True
    3.45 -        for d in dev_list:
    3.46 -            pci_str = '0x%x,0x%x,0x%x,0x%x' %(d.domain, d.bus, d.slot, d.func)
    3.47 -            # Xen doesn't care what the domid is, so we pass 0 here...
    3.48 -            domid = 0
    3.49 -            bdf = xc.test_assign_device(domid, pci_str)
    3.50 -            if bdf != 0:
    3.51 -                available = False
    3.52 -                break
    3.53 -        if available:
    3.54 -            final_devs_list = final_devs_list + [dev_list]
    3.55 -
    3.56 -    for dev_list in final_devs_list:
    3.57 -        for d in dev_list:
    3.58 -            print d.name,
    3.59 -        print
    3.60 +    xenapi_unsupported()
    3.61 +    arg_check(args, "pci-list-assignable-devices", 0)
    3.62 +
    3.63 +    devs =  server.xend.node.pciinfo()
    3.64 + 
    3.65 +    fmt_str = "%(domain)04x:%(bus)02x:%(slot)02x:%(func)01x"
    3.66 +    for x in devs:
    3.67 +        pci = parse_pci_info(x)
    3.68 +        print fmt_str % pci
    3.69 +
    3.70  
    3.71  def vscsi_sort(devs):
    3.72      def sort_hctl(ds, l):