From b08d59ac7b21909046faee6c8f8fd50866befc76 Mon Sep 17 00:00:00 2001 From: LuyaoZhong Date: Mon, 17 Feb 2020 11:19:42 +0000 Subject: [PATCH] bug-fix: Reject live migration with vpmem Reject live migration if there are virtual persistent memory resources. Otherwise, if dest host has same vpmem backend file name as that used by instance, live migration will succeed and these files will be used but not tracked in Nova; if dest host has no those vpmems, it will trigger an error. Conflicts: nova/conductor/tasks/live_migrate.py nova/tests/unit/conductor/tasks/test_live_migrate.py Note(luyao): Conflicts due to bd8e2fe9c80dbe39bdd03fb213148b30a9dfd36e and 5f63ada309f562f3ffe9b75b6f1acf1efb80ee4e not being present in Train. Change-Id: I900f74d482fc87da5b1b5ec9db2ad5aefcfcfe7a Closes-bug: #1863605 (cherry picked from commit db93b704cecdb72e9c23c7a4c07786f67bcfe7b2) --- nova/conductor/tasks/live_migrate.py | 17 +++++++++++++++++ .../unit/conductor/tasks/test_live_migrate.py | 14 ++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/nova/conductor/tasks/live_migrate.py b/nova/conductor/tasks/live_migrate.py index 6254187655e5..abcd144b42d3 100644 --- a/nova/conductor/tasks/live_migrate.py +++ b/nova/conductor/tasks/live_migrate.py @@ -254,6 +254,22 @@ class LiveMigrationTask(base.TaskBase): "source and destination nodes do not support " "the operation.") + def _check_can_migrate_specific_resources(self): + """Checks that an instance can migrate with specific resources. + + For virtual persistent memory resource: + 1. check if Instance contains vpmem resources + 2. check if live migration with vpmem is supported + """ + if not self.instance.resources: + return + + for resource in self.instance.resources: + if resource.resource_class.startswith("CUSTOM_PMEM_NAMESPACE_"): + raise exception.MigrationPreCheckError( + reason="Cannot live migration with virtual persistent " + "memory, the operation is not supported.") + def _check_host_is_up(self, host): service = objects.Service.get_by_compute_host(self.context, host) @@ -333,6 +349,7 @@ class LiveMigrationTask(base.TaskBase): return source_info, destination_info def _call_livem_checks_on_host(self, destination): + self._check_can_migrate_specific_resources() self._check_can_migrate_pci(self.source, destination) try: self.migrate_data = self.compute_rpcapi.\ diff --git a/nova/tests/unit/conductor/tasks/test_live_migrate.py b/nova/tests/unit/conductor/tasks/test_live_migrate.py index d3586e8b90f7..8a4f58ec6ed2 100644 --- a/nova/tests/unit/conductor/tasks/test_live_migrate.py +++ b/nova/tests/unit/conductor/tasks/test_live_migrate.py @@ -57,6 +57,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): self.context, objects.Instance(), db_instance) self.instance.system_metadata = {'image_hw_disk_bus': 'scsi'} self.instance.numa_topology = None + self.instance.resources = None self.destination = "destination" self.block_migration = "bm" self.disk_over_commit = "doc" @@ -740,3 +741,16 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): _test, pci_requests, False, True) self.assertRaises(exception.MigrationPreCheckError, _test, pci_requests, True, True) + + def test_check_can_migrate_specific_resources(self): + vpmem_0 = objects.LibvirtVPMEMDevice( + label='4GB', name='ns_0', devpath='/dev/dax0.0', + size=4292870144, align=2097152) + resource_0 = objects.Resource( + provider_uuid=uuids.rp, + resource_class="CUSTOM_PMEM_NAMESPACE_4GB", + identifier='ns_0', metadata=vpmem_0) + self.instance.resources = objects.ResourceList( + objects=[resource_0]) + self.assertRaises(exception.MigrationPreCheckError, + self.task._check_can_migrate_specific_resources)