]> xenbits.xensource.com Git - xen.git/commitdiff
xend: Fix 'xm pci_list_assignable_devices'
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 31 Mar 2009 10:28:08 +0000 (11:28 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 31 Mar 2009 10:28:08 +0000 (11:28 +0100)
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>
tools/python/xen/xend/XendNode.py
tools/python/xen/xend/server/XMLRPCServer.py
tools/python/xen/xm/main.py

index 1a40735cba82e47dc3bc055adc5b42b3edcba5aa..047054a961f87c17c95e6bb70878d0c28809e93a 100644 (file)
@@ -806,6 +806,43 @@ class XendNode:
 
         return [[k, info[k]] for k in ITEM_ORDER]
 
+
+    def pciinfo(self):
+        # Each element of dev_list is a PciDevice
+        dev_list = PciUtil.find_all_devices_owned_by_pciback()
+        # Each element of devs_list is a list of PciDevice
+        devs_list = PciUtil.check_FLR_capability(dev_list)
+        devs_list = PciUtil.check_mmio_bar(devs_list)
+        # Check if the devices have been assigned to guests.
+        final_devs_list = []
+        for dev_list in devs_list:
+            available = True
+            for d in dev_list:
+                pci_str = '0x%x,0x%x,0x%x,0x%x' %(d.domain, d.bus, d.slot, d.func)
+                # Xen doesn't care what the domid is, so we pass 0 here...
+                domid = 0
+                bdf = self.xc.test_assign_device(domid, pci_str)
+                if bdf != 0:
+                    available = False
+                    break
+            if available:
+                final_devs_list = final_devs_list + [dev_list]
+
+        pci_sxp_list = []
+        for dev_list in final_devs_list:
+            for d in dev_list:
+                pci_sxp = ['dev', ['domain', '0x%04x' % d.domain],
+                                  ['bus', '0x%02x' % d.bus],
+                                  ['slot', '0x%02x' % d.slot],
+                                  ['func', '0x%x' % d.func]]
+                pci_sxp_list.append(pci_sxp)
+
+        return pci_sxp_list
+
     def xenschedinfo(self):
         sched_id = self.xc.sched_id_get()
         if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
index 96c0ac24aa034c4433f30eab2430523a219e2414..fb9bdfee345cb79c422d19322546c8e35686514d 100644 (file)
@@ -198,7 +198,8 @@ class XMLRPCServer:
                     self.server.register_function(fn, "xend.domain.%s" % name[7:])
 
         # Functions in XendNode and XendDmesg
-        for type, lst, n in [(XendNode, ['info', 'send_debug_keys'], 'node'),
+        for type, lst, n in [(XendNode, ['info', 'pciinfo', 'send_debug_keys'],
+                             'node'),
                              (XendDmesg, ['info', 'clear'], 'node.dmesg')]:
             inst = type.instance()
             for name in lst:
index 46cf8e4052d21c1646e80a9c5e2ed51e7d962425..8c7ba968e8f9a8fee27399bbc73776b3ca5fd16e 100644 (file)
@@ -58,13 +58,6 @@ from xen.util.acmpolicy import ACM_LABEL_UNLABELED_DISPLAY
 
 import XenAPI
 
-import xen.lowlevel.xc
-try:
-    xc = xen.lowlevel.xc.xc()
-except Exception, ex:
-    print >>sys.stderr, ("Is xen kernel running?")
-    sys.exit(1)
-
 import inspect
 from xen.xend import XendOptions
 xoptions = XendOptions.instance()
@@ -2188,34 +2181,28 @@ def xm_pci_list(args):
             hdr = 1
         print ( fmt_str % x )
 
+
+def parse_pci_info(info):
+    def get_info(n, t, d):
+        return t(sxp.child_value(info, n, d))
+    return {
+        'domain' : get_info('domain', parse_hex, 0),
+        'bus'    : get_info('bus', parse_hex, -1),
+        'slot'   : get_info('slot', parse_hex, -1),
+        'func'   : get_info('func', parse_hex, -1)
+        }
+
 def xm_pci_list_assignable_devices(args):
-    # Each element of dev_list is a PciDevice
-    dev_list = find_all_devices_owned_by_pciback()
-
-    # Each element of devs_list is a list of PciDevice
-    devs_list = check_FLR_capability(dev_list)
-
-    devs_list = check_mmio_bar(devs_list)
-
-    # Check if the devices have been assigned to guests.
-    final_devs_list = []
-    for dev_list in devs_list:
-        available = True
-        for d in dev_list:
-            pci_str = '0x%x,0x%x,0x%x,0x%x' %(d.domain, d.bus, d.slot, d.func)
-            # Xen doesn't care what the domid is, so we pass 0 here...
-            domid = 0
-            bdf = xc.test_assign_device(domid, pci_str)
-            if bdf != 0:
-                available = False
-                break
-        if available:
-            final_devs_list = final_devs_list + [dev_list]
+    xenapi_unsupported()
+    arg_check(args, "pci-list-assignable-devices", 0)
+
+    devs =  server.xend.node.pciinfo()
+    fmt_str = "%(domain)04x:%(bus)02x:%(slot)02x:%(func)01x"
+    for x in devs:
+        pci = parse_pci_info(x)
+        print fmt_str % pci
 
-    for dev_list in final_devs_list:
-        for d in dev_list:
-            print d.name,
-        print
 
 def vscsi_sort(devs):
     def sort_hctl(ds, l):