Skip to content

Commit 58be0ca

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Generate request_id for Flavor based InstancePCIRequest"
2 parents 90e2a5e + ccab6fe commit 58be0ca

File tree

9 files changed

+285
-102
lines changed

9 files changed

+285
-102
lines changed

nova/network/neutron.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
from nova.network import model as network_model
4444
from nova import objects
4545
from nova.objects import fields as obj_fields
46-
from nova.pci import manager as pci_manager
4746
from nova.pci import request as pci_request
4847
from nova.pci import utils as pci_utils
4948
from nova.pci import whitelist as pci_whitelist
@@ -1631,8 +1630,7 @@ def _populate_neutron_binding_profile(self, instance, pci_request_id,
16311630
pci_request_id cannot be found on the instance.
16321631
"""
16331632
if pci_request_id:
1634-
pci_devices = pci_manager.get_instance_pci_devs(
1635-
instance, pci_request_id)
1633+
pci_devices = instance.get_pci_devices(request_id=pci_request_id)
16361634
if not pci_devices:
16371635
# The pci_request_id likely won't mean much except for tracing
16381636
# through the logs since it is generated per request.
@@ -1662,8 +1660,7 @@ def _populate_pci_mac_address(instance, pci_request_id, port_req_body):
16621660
Currently this is done only for PF passthrough.
16631661
"""
16641662
if pci_request_id is not None:
1665-
pci_devs = pci_manager.get_instance_pci_devs(
1666-
instance, pci_request_id)
1663+
pci_devs = instance.get_pci_devices(request_id=pci_request_id)
16671664
if len(pci_devs) != 1:
16681665
# NOTE(ndipanov): We shouldn't ever get here since
16691666
# InstancePCIRequest instances built from network requests

nova/objects/instance.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# under the License.
1414

1515
import contextlib
16+
import typing as ty
1617

1718
from oslo_config import cfg
1819
from oslo_db import exception as db_exc
@@ -1226,6 +1227,46 @@ def remove_pci_device_and_request(self, pci_device):
12261227
pci_req for pci_req in self.pci_requests.requests
12271228
if pci_req.request_id != pci_device.request_id]
12281229

1230+
def get_pci_devices(
1231+
self,
1232+
source: ty.Optional[int] = None,
1233+
request_id: ty.Optional[str] = None,
1234+
) -> ty.List["objects.PciDevice"]:
1235+
"""Return the PCI devices allocated to the instance
1236+
1237+
:param source: Filter by source. It can be
1238+
InstancePCIRequest.FLAVOR_ALIAS or InstancePCIRequest.NEUTRON_PORT
1239+
or None. None means returns devices from both type of requests.
1240+
:param request_id: Filter by PciDevice.request_id. None means do not
1241+
filter by request_id.
1242+
:return: a list of matching PciDevice objects
1243+
"""
1244+
if not self.pci_devices:
1245+
# return early to avoid an extra lazy load on self.pci_requests
1246+
# if there are no devices allocated to be filtered
1247+
return []
1248+
else:
1249+
devs = self.pci_devices.objects
1250+
1251+
if request_id is not None:
1252+
devs = [dev for dev in devs if dev.request_id == request_id]
1253+
1254+
if source is not None:
1255+
# NOTE(gibi): this happens to work for the old requests when the
1256+
# request has request_id None and therefore the device allocated
1257+
# due to that request has request_id None too, so they will be
1258+
# mapped via the None key.
1259+
req_id_to_req = {
1260+
req.request_id: req for req in self.pci_requests.requests
1261+
}
1262+
devs = [
1263+
dev
1264+
for dev in devs
1265+
if (req_id_to_req[dev.request_id].source == source)
1266+
]
1267+
1268+
return devs
1269+
12291270

12301271
def _make_instance_list(context, inst_list, db_inst_list, expected_attrs):
12311272
get_fault = expected_attrs and 'fault' in expected_attrs

nova/pci/manager.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -480,24 +480,3 @@ def clean_usage(
480480
devs = self.allocations.pop(uuid, [])
481481
for dev in devs:
482482
self._free_device(dev)
483-
484-
485-
def get_instance_pci_devs(
486-
inst: 'objects.Instance', request_id: str = None,
487-
) -> ty.List['objects.PciDevice']:
488-
"""Get the devices allocated to one or all requests for an instance.
489-
490-
- For generic PCI request, the request id is None.
491-
- For sr-iov networking, the request id is a valid uuid
492-
- There are a couple of cases where all the PCI devices allocated to an
493-
instance need to be returned. Refer to libvirt driver that handles
494-
soft_reboot and hard_boot of 'xen' instances.
495-
"""
496-
pci_devices = inst.pci_devices
497-
if pci_devices is None:
498-
return []
499-
500-
return [
501-
device for device in pci_devices if
502-
device.request_id == request_id or request_id == 'all'
503-
]

nova/pci/request.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import jsonschema
4444
from oslo_log import log as logging
4545
from oslo_serialization import jsonutils
46+
from oslo_utils import uuidutils
4647

4748
import nova.conf
4849
from nova import context as ctx
@@ -183,7 +184,9 @@ def _translate_alias_to_requests(
183184
count=int(count),
184185
spec=spec,
185186
alias_name=name,
186-
numa_policy=policy))
187+
numa_policy=policy,
188+
request_id=uuidutils.generate_uuid(),
189+
))
187190
return pci_requests
188191

189192

nova/tests/unit/network/test_neutron.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
from nova.objects import fields as obj_fields
4343
from nova.objects import network_request as net_req_obj
4444
from nova.objects import virtual_interface as obj_vif
45-
from nova.pci import manager as pci_manager
4645
from nova.pci import request as pci_request
4746
from nova.pci import utils as pci_utils
4847
from nova.pci import whitelist as pci_whitelist
@@ -7738,11 +7737,11 @@ def test_populate_neutron_extension_values_binding(self, mock_get_client):
77387737
'vf_num': 1,
77397738
}))
77407739
@mock.patch.object(pci_whitelist.Whitelist, 'get_devspec')
7741-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
7740+
@mock.patch('nova.objects.Instance.get_pci_devices')
77427741
def test_populate_neutron_extension_values_binding_sriov(
77437742
self, mock_get_instance_pci_devs, mock_get_pci_device_devspec):
77447743
host_id = 'my_host_id'
7745-
instance = {'host': host_id}
7744+
instance = objects.Instance(host=host_id)
77467745
port_req_body = {'port': {}}
77477746
pci_req_id = 'my_req_id'
77487747
pci_dev = {'vendor_id': '1377',
@@ -7783,11 +7782,11 @@ def test_populate_neutron_extension_values_binding_sriov(
77837782
})
77847783
)
77857784
@mock.patch.object(pci_whitelist.Whitelist, 'get_devspec')
7786-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
7785+
@mock.patch('nova.objects.Instance.get_pci_devices')
77877786
def test_populate_neutron_extension_values_binding_sriov_card_serial(
77887787
self, mock_get_instance_pci_devs, mock_get_pci_device_devspec):
77897788
host_id = 'my_host_id'
7790-
instance = {'host': host_id}
7789+
instance = objects.Instance(host=host_id)
77917790
port_req_body = {'port': {}}
77927791
pci_req_id = 'my_req_id'
77937792
pci_dev = {'vendor_id': 'a2d6',
@@ -7867,11 +7866,11 @@ def test_populate_neutron_extension_values_with_arq(self,
78677866
})
78687867
)
78697868
@mock.patch.object(pci_whitelist.Whitelist, 'get_devspec')
7870-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
7869+
@mock.patch('nova.objects.Instance.get_pci_devices')
78717870
def test_populate_neutron_extension_values_binding_sriov_with_cap(
78727871
self, mock_get_instance_pci_devs, mock_get_pci_device_devspec):
78737872
host_id = 'my_host_id'
7874-
instance = {'host': host_id}
7873+
instance = objects.Instance(host=host_id)
78757874
port_req_body = {'port': {
78767875
constants.BINDING_PROFILE: {
78777876
'capabilities': ['switchdev']}}}
@@ -7907,12 +7906,12 @@ def test_populate_neutron_extension_values_binding_sriov_with_cap(
79077906
constants.BINDING_PROFILE])
79087907

79097908
@mock.patch.object(pci_whitelist.Whitelist, 'get_devspec')
7910-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
7909+
@mock.patch('nova.objects.Instance.get_pci_devices')
79117910
def test_populate_neutron_extension_values_binding_sriov_pf(
79127911
self, mock_get_instance_pci_devs, mock_get_devspec
79137912
):
79147913
host_id = 'my_host_id'
7915-
instance = {'host': host_id}
7914+
instance = objects.Instance(host=host_id)
79167915
port_req_body = {'port': {}}
79177916

79187917
pci_dev = objects.PciDevice(
@@ -8041,11 +8040,11 @@ def test__get_pci_device_profile_pf(self, mock_get_pci_device_devspec):
80418040
)
80428041

80438042
@mock.patch.object(pci_whitelist.Whitelist, 'get_devspec')
8044-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
8043+
@mock.patch('nova.objects.Instance.get_pci_devices')
80458044
def test_populate_neutron_extension_values_binding_sriov_fail(
80468045
self, mock_get_instance_pci_devs, mock_get_pci_device_devspec):
80478046
host_id = 'my_host_id'
8048-
instance = {'host': host_id}
8047+
instance = objects.Instance(host=host_id)
80498048
port_req_body = {'port': {}}
80508049
pci_req_id = 'my_req_id'
80518050
pci_objs = [objects.PciDevice(vendor_id='1377',
@@ -8062,7 +8061,7 @@ def test_populate_neutron_extension_values_binding_sriov_fail(
80628061
self.api._populate_neutron_binding_profile,
80638062
instance, pci_req_id, port_req_body, None)
80648063

8065-
@mock.patch.object(pci_manager, 'get_instance_pci_devs', return_value=[])
8064+
@mock.patch('nova.objects.Instance.get_pci_devices', return_value=[])
80668065
def test_populate_neutron_binding_profile_pci_dev_not_found(
80678066
self, mock_get_instance_pci_devs):
80688067
api = neutronapi.API()
@@ -8073,7 +8072,7 @@ def test_populate_neutron_binding_profile_pci_dev_not_found(
80738072
api._populate_neutron_binding_profile,
80748073
instance, pci_req_id, port_req_body, None)
80758074
mock_get_instance_pci_devs.assert_called_once_with(
8076-
instance, pci_req_id)
8075+
request_id=pci_req_id)
80778076

80788077
@mock.patch.object(
80798078
pci_utils, 'is_physical_function',
@@ -8089,7 +8088,7 @@ def test_populate_neutron_binding_profile_pci_dev_not_found(
80898088
new=mock.MagicMock(side_effect=(lambda vf_a: {
80908089
'0000:0a:00.0': '52:54:00:1e:59:c6'}.get(vf_a)))
80918090
)
8092-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
8091+
@mock.patch('nova.objects.Instance.get_pci_devices')
80938092
def test_pci_parse_whitelist_called_once(
80948093
self, mock_get_instance_pci_devs
80958094
):
@@ -8108,7 +8107,7 @@ def test_pci_parse_whitelist_called_once(
81088107
# after the 'device_spec' is set in this test case.
81098108
api = neutronapi.API()
81108109
host_id = 'my_host_id'
8111-
instance = {'host': host_id}
8110+
instance = objects.Instance(host=host_id)
81128111
pci_req_id = 'my_req_id'
81138112
port_req_body = {'port': {}}
81148113
pci_dev = {'vendor_id': '1377',
@@ -8144,7 +8143,7 @@ def _populate_pci_mac_address_fakes(self):
81448143
vf.update_device(pci_dev)
81458144
return instance, pf, vf
81468145

8147-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
8146+
@mock.patch('nova.objects.Instance.get_pci_devices')
81488147
@mock.patch.object(pci_utils, 'get_mac_by_pci_address')
81498148
def test_populate_pci_mac_address_pf(self, mock_get_mac_by_pci_address,
81508149
mock_get_instance_pci_devs):
@@ -8158,7 +8157,7 @@ def test_populate_pci_mac_address_pf(self, mock_get_mac_by_pci_address,
81588157
self.api._populate_pci_mac_address(instance, 0, req)
81598158
self.assertEqual(expected_port_req_body, req)
81608159

8161-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
8160+
@mock.patch('nova.objects.Instance.get_pci_devices')
81628161
@mock.patch.object(pci_utils, 'get_mac_by_pci_address')
81638162
def test_populate_pci_mac_address_vf(self, mock_get_mac_by_pci_address,
81648163
mock_get_instance_pci_devs):
@@ -8170,7 +8169,7 @@ def test_populate_pci_mac_address_vf(self, mock_get_mac_by_pci_address,
81708169
self.api._populate_pci_mac_address(instance, 42, port_req_body)
81718170
self.assertEqual(port_req_body, req)
81728171

8173-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
8172+
@mock.patch('nova.objects.Instance.get_pci_devices')
81748173
@mock.patch.object(pci_utils, 'get_mac_by_pci_address')
81758174
def test_populate_pci_mac_address_vf_fail(self,
81768175
mock_get_mac_by_pci_address,
@@ -8185,7 +8184,7 @@ def test_populate_pci_mac_address_vf_fail(self,
81858184
self.api._populate_pci_mac_address(instance, 42, port_req_body)
81868185
self.assertEqual(port_req_body, req)
81878186

8188-
@mock.patch.object(pci_manager, 'get_instance_pci_devs')
8187+
@mock.patch('nova.objects.Instance.get_pci_devices')
81898188
@mock.patch('nova.network.neutron.LOG.error')
81908189
def test_populate_pci_mac_address_no_device(self, mock_log_error,
81918190
mock_get_instance_pci_devs):

0 commit comments

Comments
 (0)