From c28c87db4c2b20e0f6c1375d2d4433e06c4e1743 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Sun, 13 Oct 2013 13:51:37 -0700 Subject: [PATCH] Check for None when cleaning PCI dev usage The PCI manager needs to check for instance UUIDs mapped to None when cleaning up it's internal claims/allocations maps. Also adds a check so the claims dict doesn't map to None in the first place. There was already a check like this when setting a value in the allocations dict. Closes-Bug: #1238374 Change-Id: I7ac010f7d50ad85c145e536cfd48e07c8f4602d3 --- nova/pci/pci_manager.py | 9 ++++++--- nova/tests/pci/test_pci_manager.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/nova/pci/pci_manager.py b/nova/pci/pci_manager.py index ac8c4e813b2a..f6760da48adf 100644 --- a/nova/pci/pci_manager.py +++ b/nova/pci/pci_manager.py @@ -267,7 +267,8 @@ class PciDevTracker(object): uuid = instance['uuid'] if sign == 1 and uuid not in self.claims: devs = self._claim_instance(instance, 'new_') - self.claims[uuid] = devs + if devs: + self.claims[uuid] = devs if sign == -1 and uuid in self.claims: self._free_instance(instance) @@ -282,11 +283,13 @@ class PciDevTracker(object): for uuid in self.claims.keys(): if uuid not in existed: - for dev in self.claims.pop(uuid): + devs = self.claims.pop(uuid, []) + for dev in devs: self._free_device(dev) for uuid in self.allocations.keys(): if uuid not in existed: - for dev in self.allocations.pop(uuid): + devs = self.allocations.pop(uuid, []) + for dev in devs: self._free_device(dev) def set_compute_node_id(self, node_id): diff --git a/nova/tests/pci/test_pci_manager.py b/nova/tests/pci/test_pci_manager.py index 0ad181a43e76..3c58dcbcabb5 100644 --- a/nova/tests/pci/test_pci_manager.py +++ b/nova/tests/pci/test_pci_manager.py @@ -306,6 +306,19 @@ class PciDevTrackerTestCase(test.TestCase): set([dev['vendor_id'] for dev in self.tracker.free_devs]), set(['v', 'v1'])) + def test_clean_usage_no_request_match_no_claims(self): + # Tests the case that there is no match for the request so the + # claims mapping is set to None for the instance when the tracker + # calls clean_usage. + self.pci_requests = None + self.tracker.update_pci_for_migration(instance=self.inst, sign=1) + self.assertEqual(3, len(self.tracker.free_devs)) + self.tracker.clean_usage([], [], []) + self.assertEqual(3, len(self.tracker.free_devs)) + self.assertEqual( + set([dev['address'] for dev in self.tracker.free_devs]), + set(['0000:00:00.1', '0000:00:00.2', '0000:00:00.3'])) + class PciGetInstanceDevs(test.TestCase): def test_get_devs_non_object(self):