summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2022-06-18 12:04:08 +0000
committerGerrit Code Review <review@openstack.org>2022-06-18 12:04:08 +0000
commit7d5b28985c60322072562c0f7bd5e2cd8540b3d9 (patch)
treeae8ff453f4efc3044dcfce832610c136596f3c21
parent6e9ad143110657e874d88af7a0a50d0fd6738a2a (diff)
parent76ea8ee37707e0e2160d30cdb5c74d1fcad60de3 (diff)
downloadnova-23.2.1.tar.gz
Merge "libvirt: Abort live-migration job when monitoring fails" into stable/wallaby23.2.1
-rw-r--r--nova/tests/unit/virt/libvirt/test_driver.py27
-rw-r--r--nova/virt/libvirt/driver.py12
2 files changed, 33 insertions, 6 deletions
diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py
index e095ab32f0..00ee408f45 100644
--- a/nova/tests/unit/virt/libvirt/test_driver.py
+++ b/nova/tests/unit/virt/libvirt/test_driver.py
@@ -13338,9 +13338,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
@mock.patch.object(fakelibvirt.Connection, "_mark_running")
@mock.patch.object(libvirt_driver.LibvirtDriver,
"_live_migration_copy_disk_paths")
- def test_live_migration_main(self, mock_copy_disk_path, mock_running,
- mock_guest, mock_monitor, mock_thread,
- mock_conn):
+ @mock.patch.object(libvirt_driver.LibvirtDriver, "live_migration_abort")
+ def _test_live_migration_main(self, mock_abort, mock_copy_disk_path,
+ mock_running, mock_guest, mock_monitor,
+ mock_thread, mock_conn,
+ mon_side_effect=None):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
instance = objects.Instance(**self.test_instance)
@@ -13353,6 +13355,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_copy_disk_path.return_value = disks_to_copy
mock_guest.return_value = guest
+ mock_monitor.side_effect = mon_side_effect
def fake_post():
pass
@@ -13360,9 +13363,15 @@ class LibvirtConnTestCase(test.NoDBTestCase,
def fake_recover():
pass
- drvr._live_migration(self.context, instance, "fakehost",
- fake_post, fake_recover, True,
- migrate_data)
+ if mon_side_effect:
+ self.assertRaises(mon_side_effect, drvr._live_migration,
+ self.context, instance, "fakehost", fake_post,
+ fake_recover, True, migrate_data)
+ mock_abort.assert_called_once_with(instance)
+ else:
+ drvr._live_migration(self.context, instance, "fakehost", fake_post,
+ fake_recover, True, migrate_data)
+
mock_copy_disk_path.assert_called_once_with(self.context, instance,
guest)
@@ -13379,6 +13388,12 @@ class LibvirtConnTestCase(test.NoDBTestCase,
fake_post, fake_recover, True,
migrate_data, AnyEventletEvent(), disks_to_copy[0])
+ def test_live_migration_main(self):
+ self._test_live_migration_main()
+
+ def test_live_migration_main_monitoring_failed(self):
+ self._test_live_migration_main(mon_side_effect=Exception)
+
@mock.patch('os.path.exists', return_value=False)
@mock.patch('nova.virt.libvirt.utils.create_image')
@mock.patch.object(libvirt_driver.LibvirtDriver,
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 2c6dab3891..73ea0d2c56 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -9967,6 +9967,18 @@ class LibvirtDriver(driver.ComputeDriver):
except Exception as ex:
LOG.warning("Error monitoring migration: %(ex)s",
{"ex": ex}, instance=instance, exc_info=True)
+ # NOTE(aarents): Ensure job is aborted if still running before
+ # raising the exception so this would avoid the migration to be
+ # done and the libvirt guest to be resumed on the target while
+ # the instance record would still related to the source host.
+ try:
+ # If migration is running in post-copy mode and guest
+ # already running on dest host, libvirt will refuse to
+ # cancel migration job.
+ self.live_migration_abort(instance)
+ except libvirt.libvirtError:
+ LOG.warning("Error occured when trying to abort live ",
+ "migration job, ignoring it.", instance=instance)
raise
finally:
LOG.debug("Live migration monitoring is all done",