From db93b704cecdb72e9c23c7a4c07786f67bcfe7b2 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. Change-Id: I900f74d482fc87da5b1b5ec9db2ad5aefcfcfe7a Closes-bug: #1863605 Implements: blueprint support-live-migration-with-virtual-persistent-memory --- 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 cf53353195..acea49228e 100644 --- a/nova/conductor/tasks/live_migrate.py +++ b/nova/conductor/tasks/live_migrate.py @@ -241,6 +241,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) @@ -322,6 +338,7 @@ class LiveMigrationTask(base.TaskBase): return source_info, destination_info def _call_livem_checks_on_host(self, destination, provider_mapping): + 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 7539e47f47..acf282c8de 100644 --- a/nova/tests/unit/conductor/tasks/test_live_migrate.py +++ b/nova/tests/unit/conductor/tasks/test_live_migrate.py @@ -61,6 +61,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): self.instance.system_metadata = {'image_hw_disk_bus': 'scsi'} self.instance.numa_topology = None self.instance.pci_requests = None + self.instance.resources = None self.destination = "destination" self.block_migration = "bm" self.disk_over_commit = "doc" @@ -858,3 +859,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)