Merge "pci: move filtering of devices up into resource tracker"

This commit is contained in:
Jenkins
2015-01-06 01:28:34 +00:00
committed by Gerrit Code Review
6 changed files with 92 additions and 61 deletions
+13 -2
View File
@@ -37,6 +37,7 @@ from nova import objects
from nova.objects import base as obj_base
from nova.openstack.common import log as logging
from nova.pci import manager as pci_manager
from nova.pci import whitelist as pci_whitelist
from nova import rpc
from nova.scheduler import client as scheduler_client
from nova import utils
@@ -73,6 +74,7 @@ class ResourceTracker(object):
self.host = host
self.driver = driver
self.pci_tracker = None
self.pci_filter = pci_whitelist.get_pci_devices_filter()
self.nodename = nodename
self.compute_node = None
self.stats = importutils.import_object(CONF.compute_stats_class)
@@ -336,8 +338,17 @@ class ResourceTracker(object):
if 'pci_passthrough_devices' in resources:
if not self.pci_tracker:
self.pci_tracker = pci_manager.PciDevTracker()
self.pci_tracker.set_hvdevs(jsonutils.loads(resources.pop(
'pci_passthrough_devices')))
devs = []
for dev in jsonutils.loads(resources.pop(
'pci_passthrough_devices')):
if dev['dev_type'] == 'type-PF':
continue
if self.pci_filter.device_assignable(dev):
devs.append(dev)
self.pci_tracker.set_hvdevs(devs)
# Grab all instances assigned to this node:
instances = objects.InstanceList.get_by_host_and_node(
@@ -91,19 +91,70 @@ class FakeVirtDriver(driver.ComputeDriver):
self.memory_mb_used = 0
self.local_gb_used = 0
self.pci_support = pci_support
self.pci_devices = [{
'label': 'forza-napoli',
'dev_type': 'foo',
'compute_node_id': 1,
'address': '0000:00:00.1',
'product_id': 'p1',
'vendor_id': 'v1',
'status': 'available',
'extra_k1': 'v1'}] if self.pci_support else []
self.pci_stats = [{
'count': 1,
'vendor_id': 'v1',
'product_id': 'p1'}] if self.pci_support else []
self.pci_devices = [
{
'label': 'label_8086_0443',
'dev_type': 'type-VF',
'compute_node_id': 1,
'address': '0000:00:01.1',
'product_id': '0443',
'vendor_id': '8086',
'status': 'available',
'extra_k1': 'v1'
},
{
'label': 'label_8086_0443',
'dev_type': 'type-VF',
'compute_node_id': 1,
'address': '0000:00:01.2',
'product_id': '0443',
'vendor_id': '8086',
'status': 'available',
'extra_k1': 'v1'
},
{
'label': 'label_8086_0443',
'dev_type': 'type-PF',
'compute_node_id': 1,
'address': '0000:00:01.0',
'product_id': '0443',
'vendor_id': '8086',
'status': 'available',
'extra_k1': 'v1'
},
{
'label': 'label_8086_0123',
'dev_type': 'type-PCI',
'compute_node_id': 1,
'address': '0000:00:01.0',
'product_id': '0123',
'vendor_id': '8086',
'status': 'available',
'extra_k1': 'v1'
},
{
'label': 'label_8086_7891',
'dev_type': 'type-VF',
'compute_node_id': 1,
'address': '0000:00:01.0',
'product_id': '7891',
'vendor_id': '8086',
'status': 'available',
'extra_k1': 'v1'
},
] if self.pci_support else []
self.pci_stats = [
{
'count': 2,
'vendor_id': '8086',
'product_id': '0443'
},
{
'count': 1,
'vendor_id': '8086',
'product_id': '7891'
},
] if self.pci_support else []
if stats is not None:
self.stats = stats
@@ -149,6 +200,9 @@ class BaseTestCase(test.TestCase):
self.context = context.get_admin_context()
self.flags(pci_passthrough_whitelist=[
'{"vendor_id": "8086", "product_id": "0443"}',
'{"vendor_id": "8086", "product_id": "7891"}'])
self.flags(use_local=True, group='conductor')
self.conductor = self.start_service('conductor',
manager=CONF.conductor.manager)
+6 -17
View File
@@ -8745,17 +8745,6 @@ class LibvirtConnTestCase(test.NoDBTestCase):
self.assertEqual(actualvf, expect_vf)
def test_pci_device_assignable(self):
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.stubs.Set(conn.dev_filter, 'device_assignable', lambda x: True)
fake_dev = {'dev_type': 'type-PF'}
self.assertFalse(conn._pci_device_assignable(fake_dev))
fake_dev = {'dev_type': 'type-VF'}
self.assertTrue(conn._pci_device_assignable(fake_dev))
fake_dev = {'dev_type': 'type-PCI'}
self.assertTrue(conn._pci_device_assignable(fake_dev))
def test_list_devices_not_supported(self):
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
@@ -8799,13 +8788,12 @@ class LibvirtConnTestCase(test.NoDBTestCase):
libvirt_driver.LibvirtDriver._conn.nodeDeviceLookupByName =\
fake_nodeDeviceLookupByName
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.stubs.Set(conn.dev_filter, 'device_assignable', lambda x: x)
actjson = conn._get_pci_passthrough_devices()
expectvfs = [
{
"dev_id": "pci_0000_04_00_3",
"address": "0000:04:10.3",
"address": "0000:04:00.3",
"product_id": '1521',
"vendor_id": '8086',
"dev_type": 'type-PF',
@@ -8821,10 +8809,11 @@ class LibvirtConnTestCase(test.NoDBTestCase):
}
]
actctualvfs = jsonutils.loads(actjson)
for key in actctualvfs[0].keys():
if key not in ['phys_function', 'virt_functions', 'label']:
self.assertEqual(actctualvfs[0][key], expectvfs[1][key])
actualvfs = jsonutils.loads(actjson)
for dev in range(len(actualvfs)):
for key in actualvfs[dev].keys():
if key not in ['phys_function', 'virt_functions', 'label']:
self.assertEqual(actualvfs[dev][key], expectvfs[dev][key])
def _fake_caps_numa_topology(self):
topology = vconfig.LibvirtConfigCapsNUMATopology()
+2 -10
View File
@@ -2079,17 +2079,9 @@ class XenAPIHostTestCase(stubs.XenAPITestBase):
stats = self.conn.host_state.get_host_stats(True)
self.assertEqual(stats['vcpus_used'], 4)
def test_pci_passthrough_devices_whitelist(self):
# NOTE(guillaume-thouvenin): This pci whitelist will be used to
# match with _plugin_xenhost_get_pci_device_details method in fake.py.
white_list = '{"vendor_id":"10de", "product_id":"11bf"}'
self.flags(pci_passthrough_whitelist=[white_list])
def test_pci_passthrough_devices(self):
stats = self.conn.host_state.get_host_stats(False)
self.assertEqual(len(stats['pci_passthrough_devices']), 1)
def test_pci_passthrough_devices_no_whitelist(self):
stats = self.conn.host_state.get_host_stats(False)
self.assertEqual(len(stats['pci_passthrough_devices']), 0)
self.assertEqual(len(stats['pci_passthrough_devices']), 2)
def test_host_state_missing_sr(self):
# Must trigger construction of 'host_state' property
+1 -11
View File
@@ -80,7 +80,6 @@ from nova.openstack.common import log as logging
from nova.openstack.common import loopingcall
from nova.pci import manager as pci_manager
from nova.pci import utils as pci_utils
from nova.pci import whitelist as pci_whitelist
from nova import rpc
from nova import utils
from nova import version
@@ -403,8 +402,6 @@ class LibvirtDriver(driver.ComputeDriver):
self.volume_drivers = driver.driver_dict_from_config(
CONF.libvirt.volume_drivers, self)
self.dev_filter = pci_whitelist.get_pci_devices_filter()
self._disk_cachemode = None
self.image_cache_manager = imagecache.ImageCacheManager()
self.image_backend = imagebackend.Backend(CONF.use_cow_images)
@@ -4689,11 +4686,6 @@ class LibvirtDriver(driver.ComputeDriver):
device.update(_get_device_type(cfgdev))
return device
def _pci_device_assignable(self, device):
if device['dev_type'] == 'type-PF':
return False
return self.dev_filter.device_assignable(device)
def _get_pci_passthrough_devices(self):
"""Get host PCI devices information.
@@ -4729,9 +4721,7 @@ class LibvirtDriver(driver.ComputeDriver):
pci_info = []
for name in dev_names:
pci_dev = self._get_pcidev_info(name)
if self._pci_device_assignable(pci_dev):
pci_info.append(pci_dev)
pci_info.append(self._get_pcidev_info(name))
return jsonutils.dumps(pci_info)
+3 -8
View File
@@ -32,7 +32,6 @@ from nova import exception
from nova.i18n import _, _LE, _LI, _LW
from nova import objects
from nova.openstack.common import log as logging
from nova.pci import whitelist as pci_whitelist
from nova.virt.xenapi import pool_states
from nova.virt.xenapi import vm_utils
@@ -147,7 +146,6 @@ class HostState(object):
super(HostState, self).__init__()
self._session = session
self._stats = {}
self._pci_device_filter = pci_whitelist.get_pci_devices_filter()
self.update_status()
def _get_passthrough_devices(self):
@@ -155,10 +153,9 @@ class HostState(object):
We use a plugin to get the output of the lspci command runs on dom0.
From this list we will extract pci devices that are using the pciback
kernel driver. Then we compare this list to the pci whitelist to get
a new list of pci devices that can be used for pci passthrough.
kernel driver.
:returns: a list of pci devices available for pci passthrough.
:returns: a list of pci devices on the node
"""
def _compile_hex(pattern):
"""Return a compiled regular expression pattern into which we have
@@ -217,9 +214,7 @@ class HostState(object):
for dev_string_info in pci_list:
if "Driver:\tpciback" in dev_string_info:
new_dev = _parse_pci_device_string(dev_string_info)
if self._pci_device_filter.device_assignable(new_dev):
passthrough_devices.append(new_dev)
passthrough_devices.append(new_dev)
return passthrough_devices