summaryrefslogtreecommitdiff
path: root/nova/objects
diff options
context:
space:
mode:
authorBalazs Gibizer <gibi@redhat.com>2022-08-19 20:21:15 +0200
committerBalazs Gibizer <gibi@redhat.com>2022-08-27 12:44:11 +0200
commitccab6fed463337c029459469c76e92af3b96fa06 (patch)
tree44aff66f136155b86d25df39fb7b7406ef4bac35 /nova/objects
parent06389f8d849c6380a5f3763f03e84f804c4d29f2 (diff)
downloadnova-ccab6fed463337c029459469c76e92af3b96fa06.tar.gz
Generate request_id for Flavor based InstancePCIRequest
The InstancePCIRequest.request_id is used to correlate allocated PciDevice objects with the InstancePCIRequest object triggered the PCI allocation. For neutron port based PCI requests the IstancePCIRequest.request_id was already set to a generated UUID by nova. But for Flavor based request the request_id was kept None. The placement PCI scheduling code depends on the request_id to be a unique identifier of the request. So this patch starts filling the request_id for flavor based requests as well. This change showed than in some places nova still uses the request_id == None condition to distinguish between flavor based and neutron based requests. This logic is now adapted to use the newer and better InstancePCIRequest.source based approach. Also we took the opportunity to move the logic of querying PCI devices allocated to an instance to the Instance ovo. This change fills the request_id for newly created flavor based InstancePCIRequest ovos. But the change in logic to use the InstancePCIRequest.source property instead of the request_id == None condition works even if the request_id is None for already existing InstancePCIRequest objects. So this patch does not include a data migration logic to fill request_id for existing objects. blueprint: pci-device-tracking-in-placement Change-Id: I53e03ff7a0221db682b043fb6d5adba3f5c9fdbe
Diffstat (limited to 'nova/objects')
-rw-r--r--nova/objects/instance.py41
1 files changed, 41 insertions, 0 deletions
diff --git a/nova/objects/instance.py b/nova/objects/instance.py
index e99762d277..0bdf4af31e 100644
--- a/nova/objects/instance.py
+++ b/nova/objects/instance.py
@@ -13,6 +13,7 @@
# under the License.
import contextlib
+import typing as ty
from oslo_config import cfg
from oslo_db import exception as db_exc
@@ -1226,6 +1227,46 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
pci_req for pci_req in self.pci_requests.requests
if pci_req.request_id != pci_device.request_id]
+ def get_pci_devices(
+ self,
+ source: ty.Optional[int] = None,
+ request_id: ty.Optional[str] = None,
+ ) -> ty.List["objects.PciDevice"]:
+ """Return the PCI devices allocated to the instance
+
+ :param source: Filter by source. It can be
+ InstancePCIRequest.FLAVOR_ALIAS or InstancePCIRequest.NEUTRON_PORT
+ or None. None means returns devices from both type of requests.
+ :param request_id: Filter by PciDevice.request_id. None means do not
+ filter by request_id.
+ :return: a list of matching PciDevice objects
+ """
+ if not self.pci_devices:
+ # return early to avoid an extra lazy load on self.pci_requests
+ # if there are no devices allocated to be filtered
+ return []
+ else:
+ devs = self.pci_devices.objects
+
+ if request_id is not None:
+ devs = [dev for dev in devs if dev.request_id == request_id]
+
+ if source is not None:
+ # NOTE(gibi): this happens to work for the old requests when the
+ # request has request_id None and therefore the device allocated
+ # due to that request has request_id None too, so they will be
+ # mapped via the None key.
+ req_id_to_req = {
+ req.request_id: req for req in self.pci_requests.requests
+ }
+ devs = [
+ dev
+ for dev in devs
+ if (req_id_to_req[dev.request_id].source == source)
+ ]
+
+ return devs
+
def _make_instance_list(context, inst_list, db_inst_list, expected_attrs):
get_fault = expected_attrs and 'fault' in expected_attrs