From 7f3f0ef1fbb51f6f17d2c13840e0f98d17fa9093 Mon Sep 17 00:00:00 2001 From: Steven Webster Date: Wed, 5 Apr 2017 09:05:07 -0400 Subject: [PATCH] Fix mitaka online migration for PCI devices Currently, a validation error is thrown if we find any PCI device records which have not populated the parent_addr column on a nova upgrade. However, the only PCI records for which a parent_addr makes sense for are those with a device type of 'type-VF' (ie. an SRIOV virtual function). PCI records with a device type of 'type-PF' or 'type-PCI' will not have a parent_addr. If any of those records are present on upgrade, the validation will fail. This change checks that the device type of the PCI record is 'type-VF' when making sure the parent_addr has been correctly populated Closes-Bug: #1680918 Change-Id: Ia7e773674a4976fc03deee3f08a6ddb45568ec11 --- .../330_enforce_mitaka_online_migrations.py | 8 ++++- .../unit/db/test_sqlalchemy_migration.py | 31 +++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/330_enforce_mitaka_online_migrations.py b/nova/db/sqlalchemy/migrate_repo/versions/330_enforce_mitaka_online_migrations.py index d6a432c81dc6..3649f13e2d7b 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/330_enforce_mitaka_online_migrations.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/330_enforce_mitaka_online_migrations.py @@ -38,9 +38,15 @@ def upgrade(migrate_engine): raise exception.ValidationError(detail=msg) pci_devices = Table('pci_devices', meta, autoload=True) + + # Ensure that all non-deleted PCI device records have a populated + # parent address. Note that we test directly against the 'type-VF' + # enum value to prevent issues with this migration going forward + # if the definition is altered. count = select([func.count()]).select_from(pci_devices).where(and_( pci_devices.c.deleted == 0, - pci_devices.c.parent_addr == None)).execute().scalar() # NOQA + pci_devices.c.parent_addr == None, + pci_devices.c.dev_type == 'type-VF')).execute().scalar() # NOQA if count > 0: msg = WARNING_MSG % { 'count': count, diff --git a/nova/tests/unit/db/test_sqlalchemy_migration.py b/nova/tests/unit/db/test_sqlalchemy_migration.py index fad21ef9754b..e53f8d08705d 100644 --- a/nova/tests/unit/db/test_sqlalchemy_migration.py +++ b/nova/tests/unit/db/test_sqlalchemy_migration.py @@ -268,19 +268,46 @@ class TestNewtonCheck(test.TestCase): self.assertRaises(exception.ValidationError, self.migration.upgrade, self.engine) - def test_pci_device_not_migrated(self): + def test_pci_device_type_vf_not_migrated(self): db_api.pci_device_update(self.context, 1, 'foo:bar', {'parent_addr': None, 'compute_node_id': 1, 'address': 'foo:bar', 'vendor_id': '123', 'product_id': '456', - 'dev_type': 'foo', + 'dev_type': 'type-VF', 'label': 'foobar', 'status': 'whatisthis?'}) + # type-VF devices should have a parent_addr self.assertRaises(exception.ValidationError, self.migration.upgrade, self.engine) + def test_pci_device_type_pf_not_migrated(self): + db_api.pci_device_update(self.context, 1, 'foo:bar', + {'parent_addr': None, + 'compute_node_id': 1, + 'address': 'foo:bar', + 'vendor_id': '123', + 'product_id': '456', + 'dev_type': 'type-PF', + 'label': 'foobar', + 'status': 'whatisthis?'}) + # blocker should not block on type-PF devices + self.migration.upgrade(self.engine) + + def test_pci_device_type_pci_not_migrated(self): + db_api.pci_device_update(self.context, 1, 'foo:bar', + {'parent_addr': None, + 'compute_node_id': 1, + 'address': 'foo:bar', + 'vendor_id': '123', + 'product_id': '456', + 'dev_type': 'type-PCI', + 'label': 'foobar', + 'status': 'whatisthis?'}) + # blocker should not block on type-PCI devices + self.migration.upgrade(self.engine) + def test_deleted_not_migrated(self): cn_values = dict(vcpus=1, memory_mb=512, local_gb=10, vcpus_used=0, memory_mb_used=256,