From 75f6b53ab0b00cd26540c75dcde4be184cae9794 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 31 Mar 2009 11:28:08 +0100 Subject: [PATCH] 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 --- tools/python/xen/xend/XendNode.py | 37 ++++++++++++++ tools/python/xen/xend/server/XMLRPCServer.py | 3 +- tools/python/xen/xm/main.py | 53 ++++++++------------ 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index 1a40735cba..047054a961 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -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: diff --git a/tools/python/xen/xend/server/XMLRPCServer.py b/tools/python/xen/xend/server/XMLRPCServer.py index 96c0ac24aa..fb9bdfee34 100644 --- a/tools/python/xen/xend/server/XMLRPCServer.py +++ b/tools/python/xen/xend/server/XMLRPCServer.py @@ -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: diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 46cf8e4052..8c7ba968e8 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -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): -- 2.39.5