objects: Add 'VDPA' to 'PciDeviceType'

Add a new PCI device type and update the parent objects to reflect this.
The code for handling the '[pci] alias' config option is updated to
prevent users specifying this in an alias.

Blueprint: libvirt-vdpa-support
Change-Id: I7c779ce7ee0648833758a75164e0bc0b54fe9a71
This commit is contained in:
Sean Mooney 2021-02-24 20:25:50 +00:00 committed by Stephen Finucane
parent 658f2327bc
commit 7313832d58
6 changed files with 47 additions and 4 deletions

View File

@ -757,8 +757,12 @@ class PciDeviceType(BaseNovaEnum):
STANDARD = "type-PCI"
SRIOV_PF = "type-PF"
SRIOV_VF = "type-VF"
# NOTE(sean-k-mooney): The DB field is Column(String(8), nullable=False)
# type-vdpa is 9 long...and as Jay notes above the prefix is silly so
# for the new vdpa value we drop the prefix to avoid a DB migration
VDPA = "vdpa"
ALL = (STANDARD, SRIOV_PF, SRIOV_VF)
ALL = (STANDARD, SRIOV_PF, SRIOV_VF, VDPA)
class PCINUMAAffinityPolicy(BaseNovaEnum):

View File

@ -98,7 +98,8 @@ class PciDevice(base.NovaPersistentObject, base.NovaObject):
# Version 1.4: Added parent_addr field
# Version 1.5: Added 2 new device statuses: UNCLAIMABLE and UNAVAILABLE
# Version 1.6: Added uuid field
VERSION = '1.6'
# Version 1.7: Added 'vdpa' to 'dev_type' field
VERSION = '1.7'
fields = {
'id': fields.IntegerField(),
@ -140,6 +141,13 @@ class PciDevice(base.NovaPersistentObject, base.NovaObject):
status, target_version))
if target_version < (1, 6) and 'uuid' in primitive:
del primitive['uuid']
if target_version < (1, 7) and 'dev_type' in primitive:
dev_type = primitive['dev_type']
if dev_type == fields.PciDeviceType.VDPA:
raise exception.ObjectActionError(
action='obj_make_compatible',
reason='dev_type=%s not supported in version %s' % (
dev_type, target_version))
def update_device(self, dev_dict):
"""Sync the content from device dictionary to device object.

View File

@ -86,7 +86,13 @@ _ALIAS_SCHEMA = {
},
"device_type": {
"type": "string",
"enum": list(obj_fields.PciDeviceType.ALL),
# NOTE(sean-k-mooney): vDPA devices cannot currently be used with
# alias-based PCI passthrough so we exclude it here
"enum": [
obj_fields.PciDeviceType.STANDARD,
obj_fields.PciDeviceType.SRIOV_PF,
obj_fields.PciDeviceType.SRIOV_VF,
],
},
"numa_policy": {
"type": "string",

View File

@ -1115,7 +1115,7 @@ object_data = {
'NetworkRequestList': '1.1-15ecf022a68ddbb8c2a6739cfc9f8f5e',
'NicDiagnostics': '1.0-895e9ad50e0f56d5258585e3e066aea5',
'PCIDeviceBus': '1.0-2b891cb77e42961044689f3dc2718995',
'PciDevice': '1.6-25ca0542a22bc25386a72c0065a79c01',
'PciDevice': '1.7-680e4c590aae154958ccf9677774413b',
'PciDeviceList': '1.3-52ff14355491c8c580bdc0ba34c26210',
'PciDevicePool': '1.1-3f5ddc3ff7bfa14da7f6c7e9904cc000',
'PciDevicePoolList': '1.1-15ecf022a68ddbb8c2a6739cfc9f8f5e',

View File

@ -224,6 +224,24 @@ class _TestPciDeviceObject(object):
self.assertIsNotNone(dev.uuid)
self.assertEqual(1, mock_create_uuid.call_count)
def test_dev_type_vdpa_1_6_fails(self):
ctxt = context.get_admin_context()
fake_dev = copy.deepcopy(fake_db_dev)
fake_dev['dev_type'] = fields.PciDeviceType.VDPA
dev = pci_device.PciDevice._from_db_object(
ctxt, pci_device.PciDevice(), fake_dev)
self.assertRaises(exception.ObjectActionError,
dev.obj_to_primitive, '1.6')
def test_dev_type_vdpa_1_6(self):
ctxt = context.get_admin_context()
fake_dev = copy.deepcopy(fake_db_dev)
fake_dev['dev_type'] = fields.PciDeviceType.STANDARD
dev = pci_device.PciDevice._from_db_object(
ctxt, pci_device.PciDevice(), fake_dev)
dev.obj_make_compatible(dev.obj_to_primitive(), '1.6')
self.assertEqual(dev.dev_type, fake_dev['dev_type'])
def test_save_empty_parent_addr(self):
ctxt = context.get_admin_context()
dev = pci_device.PciDevice._from_db_object(

View File

@ -128,6 +128,13 @@ class PciRequestTestCase(test.NoDBTestCase):
})
self._test_get_alias_from_config_invalid(fake_alias)
def test_get_alias_from_config_device_type_vdpa(self):
fake_alias = jsonutils.dumps({
"name": "xxx",
"device_type": "vdpa",
})
self._test_get_alias_from_config_invalid(fake_alias)
def test_get_alias_from_config_invalid_product_id(self):
fake_alias = jsonutils.dumps({
"name": "xxx",