mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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>
This commit is contained in:
1 parent
60dadd604d
commit
44c1edcdb5
4 files changed
+52
-26
No files matched your search
@@ -14,6 +14,7 @@ import struct
|
||||
import time
|
||||
import threading
|
||||
from xen.util import utils
|
||||
from xen.xend import sxp
|
||||
|
||||
PROC_PCI_PATH = '/proc/bus/pci/devices'
|
||||
PROC_PCI_NUM_RESOURCES = 7
|
||||
@@ -140,10 +141,17 @@ def parse_pci_name(pci_name_string):
|
||||
return (domain, bus, slot, func)
|
||||
|
||||
def assigned_or_requested_vslot(dev):
|
||||
if dev.has_key("vslot"):
|
||||
return dev["vslot"]
|
||||
if dev.has_key("requested_vslot"):
|
||||
return dev["requested_vslot"]
|
||||
if isinstance(dev, types.DictType):
|
||||
if dev.has_key("vslot"):
|
||||
return dev["vslot"]
|
||||
if dev.has_key("requested_vslot"):
|
||||
return dev["requested_vslot"]
|
||||
elif isinstance(dev, (types.ListType, types.TupleType)):
|
||||
vslot = sxp.child_value(dev, 'vslot', None)
|
||||
if not vslot:
|
||||
vslot = sxp.child_value(dev, 'requested_vslot', None)
|
||||
if vslot:
|
||||
return vslot
|
||||
raise PciDeviceVslotMissing("%s" % dev)
|
||||
|
||||
def find_sysfs_mnt():
|
||||
|
||||
@@ -37,6 +37,7 @@ from xen.xend.xenstore.xstransact import xstransact
|
||||
from xen.xend.server.BlktapController import blktap_disk_types
|
||||
from xen.xend.server.netif import randomMAC
|
||||
from xen.util.blkif import blkdev_name_to_number, blkdev_uname_to_file
|
||||
from xen.util.pci import assigned_or_requested_vslot
|
||||
from xen.util import xsconstants
|
||||
import xen.util.auxbin
|
||||
|
||||
@@ -2186,3 +2187,26 @@ class XendConfig(dict):
|
||||
|
||||
def is_hap(self):
|
||||
return self['platform'].get('hap', 0)
|
||||
|
||||
def update_platform_pci(self):
|
||||
if not self.is_hvm():
|
||||
return
|
||||
|
||||
pci = []
|
||||
for dev_type, dev_info in self.all_devices_sxpr():
|
||||
if dev_type != 'pci':
|
||||
continue
|
||||
for dev in sxp.children(dev_info, 'dev'):
|
||||
domain = sxp.child_value(dev, 'domain')
|
||||
bus = sxp.child_value(dev, 'bus')
|
||||
slot = sxp.child_value(dev, 'slot')
|
||||
func = sxp.child_value(dev, 'func')
|
||||
vslot = assigned_or_requested_vslot(dev)
|
||||
opts = ''
|
||||
for opt in sxp.child_value(dev, 'opts', []):
|
||||
if opts:
|
||||
opts += ','
|
||||
opts += '%s=%s' % (opt[0], str(opt[1]))
|
||||
pci.append([domain, bus, slot, func, vslot, opts])
|
||||
self['platform']['pci'] = pci
|
||||
|
||||
@@ -893,18 +893,9 @@ class XendDomainInfo:
|
||||
if num_devs == 0:
|
||||
if self.info.is_hvm():
|
||||
self.destroyDevice('pci', devid, True)
|
||||
del self.info['devices'][dev_uuid]
|
||||
platform = self.info['platform']
|
||||
orig_dev_num = len(platform['pci'])
|
||||
# TODO: can use this to keep some info to ask high level
|
||||
# management tools to hot insert a new passthrough dev
|
||||
# after migration
|
||||
if orig_dev_num != 0:
|
||||
#platform['pci'] = ["%dDEVs" % orig_dev_num]
|
||||
platform['pci'] = []
|
||||
else:
|
||||
self.destroyDevice('pci', devid)
|
||||
del self.info['devices'][dev_uuid]
|
||||
del self.info['devices'][dev_uuid]
|
||||
else:
|
||||
new_dev_sxp = ['pci']
|
||||
for cur_dev in sxp.children(existing_dev_info, 'dev'):
|
||||
@@ -923,18 +914,9 @@ class XendDomainInfo:
|
||||
dev_uuid = sxp.child_value(existing_dev_info, 'uuid')
|
||||
self.info.device_update(dev_uuid, new_dev_sxp)
|
||||
|
||||
# If there is only 'vscsi' in new_dev_sxp, remove the config.
|
||||
# If there is no device left, remove config.
|
||||
if len(sxp.children(new_dev_sxp, 'dev')) == 0:
|
||||
del self.info['devices'][dev_uuid]
|
||||
if self.info.is_hvm():
|
||||
platform = self.info['platform']
|
||||
orig_dev_num = len(platform['pci'])
|
||||
# TODO: can use this to keep some info to ask high level
|
||||
# management tools to hot insert a new passthrough dev
|
||||
# after migration
|
||||
if orig_dev_num != 0:
|
||||
#platform['pci'] = ["%dDEVs" % orig_dev_num]
|
||||
platform['pci'] = []
|
||||
|
||||
xen.xend.XendDomain.instance().managed_config_save(self)
|
||||
|
||||
@@ -2463,6 +2445,7 @@ class XendDomainInfo:
|
||||
(self.getVCpuCount() * 100))
|
||||
|
||||
# Test whether the devices can be assigned with VT-d
|
||||
self.info.update_platform_pci()
|
||||
pci = self.info["platform"].get("pci")
|
||||
pci_str = ''
|
||||
if pci and len(pci) > 0:
|
||||
|
||||
@@ -223,6 +223,11 @@ class PciController(DevController):
|
||||
except IndexError:
|
||||
dev_dict['vslot'] = AUTO_PHP_SLOT_STR
|
||||
|
||||
#append opts info
|
||||
opts = self.readBackend(devid, 'opts-%d' % i)
|
||||
if opts is not None:
|
||||
dev_dict['opts'] = opts
|
||||
|
||||
pci_devs.append(dev_dict)
|
||||
|
||||
result['devs'] = pci_devs
|
||||
@@ -243,8 +248,14 @@ class PciController(DevController):
|
||||
|
||||
for dev in devs:
|
||||
dev_sxpr = ['dev']
|
||||
for dev_item in dev.items():
|
||||
dev_sxpr.append(list(dev_item))
|
||||
for dev_key, dev_val in dev.items():
|
||||
if dev_key == 'opts':
|
||||
opts = []
|
||||
for opt in dev_val.split(','):
|
||||
opts.append(opt.split('='))
|
||||
dev_sxpr.append(['opts', opts])
|
||||
else:
|
||||
dev_sxpr.append([dev_key, dev_val])
|
||||
sxpr.append(dev_sxpr)
|
||||
|
||||
for key, val in configDict.items():
|
||||
|
||||