Merge "Separate methods to free claimed and allocated devs"

This commit is contained in:
Zuul 2019-03-07 20:41:03 +00:00 committed by Gerrit Code Review
commit 131f7606c1
2 changed files with 84 additions and 12 deletions

View File

@ -314,23 +314,43 @@ class PciDevTracker(object):
for dev in freed_devs:
self.stats.add_device(dev)
def _free_instance(self, instance):
def free_instance_allocations(self, context, instance):
"""Free devices that are in ALLOCATED state for instance.
:param context: user request context (nova.context.RequestContext)
:param instance: instance object
"""
if self.allocations.pop(instance['uuid'], None):
for dev in self.pci_devs:
if (dev.status == fields.PciDeviceStatus.ALLOCATED and
dev.instance_uuid == instance['uuid']):
self._free_device(dev)
def free_instance_claims(self, context, instance):
"""Free devices that are in CLAIMED state for instance.
:param context: user request context (nova.context.RequestContext)
:param instance: instance object
"""
if self.claims.pop(instance['uuid'], None):
for dev in self.pci_devs:
if (dev.status == fields.PciDeviceStatus.CLAIMED and
dev.instance_uuid == instance['uuid']):
self._free_device(dev)
def free_instance(self, context, instance):
"""Free devices that are in CLAIMED or ALLOCATED state for instance.
:param context: user request context (nova.context.RequestContext)
:param instance: instance object
"""
# Note(yjiang5): When an instance is resized, the devices in the
# destination node are claimed to the instance in prep_resize stage.
# However, the instance contains only allocated devices
# information, not the claimed one. So we can't use
# instance['pci_devices'] to check the devices to be freed.
for dev in self.pci_devs:
if dev.status in (fields.PciDeviceStatus.CLAIMED,
fields.PciDeviceStatus.ALLOCATED):
if dev.instance_uuid == instance['uuid']:
self._free_device(dev)
def free_instance(self, context, instance):
if self.allocations.pop(instance['uuid'], None):
self._free_instance(instance)
elif self.claims.pop(instance['uuid'], None):
self._free_instance(instance)
self.free_instance_allocations(context, instance)
self.free_instance_claims(context, instance)
def update_pci_for_instance(self, context, instance, sign):
"""Update PCI usage information if devices are de/allocated.

View File

@ -546,6 +546,58 @@ class PciDevTrackerTestCase(test.NoDBTestCase):
self.assertIn(pci_device.id, free_pci_device_ids)
self.assertIsNone(self.tracker.allocations.get(instance_uuid))
def test_free_instance_claims(self):
# Create an InstancePCIRequest object
pci_requests_obj = self._create_pci_requests_object(
[{'count': 1, 'spec': [{'vendor_id': 'v'}]}])
# Claim a single PCI device
claimed_devs = self.tracker.claim_instance(mock.sentinel.context,
pci_requests_obj, None)
# Assert we have exactly one claimed device for the given instance.
claimed_dev = claimed_devs[0]
instance_uuid = self.inst['uuid']
self.assertEqual(1, len(self.tracker.claims.get(instance_uuid)))
self.assertIn(claimed_dev.id,
[pci_dev.id for pci_dev in
self.tracker.claims.get(instance_uuid)])
self.assertIsNone(self.tracker.allocations.get(instance_uuid))
# Free instance claims
self.tracker.free_instance_claims(mock.sentinel.context, self.inst)
# Assert no claims for instance and all PCI devices are free
self.assertIsNone(self.tracker.claims.get(instance_uuid))
free_devs = self.tracker.pci_stats.get_free_devs()
self.assertEqual(len(fake_db_devs), len(free_devs))
def test_free_instance_allocations(self):
# Create an InstancePCIRequest object
pci_requests_obj = self._create_pci_requests_object(
[{'count': 1, 'spec': [{'vendor_id': 'v'}]}])
# Allocate a single PCI device
allocated_devs = self.tracker.claim_instance(mock.sentinel.context,
pci_requests_obj, None)
self.tracker.allocate_instance(self.inst)
# Assert we have exactly one allocated device for the given instance.
allocated_dev = allocated_devs[0]
instance_uuid = self.inst['uuid']
self.assertIsNone(self.tracker.claims.get(instance_uuid))
self.assertEqual(1, len(self.tracker.allocations.get(instance_uuid)))
self.assertIn(allocated_dev.id,
[pci_dev.id for pci_dev in
self.tracker.allocations.get(instance_uuid)])
# Free instance allocations and assert claims did not change
self.tracker.free_instance_allocations(mock.sentinel.context,
self.inst)
# Assert all PCI devices are free.
self.assertIsNone(self.tracker.allocations.get(instance_uuid))
free_devs = self.tracker.pci_stats.get_free_devs()
self.assertEqual(len(fake_db_devs), len(free_devs))
class PciGetInstanceDevs(test.NoDBTestCase):