Record requester in the InstancePCIRequest

An InstancePCIRequest might represent the VF device request of a
neutron port that has bandwidth request as well. In this case nova
needs to correlate the pci request with the port's resource request to
make sure the bandwidth and the VF are allocated from the same PF.

This patch introduces the new ``requester_id`` field to the
InstancePCIRequest ovo and stores the port_id in that field if the
pci request is created from a neutron port.

The value of the ``requester_id`` field will be used in a subsequent
patch to match it against the existing RequestGroup.requester_id.

Change-Id: I73786b7900957faca72d6ddfd01023a4b186e14d
blueprint: bandwidth-resource-provider
This commit is contained in:
Balazs Gibizer 2018-12-14 15:56:14 +01:00 committed by Matt Riedemann
parent 859a0ac118
commit fc4010176a
8 changed files with 47 additions and 7 deletions

View File

@ -2048,6 +2048,7 @@ class API(base_api.NetworkAPI):
tunneled_ = False
vnic_type = network_model.VNIC_TYPE_NORMAL
pci_request_id = None
requester_id = None
if request_net.port_id:
result = self._get_port_vnic_info(
@ -2057,6 +2058,9 @@ class API(base_api.NetworkAPI):
context, neutron, network_id)
if resource_request:
# InstancePCIRequest.requester_id is semantically linked
# to a port with a resource_request.
requester_id = request_net.port_id
# NOTE(gibi): explicitly orphan the RequestGroup by setting
# context=None as we never intended to save it to the DB.
resource_requests.append(
@ -2101,7 +2105,8 @@ class API(base_api.NetworkAPI):
request = objects.InstancePCIRequest(
count=1,
spec=[spec],
request_id=uuidutils.generate_uuid())
request_id=uuidutils.generate_uuid(),
requester_id=requester_id)
pci_requests.requests.append(request)
pci_request_id = request.request_id

View File

@ -25,7 +25,8 @@ class InstancePCIRequest(base.NovaObject,
# Version 1.0: Initial version
# Version 1.1: Add request_id
# Version 1.2: Add PCI NUMA affinity policy
VERSION = '1.2'
# Version 1.3: Add requester_id
VERSION = '1.3'
fields = {
'count': fields.IntegerField(),
@ -35,6 +36,7 @@ class InstancePCIRequest(base.NovaObject,
# on major version bump
'is_new': fields.BooleanField(default=False),
'request_id': fields.UUIDField(nullable=True),
'requester_id': fields.StringField(nullable=True),
'numa_policy': fields.PCINUMAAffinityPolicyField(nullable=True),
}
@ -45,6 +47,8 @@ class InstancePCIRequest(base.NovaObject,
super(InstancePCIRequest, self).obj_make_compatible(primitive,
target_version)
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 3) and 'requester_id' in primitive:
del primitive['requester_id']
if target_version < (1, 2) and 'numa_policy' in primitive:
del primitive['numa_policy']
if target_version < (1, 1) and 'request_id' in primitive:
@ -86,7 +90,8 @@ class InstancePCIRequests(base.NovaObject,
request_obj = InstancePCIRequest(
count=request['count'], spec=request['spec'],
alias_name=request['alias_name'], is_new=False,
request_id=request['request_id'])
request_id=request['request_id'],
requester_id=request.get('requester_id'))
request_obj.obj_reset_changes()
self.requests.append(request_obj)
self.obj_reset_changes()
@ -137,7 +142,8 @@ class InstancePCIRequests(base.NovaObject,
'spec': x.spec,
'alias_name': x.alias_name,
'is_new': x.is_new,
'request_id': x.request_id} for x in self.requests]
'request_id': x.request_id,
'requester_id': x.requester_id} for x in self.requests]
return jsonutils.dumps(blob)
@classmethod

View File

@ -159,6 +159,10 @@ def _translate_alias_to_requests(alias_spec):
count = int(count)
numa_policy, spec = pci_aliases[name]
# NOTE(gibi): InstancePCIRequest has a requester_id field that could
# be filled with the flavor.flavorid but currently there is no special
# handling for InstancePCIRequests created from the flavor. So it is
# left empty.
pci_requests.append(objects.InstancePCIRequest(
count=count,
spec=spec,

View File

@ -5463,6 +5463,11 @@ class TestNeutronv2WithMock(_TestNeutronv2Common):
else:
self.assertNotIn(pci_request.PCI_TRUSTED_TAG, spec)
# Only the port with a resource_request will have pci_req.requester_id.
self.assertEqual(
[None, None, None, None, uuids.trusted_port],
[pci_req.requester_id for pci_req in pci_requests.requests])
self.assertItemsEqual(
['physnet1', 'physnet2', 'physnet3', 'physnet4'],
network_metadata.physnets)

View File

@ -572,7 +572,8 @@ class _TestInstanceObject(object):
@mock.patch('nova.db.api.instance_extra_update_by_uuid')
def test_save_object_pci_requests(self, mock_instance_extra_update):
expected_json = ('[{"count": 1, "alias_name": null, "is_new": false,'
'"request_id": null, "spec": [{"vendor_id": "8086",'
'"request_id": null, "requester_id": null,'
'"spec": [{"vendor_id": "8086", '
'"product_id": "1502"}]}]')
inst = objects.Instance()

View File

@ -38,7 +38,8 @@ fake_pci_requests = [
'device_id': '07B5'}],
'alias_name': 'alias_2',
'is_new': True,
'request_id': FAKE_REQUEST_UUID},
'request_id': FAKE_REQUEST_UUID,
'requester_id': uuids.requester_id},
]
fake_legacy_pci_requests = [
@ -117,6 +118,8 @@ class _TestInstancePCIRequests(object):
self.assertEqual(FAKE_UUID, req.instance_uuid)
self.assertEqual(2, len(req.requests))
self.assertEqual('alias_1', req.requests[0].alias_name)
self.assertIsNone(None, req.requests[0].requester_id)
self.assertEqual(uuids.requester_id, req.requests[1].requester_id)
def test_from_request_spec_instance_props(self):
requests = objects.InstancePCIRequests(
@ -159,6 +162,20 @@ class _TestInstancePCIRequests(object):
self.assertNotIn('request_id', primitive['nova_object.data'])
def test_obj_make_compatible_pre_1_3(self):
topo_obj = objects.InstancePCIRequest(
count=1,
spec=[{'vendor_id': '8086', 'device_id': '1502'}],
request_id=uuids.pci_request_id,
requester_id=uuids.requester_id,
numa_policy=fields.PCINUMAAffinityPolicy.PREFERRED)
versions = ovo_base.obj_tree_get_versions('InstancePCIRequest')
primitive = topo_obj.obj_to_primitive(target_version='1.2',
version_manifest=versions)
self.assertNotIn('requester_id', primitive['nova_object.data'])
self.assertIn('numa_policy', primitive['nova_object.data'])
class TestInstancePCIRequests(test_objects._LocalTest,
_TestInstancePCIRequests):

View File

@ -1111,7 +1111,7 @@ object_data = {
'InstanceMappingList': '1.2-ee638619aa3d8a82a59c0c83bfa64d78',
'InstanceNUMACell': '1.4-7c1eb9a198dee076b4de0840e45f4f55',
'InstanceNUMATopology': '1.3-ec0030cb0402a49c96da7051c037082a',
'InstancePCIRequest': '1.2-6344dd8bd1bf873e7325c07afe47f774',
'InstancePCIRequest': '1.3-f6d324f1c337fad4f34892ed5f484c9a',
'InstancePCIRequests': '1.1-65e38083177726d806684cb1cc0136d2',
'KeyPair': '1.4-1244e8d1b103cc69d038ed78ab3a8cc6',
'KeyPairList': '1.3-94aad3ac5c938eef4b5e83da0212f506',

View File

@ -208,12 +208,14 @@ class AliasTestCase(test.NoDBTestCase):
self.flags(alias=[_fake_alias1, _fake_alias3], group='pci')
expect_request = [
{'count': 3,
'requester_id': None,
'spec': [{'vendor_id': '8086', 'product_id': '4443',
'dev_type': 'type-PCI',
'capability_type': 'pci'}],
'alias_name': 'QuicAssist'},
{'count': 1,
'requester_id': None,
'spec': [{'vendor_id': '8086', 'product_id': '1111',
'dev_type': "type-PF",
'capability_type': 'pci'}],