diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py
index 86dd43fb59c..5e53598231c 100644
--- a/nova/tests/unit/virt/libvirt/test_driver.py
+++ b/nova/tests/unit/virt/libvirt/test_driver.py
@@ -6870,20 +6870,14 @@ def test_live_migration_copy_disk_paths(self, mock_xml):
"_live_migration_copy_disk_paths")
def test_live_migration_data_gb_plain(self, mock_paths):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
- dom = fakelibvirt.Domain(drvr._get_connection(), "", False)
- guest = libvirt_guest.Guest(dom)
instance = objects.Instance(**self.test_instance)
- data_gb = drvr._live_migration_data_gb(instance, guest, False)
+ data_gb = drvr._live_migration_data_gb(instance, [])
self.assertEqual(2, data_gb)
self.assertEqual(0, mock_paths.call_count)
- @mock.patch.object(libvirt_driver.LibvirtDriver,
- "_live_migration_copy_disk_paths")
- def test_live_migration_data_gb_block(self, mock_paths):
+ def test_live_migration_data_gb_block(self):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
- dom = fakelibvirt.Domain(drvr._get_connection(), "", False)
- guest = libvirt_guest.Guest(dom)
instance = objects.Instance(**self.test_instance)
def fake_stat(path):
@@ -6902,15 +6896,14 @@ def st_size(self):
else:
raise Exception("Should not be reached")
- mock_paths.return_value = ["/var/lib/nova/instance/123/disk.root",
- "/dev/mapper/somevol"]
+ disk_paths = ["/var/lib/nova/instance/123/disk.root",
+ "/dev/mapper/somevol"]
with mock.patch.object(os, "stat") as mock_stat:
mock_stat.side_effect = fake_stat
- data_gb = drvr._live_migration_data_gb(instance, guest, True)
+ data_gb = drvr._live_migration_data_gb(instance, disk_paths)
# Expecting 2 GB for RAM, plus 10 GB for disk.root
# and 1.5 GB rounded to 2 GB for somevol, so 14 GB
self.assertEqual(14, data_gb)
- self.assertEqual(1, mock_paths.call_count)
EXPECT_SUCCESS = 1
EXPECT_FAILURE = 2
@@ -6978,7 +6971,8 @@ def fake_time():
False,
migrate_data,
dom,
- finish_event)
+ finish_event,
+ [])
if expect_result == self.EXPECT_SUCCESS:
self.assertFalse(fake_recover_method.called,
@@ -7239,14 +7233,18 @@ def test_live_migration_downtime_steps(self):
@mock.patch.object(libvirt_driver.LibvirtDriver, "_live_migration_monitor")
@mock.patch.object(host.Host, "get_guest")
@mock.patch.object(fakelibvirt.Connection, "_mark_running")
- def test_live_migration_main(self, mock_running, mock_guest,
- mock_monitor, mock_thread):
+ @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):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
instance = objects.Instance(**self.test_instance)
dom = fakelibvirt.Domain(drvr._get_connection(),
"demo", True)
guest = libvirt_guest.Guest(dom)
migrate_data = {}
+ disk_paths = ['/dev/vda', '/dev/vdb']
+ mock_copy_disk_path.return_value = disk_paths
mock_guest.return_value = guest
@@ -7257,7 +7255,7 @@ def fake_recover():
pass
drvr._live_migration(self.context, instance, "fakehost",
- fake_post, fake_recover, False,
+ fake_post, fake_recover, True,
migrate_data)
class AnyEventletEvent(object):
@@ -7266,12 +7264,12 @@ def __eq__(self, other):
mock_thread.assert_called_once_with(
drvr._live_migration_operation,
- self.context, instance, "fakehost", False,
+ self.context, instance, "fakehost", True,
migrate_data, dom)
mock_monitor.assert_called_once_with(
self.context, instance, guest, "fakehost",
- fake_post, fake_recover, False,
- migrate_data, dom, AnyEventletEvent())
+ fake_post, fake_recover, True,
+ migrate_data, dom, AnyEventletEvent(), disk_paths)
def _do_test_create_images_and_backing(self, disk_type):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 797c4846c9e..4a782e59195 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -5828,12 +5828,12 @@ def _live_migration_copy_disk_paths(self, guest):
disks.append(dev.source_path)
return disks
- def _live_migration_data_gb(self, instance, guest, block_migration):
+ def _live_migration_data_gb(self, instance, disk_paths):
'''Calculate total amount of data to be transferred
:param instance: the nova.objects.Instance being migrated
- :param guest: the Guest being migrated
- :param block_migration: true if block migration is requested
+ :param disk_paths: list of disk paths that are being migrated
+ with instance
Calculates the total amount of data that needs to be
transferred during the live migration. The actual
@@ -5849,12 +5849,8 @@ def _live_migration_data_gb(self, instance, guest, block_migration):
if ram_gb < 2:
ram_gb = 2
- if not block_migration:
- return ram_gb
-
- paths = self._live_migration_copy_disk_paths(guest)
disk_gb = 0
- for path in paths:
+ for path in disk_paths:
try:
size = os.stat(path).st_size
size_gb = (size / units.Gi)
@@ -5872,9 +5868,9 @@ def _live_migration_data_gb(self, instance, guest, block_migration):
def _live_migration_monitor(self, context, instance, guest,
dest, post_method,
recover_method, block_migration,
- migrate_data, dom, finish_event):
- data_gb = self._live_migration_data_gb(instance, guest,
- block_migration)
+ migrate_data, dom, finish_event,
+ disk_paths):
+ data_gb = self._live_migration_data_gb(instance, disk_paths)
downtime_steps = list(self._migration_downtime_steps(data_gb))
completion_timeout = int(
CONF.libvirt.live_migration_completion_timeout * data_gb)
@@ -6087,6 +6083,11 @@ def _live_migration(self, context, instance, dest, post_method,
guest = self._host.get_guest(instance)
+ disk_paths = []
+ if block_migration:
+ disk_paths = self._live_migration_copy_disk_paths(
+ context, instance, guest)
+
# TODO(sahid): We are converting all calls from a
# virDomain object to use nova.virt.libvirt.Guest.
# We should be able to remove dom at the end.
@@ -6114,7 +6115,7 @@ def thread_finished(thread, event):
self._live_migration_monitor(context, instance, guest, dest,
post_method, recover_method,
block_migration, migrate_data,
- dom, finish_event)
+ dom, finish_event, disk_paths)
except Exception as ex:
LOG.warn(_LW("Error monitoring migration: %(ex)s"),
{"ex": ex}, instance=instance, exc_info=True)