summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2021-02-03 19:56:01 +0000
committerGerrit Code Review <review@openstack.org>2021-02-03 19:56:01 +0000
commit2e31f6a0c036b575b08ba1e30de2c13d1e4d7e18 (patch)
tree6a43ae2b6573dcc1cfd73b204ab9747aa213c34a
parentcf1db74731198b573cc3693c7923c665b43fcf9c (diff)
parent09784db62fcd01124a101c4c69cab6e71e1ac781 (diff)
downloadnova-2e31f6a0c036b575b08ba1e30de2c13d1e4d7e18.tar.gz
Merge "Prevent archiving of pci_devices records because of 'instance_uuid'" into stable/victoria
-rw-r--r--nova/db/sqlalchemy/api.py6
-rw-r--r--nova/tests/functional/db/test_archive.py15
2 files changed, 20 insertions, 1 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index e523f575a1..1cf18ff292 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -4225,7 +4225,11 @@ def _archive_deleted_rows_for_table(metadata, tablename, max_rows, before):
# NOTE(jake): instance_actions_events doesn't have a instance_uuid column
# but still needs to be archived as it is a FK constraint
if ((max_rows is None or rows_archived < max_rows) and
- ('instance_uuid' in columns or
+ # NOTE(melwitt): The pci_devices table uses the 'instance_uuid'
+ # column to track the allocated association of a PCI device and its
+ # records are not tied to the lifecycles of instance records.
+ (tablename != 'pci_devices' and
+ 'instance_uuid' in columns or
tablename == 'instance_actions_events')):
instances = models.BASE.metadata.tables['instances']
limit = max_rows - rows_archived if max_rows is not None else None
diff --git a/nova/tests/functional/db/test_archive.py b/nova/tests/functional/db/test_archive.py
index 0bda64eb43..68ddb327ba 100644
--- a/nova/tests/functional/db/test_archive.py
+++ b/nova/tests/functional/db/test_archive.py
@@ -114,6 +114,19 @@ class TestDatabaseArchive(integrated_helpers._IntegratedTestBase):
# Verify we have some system_metadata since we'll check that later.
self.assertTrue(len(instance.system_metadata),
'No system_metadata for instance: %s' % server_id)
+ # Create a pci_devices record to simulate an instance that had a PCI
+ # device allocated at the time it was deleted. There is a window of
+ # time between deletion of the instance record and freeing of the PCI
+ # device in nova-compute's _complete_deletion method during RT update.
+ db.pci_device_update(admin_context, 1, 'fake-address',
+ {'compute_node_id': 1,
+ 'address': 'fake-address',
+ 'vendor_id': 'fake',
+ 'product_id': 'fake',
+ 'dev_type': 'fake',
+ 'label': 'fake',
+ 'status': 'allocated',
+ 'instance_uuid': instance.uuid})
# Now try and archive the soft deleted records.
results, deleted_instance_uuids, archived = \
db.archive_deleted_rows(max_rows=100)
@@ -128,6 +141,8 @@ class TestDatabaseArchive(integrated_helpers._IntegratedTestBase):
self.assertIn('instance_actions', results)
self.assertIn('instance_actions_events', results)
self.assertEqual(sum(results.values()), archived)
+ # Verify that the pci_devices record has not been dropped
+ self.assertNotIn('pci_devices', results)
def _get_table_counts(self):
engine = sqlalchemy_api.get_engine()