Merge "Add numa_node to PCIDevice"
This commit is contained in:
commit
83178d91df
|
@ -0,0 +1,41 @@
|
|||
# Copyright 2014 Intel Corporation
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
#
|
||||
# See blueprint backportable-db-migrations-icehouse
|
||||
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
|
||||
|
||||
from sqlalchemy import MetaData, Table, Column, Integer
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData(bind=migrate_engine)
|
||||
|
||||
# Add a new column to store PCI device numa node
|
||||
pci_devices = Table('pci_devices', meta, autoload=True)
|
||||
shadow_pci_devices = Table('shadow_pci_devices', meta, autoload=True)
|
||||
|
||||
numa_node = Column('numa_node', Integer, default=None)
|
||||
pci_devices.create_column(numa_node)
|
||||
shadow_pci_devices.create_column(numa_node.copy())
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = MetaData(bind=migrate_engine)
|
||||
|
||||
# Remove the numa_node column
|
||||
pci_devices = Table('pci_devices', meta, autoload=True)
|
||||
shadow_pci_devices = Table('shadow_pci_devices', meta, autoload=True)
|
||||
|
||||
pci_devices.drop_column('numa_node')
|
||||
shadow_pci_devices.drop_column('numa_node')
|
|
@ -1413,6 +1413,9 @@ class PciDevice(BASE, NovaBase):
|
|||
extra_info = Column(Text)
|
||||
|
||||
instance_uuid = Column(String(36))
|
||||
|
||||
numa_node = Column(Integer, nullable=True)
|
||||
|
||||
instance = orm.relationship(Instance, backref="pci_devices",
|
||||
foreign_keys=instance_uuid,
|
||||
primaryjoin='and_('
|
||||
|
|
|
@ -71,7 +71,8 @@ class PciDevice(base.NovaPersistentObject, base.NovaObject,
|
|||
# Version 1.0: Initial version
|
||||
# Version 1.1: String attributes updated to support unicode
|
||||
# Version 1.2: added request_id field
|
||||
VERSION = '1.2'
|
||||
# Version 1.3: Added field to represent PCI device NUMA node
|
||||
VERSION = '1.3'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
|
@ -88,6 +89,7 @@ class PciDevice(base.NovaPersistentObject, base.NovaObject,
|
|||
'instance_uuid': fields.StringField(nullable=True),
|
||||
'request_id': fields.StringField(nullable=True),
|
||||
'extra_info': fields.DictOfStringsField(),
|
||||
'numa_node': fields.IntegerField(nullable=True),
|
||||
}
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
|
@ -188,6 +190,7 @@ class PciDeviceList(base.ObjectListBase, base.NovaObject):
|
|||
'1.0': '1.1',
|
||||
# NOTE(danms): PciDevice was at 1.1 before we added this
|
||||
'1.1': '1.2',
|
||||
'1.2': '1.3',
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
|
|
@ -29,6 +29,7 @@ fake_db_dev_1 = {
|
|||
'compute_node_id': 1,
|
||||
'address': '0000:04:10.0',
|
||||
'vendor_id': '8086',
|
||||
'numa_node': 0,
|
||||
'product_id': '1520',
|
||||
'dev_type': 'type-VF',
|
||||
'status': 'available',
|
||||
|
@ -48,6 +49,7 @@ fake_db_dev_2 = {
|
|||
'compute_node_id': 1,
|
||||
'address': '0000:04:10.1',
|
||||
'vendor_id': '8086',
|
||||
'numa_node': 1,
|
||||
'product_id': '1520',
|
||||
'dev_type': 'type-VF',
|
||||
'status': 'available',
|
||||
|
|
|
@ -7663,6 +7663,7 @@ class PciDeviceDBApiTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
|||
'address': '0000:0f:08.7',
|
||||
'vendor_id': '8086',
|
||||
'product_id': '1520',
|
||||
'numa_node': 1,
|
||||
'dev_type': 'type-VF',
|
||||
'dev_id': 'pci_0000:0f:08.7',
|
||||
'extra_info': None,
|
||||
|
@ -7675,6 +7676,7 @@ class PciDeviceDBApiTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
|||
'address': '0000:0f:03.7',
|
||||
'vendor_id': '8083',
|
||||
'product_id': '1523',
|
||||
'numa_node': 0,
|
||||
'dev_type': 'type-VF',
|
||||
'dev_id': 'pci_0000:0f:08.7',
|
||||
'extra_info': None,
|
||||
|
|
|
@ -561,6 +561,24 @@ class NovaMigrationsCheckers(test_migrations.WalkVersionsMixin):
|
|||
self.assertColumnNotExists(engine, 'compute_nodes', 'host')
|
||||
self.assertColumnNotExists(engine, 'shadow_compute_nodes', 'host')
|
||||
|
||||
def _check_269(self, engine, data):
|
||||
|
||||
self.assertColumnExists(engine, 'pci_devices', 'numa_node')
|
||||
self.assertColumnExists(engine, 'shadow_pci_devices', 'numa_node')
|
||||
pci_devices = oslodbutils.get_table(engine, 'pci_devices')
|
||||
shadow_pci_devices = oslodbutils.get_table(
|
||||
engine, 'shadow_pci_devices')
|
||||
self.assertIsInstance(pci_devices.c.numa_node.type,
|
||||
sqlalchemy.types.Integer)
|
||||
self.assertTrue(pci_devices.c.numa_node.nullable)
|
||||
self.assertIsInstance(shadow_pci_devices.c.numa_node.type,
|
||||
sqlalchemy.types.Integer)
|
||||
self.assertTrue(shadow_pci_devices.c.numa_node.nullable)
|
||||
|
||||
def _post_downgrade_269(self, engine):
|
||||
self.assertColumnNotExists(engine, 'pci_devices', 'numa_node')
|
||||
self.assertColumnNotExists(engine, 'shadow_pci_devices', 'numa_node')
|
||||
|
||||
|
||||
class TestNovaMigrationsSQLite(NovaMigrationsCheckers,
|
||||
test_base.DbTestCase):
|
||||
|
|
|
@ -606,6 +606,7 @@ class _TestInstanceObject(object):
|
|||
'compute_node_id': 1,
|
||||
'address': 'a1',
|
||||
'vendor_id': 'v1',
|
||||
'numa_node': 0,
|
||||
'product_id': 'p1',
|
||||
'dev_type': 't',
|
||||
'status': 'allocated',
|
||||
|
@ -623,6 +624,7 @@ class _TestInstanceObject(object):
|
|||
'compute_node_id': 1,
|
||||
'address': 'a',
|
||||
'vendor_id': 'v',
|
||||
'numa_node': 1,
|
||||
'product_id': 'p',
|
||||
'dev_type': 't',
|
||||
'status': 'allocated',
|
||||
|
|
|
@ -1160,8 +1160,8 @@ object_data = {
|
|||
'NUMACell': '1.2-cb9c3b08cc1c418d021492f788d04173',
|
||||
'NUMAPagesTopology': '1.0-97d93f70a68625b5f29ff63a40a4f612',
|
||||
'NUMATopology': '1.2-790f6bdff85bf6e5677f409f3a4f1c6a',
|
||||
'PciDevice': '1.2-29e35c3199f3b98ce66e5d1212612818',
|
||||
'PciDeviceList': '1.1-2896df4f5b06579e5f35adba5fcae9db',
|
||||
'PciDevice': '1.3-e059641df10e85d464672c5183a9473b',
|
||||
'PciDeviceList': '1.1-38cbe2d3c23b9e46f7a74b486abcad85',
|
||||
'PciDevicePool': '1.0-d6ed1abe611c9947345a44155abe6f11',
|
||||
'PciDevicePoolList': '1.0-d31e08e0ff620a4df7cc2014b6c50da8',
|
||||
'Quotas': '1.2-36098cf2143e6535873c3fa3d6fe56f7',
|
||||
|
|
|
@ -26,6 +26,7 @@ dev_dict = {
|
|||
'address': 'a',
|
||||
'product_id': 'p',
|
||||
'vendor_id': 'v',
|
||||
'numa_node': 0,
|
||||
'status': 'available'}
|
||||
|
||||
|
||||
|
@ -39,6 +40,7 @@ fake_db_dev = {
|
|||
'address': 'a',
|
||||
'vendor_id': 'v',
|
||||
'product_id': 'p',
|
||||
'numa_node': 0,
|
||||
'dev_type': 't',
|
||||
'status': 'available',
|
||||
'dev_id': 'i',
|
||||
|
@ -59,6 +61,7 @@ fake_db_dev_1 = {
|
|||
'address': 'a1',
|
||||
'vendor_id': 'v1',
|
||||
'product_id': 'p1',
|
||||
'numa_node': 1,
|
||||
'dev_type': 't',
|
||||
'status': 'available',
|
||||
'dev_id': 'i',
|
||||
|
@ -87,7 +90,7 @@ class _TestPciDeviceObject(object):
|
|||
self.assertEqual(self.pci_device.product_id, 'p')
|
||||
self.assertEqual(self.pci_device.obj_what_changed(),
|
||||
set(['compute_node_id', 'product_id', 'vendor_id',
|
||||
'status', 'address', 'extra_info']))
|
||||
'numa_node', 'status', 'address', 'extra_info']))
|
||||
|
||||
def test_pci_device_extra_info(self):
|
||||
self.dev_dict = copy.copy(dev_dict)
|
||||
|
@ -99,7 +102,8 @@ class _TestPciDeviceObject(object):
|
|||
self.assertEqual(set(extra_value.keys()), set(('k1', 'k2')))
|
||||
self.assertEqual(self.pci_device.obj_what_changed(),
|
||||
set(['compute_node_id', 'address', 'product_id',
|
||||
'vendor_id', 'status', 'extra_info']))
|
||||
'vendor_id', 'numa_node', 'status',
|
||||
'extra_info']))
|
||||
|
||||
def test_update_device(self):
|
||||
self.pci_device = pci_device.PciDevice.create(dev_dict)
|
||||
|
@ -199,6 +203,15 @@ class _TestPciDeviceObject(object):
|
|||
self.pci_device.save(ctxt)
|
||||
self.assertEqual(self.called, False)
|
||||
|
||||
def test_update_numa_node(self):
|
||||
self.pci_device = pci_device.PciDevice.create(dev_dict)
|
||||
self.assertEqual(0, self.pci_device.numa_node)
|
||||
|
||||
self.dev_dict = copy.copy(dev_dict)
|
||||
self.dev_dict['numa_node'] = '1'
|
||||
self.pci_device = pci_device.PciDevice.create(self.dev_dict)
|
||||
self.assertEqual(1, self.pci_device.numa_node)
|
||||
|
||||
|
||||
class TestPciDeviceObject(test_objects._LocalTest,
|
||||
_TestPciDeviceObject):
|
||||
|
|
|
@ -30,6 +30,7 @@ dev_dict = {
|
|||
'address': 'a',
|
||||
'vendor_id': 'v',
|
||||
'product_id': 'p',
|
||||
'numa_node': 1,
|
||||
'dev_type': 't',
|
||||
'status': 'available',
|
||||
'dev_id': 'i',
|
||||
|
|
|
@ -52,6 +52,7 @@ fake_db_dev = {
|
|||
'address': '0000:00:00.1',
|
||||
'vendor_id': 'v',
|
||||
'product_id': 'p',
|
||||
'numa_node': 1,
|
||||
'dev_type': 't',
|
||||
'status': 'available',
|
||||
'dev_id': 'i',
|
||||
|
|
|
@ -1974,6 +1974,7 @@ class LibvirtConfigNodeDevicePciCapTest(LibvirtConfigBaseTest):
|
|||
self.assertEqual(obj.product_id, 0x10bd)
|
||||
self.assertEqual(obj.vendor, "Intel Inc.")
|
||||
self.assertEqual(obj.vendor_id, 0x8086)
|
||||
self.assertIsNone(obj.numa_node)
|
||||
self.assertIsInstance(obj.fun_capability[0],
|
||||
config.LibvirtConfigNodeDevicePciSubFunctionCap)
|
||||
|
||||
|
@ -1991,6 +1992,7 @@ class LibvirtConfigNodeDevicePciCapTest(LibvirtConfigBaseTest):
|
|||
<function>5</function>
|
||||
<product id="0x10bd">Intel 10 Gigabit Ethernet</product>
|
||||
<vendor id="0x8086">Intel Inc.</vendor>
|
||||
<numa node='0'/>
|
||||
<capability type="virt_functions">
|
||||
<address domain="0000" bus="0x0a" slot="0x1" function="0x1"/>
|
||||
<address domain="0001" bus="0x0a" slot="0x02" function="0x03"/>
|
||||
|
@ -2010,6 +2012,7 @@ class LibvirtConfigNodeDevicePciCapTest(LibvirtConfigBaseTest):
|
|||
self.assertEqual(obj.product_id, 0x10bd)
|
||||
self.assertEqual(obj.vendor, "Intel Inc.")
|
||||
self.assertEqual(obj.vendor_id, 0x8086)
|
||||
self.assertEqual(0, obj.numa_node)
|
||||
self.assertIsInstance(obj.fun_capability[0],
|
||||
config.LibvirtConfigNodeDevicePciSubFunctionCap)
|
||||
|
||||
|
|
|
@ -140,7 +140,8 @@ _fake_NodeDevXml = \
|
|||
<bus>4</bus>
|
||||
<slot>16</slot>
|
||||
<function>7</function>
|
||||
<product id='0x1520'>I350 Ethernet Controller Virtual Function</product>
|
||||
<product id='0x1520'>I350 Ethernet Controller Virtual Function
|
||||
</product>
|
||||
<vendor id='0x8086'>Intel Corporation</vendor>
|
||||
<capability type='phys_function'>
|
||||
<address domain='0x0000' bus='0x04' slot='0x00' function='0x3'/>
|
||||
|
@ -148,6 +149,29 @@ _fake_NodeDevXml = \
|
|||
<capability type='virt_functions'>
|
||||
</capability>
|
||||
</capability>
|
||||
</device>""",
|
||||
"pci_0000_04_11_7": """
|
||||
<device>
|
||||
<name>pci_0000_04_11_7</name>
|
||||
<parent>pci_0000_00_01_1</parent>
|
||||
<driver>
|
||||
<name>igbvf</name>
|
||||
</driver>
|
||||
<capability type='pci'>
|
||||
<domain>0</domain>
|
||||
<bus>4</bus>
|
||||
<slot>17</slot>
|
||||
<function>7</function>
|
||||
<product id='0x1520'>I350 Ethernet Controller Virtual Function
|
||||
</product>
|
||||
<vendor id='0x8086'>Intel Corporation</vendor>
|
||||
<numa node='0'/>
|
||||
<capability type='phys_function'>
|
||||
<address domain='0x0000' bus='0x04' slot='0x00' function='0x3'/>
|
||||
</capability>
|
||||
<capability type='virt_functions'>
|
||||
</capability>
|
||||
</capability>
|
||||
</device>"""}
|
||||
|
||||
|
||||
|
@ -8838,24 +8862,38 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
"dev_id": "pci_0000_04_00_3",
|
||||
"address": "0000:04:00.3",
|
||||
"product_id": '1521',
|
||||
"numa_node": None,
|
||||
"vendor_id": '8086',
|
||||
"label": 'label_8086_1521',
|
||||
"dev_type": 'type-PF',
|
||||
}
|
||||
|
||||
self.assertEqual(actualvf, expect_vf)
|
||||
self.assertEqual(expect_vf, actualvf)
|
||||
actualvf = conn._get_pcidev_info("pci_0000_04_10_7")
|
||||
expect_vf = {
|
||||
"dev_id": "pci_0000_04_10_7",
|
||||
"address": "0000:04:10.7",
|
||||
"product_id": '1520',
|
||||
"numa_node": None,
|
||||
"vendor_id": '8086',
|
||||
"label": 'label_8086_1520',
|
||||
"dev_type": 'type-VF',
|
||||
"phys_function": '0000:04:00.3',
|
||||
}
|
||||
self.assertEqual(expect_vf, actualvf)
|
||||
actualvf = conn._get_pcidev_info("pci_0000_04_11_7")
|
||||
expect_vf = {
|
||||
"dev_id": "pci_0000_04_11_7",
|
||||
"address": "0000:04:11.7",
|
||||
"product_id": '1520',
|
||||
"vendor_id": '8086',
|
||||
"numa_node": 0,
|
||||
"label": 'label_8086_1520',
|
||||
"dev_type": 'type-VF',
|
||||
"phys_function": '0000:04:00.3',
|
||||
}
|
||||
|
||||
self.assertEqual(actualvf, expect_vf)
|
||||
self.assertEqual(expect_vf, actualvf)
|
||||
|
||||
def test_list_devices_not_supported(self):
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
|
@ -8889,9 +8927,11 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
def test_get_pci_passthrough_devices(self):
|
||||
|
||||
def fakelistDevices(caps, fakeargs=0):
|
||||
return ['pci_0000_04_00_3', 'pci_0000_04_10_7']
|
||||
return ['pci_0000_04_00_3', 'pci_0000_04_10_7',
|
||||
'pci_0000_04_11_7']
|
||||
|
||||
self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
|
||||
|
||||
libvirt_driver.LibvirtDriver._conn.listDevices = fakelistDevices
|
||||
|
||||
def fake_nodeDeviceLookupByName(name):
|
||||
|
@ -8909,13 +8949,24 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
"product_id": '1521',
|
||||
"vendor_id": '8086',
|
||||
"dev_type": 'type-PF',
|
||||
"phys_function": None},
|
||||
"phys_function": None,
|
||||
"numa_node": None},
|
||||
{
|
||||
"dev_id": "pci_0000_04_10_7",
|
||||
"domain": 0,
|
||||
"address": "0000:04:10.7",
|
||||
"product_id": '1520',
|
||||
"vendor_id": '8086',
|
||||
"numa_node": None,
|
||||
"dev_type": 'type-VF',
|
||||
"phys_function": [('0x0000', '0x04', '0x00', '0x3')]},
|
||||
{
|
||||
"dev_id": "pci_0000_04_11_7",
|
||||
"domain": 0,
|
||||
"address": "0000:04:11.7",
|
||||
"product_id": '1520',
|
||||
"vendor_id": '8086',
|
||||
"numa_node": 0,
|
||||
"dev_type": 'type-VF',
|
||||
"phys_function": [('0x0000', '0x04', '0x00', '0x3')],
|
||||
}
|
||||
|
@ -8925,7 +8976,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
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])
|
||||
self.assertEqual(expectvfs[dev][key], actualvfs[dev][key])
|
||||
|
||||
def _fake_caps_numa_topology(self):
|
||||
topology = vconfig.LibvirtConfigCapsNUMATopology()
|
||||
|
|
|
@ -2004,6 +2004,7 @@ class LibvirtConfigNodeDevicePciCap(LibvirtConfigObject):
|
|||
self.product_id = None
|
||||
self.vendor = None
|
||||
self.vendor_id = None
|
||||
self.numa_node = None
|
||||
self.fun_capability = list()
|
||||
|
||||
def parse_dom(self, xmldoc):
|
||||
|
@ -2024,6 +2025,8 @@ class LibvirtConfigNodeDevicePciCap(LibvirtConfigObject):
|
|||
elif c.tag == "vendor":
|
||||
self.vendor = c.text
|
||||
self.vendor_id = int(c.get('id'), 16)
|
||||
elif c.tag == "numa":
|
||||
self.numa_node = int(c.get('node'))
|
||||
elif c.tag == "capability" and c.get('type') in \
|
||||
('virt_functions', 'phys_function'):
|
||||
funcap = LibvirtConfigNodeDevicePciSubFunctionCap()
|
||||
|
|
|
@ -4719,6 +4719,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
"vendor_id": "%04x" % cfgdev.pci_capability.vendor_id,
|
||||
}
|
||||
|
||||
device["numa_node"] = cfgdev.pci_capability.numa_node
|
||||
|
||||
# requirement by DataBase Model
|
||||
device['label'] = 'label_%(vendor_id)s_%(product_id)s' % device
|
||||
device.update(_get_device_type(cfgdev))
|
||||
|
|
Loading…
Reference in New Issue