Skip to content

Commit e8999f0

Browse files
committed
Fix regression with live migration on shared storage
The commit c1ccc1a introduced a regression when NUMA live migration was done on shared storage The live migration support for the power mgmt feature means we need to call driver.cleanup() for all NUMA instances to potentially offline pcpus that are not used any more after the instance is migrated away. However this change exposed an issue with the disk cleanup logic. Nova should never delete the instance directory if that directory is on shared storage (e.g. the nova instances path is backed by NFS). This patch will fix that behavior so live migration will function 2023.x only: Conflict resolved in compute/manager.py due to bluperint libvirt-mdev-live-migrate is not in 2023.x and the related unit test is removed. Closes-Bug: #2080436 Change-Id: Ia2bbb5b4ac728563a8aabd857ed0503449991df1 (cherry picked from commit 035b840) (cherry picked from commit 57e037b) (cherry picked from commit 0e4406a)
1 parent cf08543 commit e8999f0

File tree

5 files changed

+39
-9
lines changed

5 files changed

+39
-9
lines changed

nova/compute/manager.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9105,7 +9105,9 @@ def _live_migration_cleanup_flags(self, migrate_data, migr_ctxt=None):
91059105
# vpmem must be cleaned
91069106
do_cleanup = (not migrate_data.is_shared_instance_path or
91079107
has_vpmem or power_management_possible)
9108-
destroy_disks = not migrate_data.is_shared_block_storage
9108+
destroy_disks = not (
9109+
migrate_data.is_shared_block_storage or
9110+
migrate_data.is_shared_instance_path)
91099111
elif isinstance(migrate_data, migrate_data_obj.HyperVLiveMigrateData):
91109112
# NOTE(claudiub): We need to cleanup any zombie Planned VM.
91119113
do_cleanup = True

nova/tests/unit/compute/test_compute_mgr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11201,7 +11201,7 @@ def test_live_migration_cleanup_flags_shared_path_and_vpmem_libvirt(self):
1120111201
do_cleanup, destroy_disks = self.compute._live_migration_cleanup_flags(
1120211202
migrate_data, migr_ctxt)
1120311203
self.assertTrue(do_cleanup)
11204-
self.assertTrue(destroy_disks)
11204+
self.assertFalse(destroy_disks)
1120511205

1120611206
def test_live_migration_cleanup_flags_block_migrate_libvirt(self):
1120711207
migrate_data = objects.LibvirtLiveMigrateData(
@@ -11228,7 +11228,7 @@ def test_live_migration_cleanup_flags_shared_path_libvirt(self):
1122811228
do_cleanup, destroy_disks = self.compute._live_migration_cleanup_flags(
1122911229
migrate_data)
1123011230
self.assertFalse(do_cleanup)
11231-
self.assertTrue(destroy_disks)
11231+
self.assertFalse(destroy_disks)
1123211232

1123311233
def test_live_migration_cleanup_flags_shared_libvirt(self):
1123411234
migrate_data = objects.LibvirtLiveMigrateData(

nova/tests/unit/virt/libvirt/test_driver.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20448,7 +20448,8 @@ def test_cleanup_migrate_data_shared_block_storage(self,
2044820448
# is_shared_block_storage=True and destroy_disks=False.
2044920449
instance = objects.Instance(self.context, **self.test_instance)
2045020450
migrate_data = objects.LibvirtLiveMigrateData(
20451-
is_shared_block_storage=True)
20451+
is_shared_block_storage=True,
20452+
is_shared_instance_path=False)
2045220453
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
2045320454
drvr.cleanup(
2045420455
self.context, instance, network_info={}, destroy_disks=False,
@@ -20458,6 +20459,25 @@ def test_cleanup_migrate_data_shared_block_storage(self,
2045820459
self.assertTrue(instance.cleaned)
2045920460
save.assert_called_once_with()
2046020461

20462+
@mock.patch.object(libvirt_driver.LibvirtDriver, 'delete_instance_files',
20463+
return_value=True)
20464+
@mock.patch.object(objects.Instance, 'save')
20465+
@mock.patch.object(libvirt_driver.LibvirtDriver, '_undefine_domain')
20466+
def test_cleanup_migrate_data_block_storage_and_share_instance_dir(
20467+
self, _undefine_domain, save, delete_instance_files
20468+
):
20469+
# Test the case when the instance directory is on shared storage
20470+
# (e.g. NFS) and the instance is booted form volume.
20471+
instance = objects.Instance(self.context, **self.test_instance)
20472+
migrate_data = objects.LibvirtLiveMigrateData(
20473+
is_shared_block_storage=True,
20474+
is_shared_instance_path=True)
20475+
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
20476+
drvr.cleanup(
20477+
self.context, instance, network_info={}, destroy_disks=False,
20478+
migrate_data=migrate_data, destroy_vifs=False)
20479+
delete_instance_files.assert_not_called()
20480+
2046120481
@mock.patch.object(libvirt_driver.LibvirtDriver, 'delete_instance_files',
2046220482
return_value=True)
2046320483
@mock.patch.object(objects.Instance, 'save')

nova/virt/libvirt/driver.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,12 +1614,12 @@ def cleanup(self, context, instance, network_info, block_device_info=None,
16141614
cleanup_instance_dir = True
16151615
cleanup_instance_disks = True
16161616
else:
1617-
# NOTE(mdbooth): I think the theory here was that if this is a
1618-
# migration with shared block storage then we need to delete the
1619-
# instance directory because that's not shared. I'm pretty sure
1620-
# this is wrong.
1617+
# NOTE(mheler): For shared block storage we only need to clean up
1618+
# the instance directory when it's not on a shared path.
16211619
if migrate_data and 'is_shared_block_storage' in migrate_data:
1622-
cleanup_instance_dir = migrate_data.is_shared_block_storage
1620+
cleanup_instance_dir = (
1621+
migrate_data.is_shared_block_storage and
1622+
not migrate_data.is_shared_instance_path)
16231623

16241624
# NOTE(lyarwood): The following workaround allows operators to
16251625
# ensure that non-shared instance directories are removed after an
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
fixes:
3+
- |
4+
Fixes a regression for live migration on shared storage that
5+
was removing the backing disk and instance folder during the
6+
cleanup of a virtual machine post live migration.
7+
`bug 2080436
8+
<https://bugs.launchpad.net/nova/+bug/2080436>`__ for details.

0 commit comments

Comments
 (0)