diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 214bb2938a88..85378df20456 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -440,7 +440,7 @@ class FakeNodeDevice(object): return self.xml -class LibvirtConnTestCase(test.NoDBTestCase): +class LibvirtConnTestCase(test.TestCase): REQUIRES_LOCKING = True @@ -6881,7 +6881,9 @@ class LibvirtConnTestCase(test.NoDBTestCase): drvr.plug_vifs(mox.IsA(instance), nw_info) self.mox.ReplayAll() - result = drvr.pre_live_migration(c, instance, vol, nw_info, None) + result = drvr.pre_live_migration( + c, instance, vol, nw_info, None, + migrate_data={"block_migration": False}) target_ret = { 'graphics_listen_addrs': {'spice': '127.0.0.1', 'vnc': '127.0.0.1'}, @@ -7080,6 +7082,32 @@ class LibvirtConnTestCase(test.NoDBTestCase): self.assertTrue(create_image_mock.called) self.assertIsInstance(res, dict) + def test_pre_live_migration_block_migrate_fails(self): + bdms = [{ + 'connection_info': { + 'serial': '12345', + u'data': { + 'device_path': + u'/dev/disk/by-path/ip-1.2.3.4:3260-iqn.abc.12345.t-lun-X' + } + }, + 'mount_device': '/dev/sda'}] + + drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + instance = objects.Instance(**self.test_instance) + + with contextlib.nested( + mock.patch.object(drvr, '_create_images_and_backing'), + mock.patch.object(drvr, 'ensure_filtering_rules_for_instance'), + mock.patch.object(drvr, 'plug_vifs'), + mock.patch.object(drvr, '_connect_volume'), + mock.patch.object(driver, 'block_device_info_get_mapping', + return_value=bdms)): + self.assertRaises(exception.MigrationError, + drvr.pre_live_migration, + self.context, instance, block_device_info=None, + network_info=[], disk_info={}, migrate_data={}) + def test_get_instance_disk_info_works_correctly(self): # Test data instance = objects.Instance(**self.test_instance) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 00420391ec57..1d8ffd1b9236 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -5442,6 +5442,18 @@ class LibvirtDriver(driver.ComputeDriver): CONF.libvirt.virt_type, image_meta, vol) self._connect_volume(connection_info, disk_info) + if is_block_migration and len(block_device_mapping): + # NOTE(stpierre): if this instance has mapped volumes, + # we can't do a block migration, since that will + # result in volumes being copied from themselves to + # themselves, which is a recipe for disaster. + LOG.error( + _LE('Cannot block migrate instance %s with mapped volumes') % + instance.uuid) + raise exception.MigrationError( + _('Cannot block migrate instance %s with mapped volumes') % + instance.uuid) + # We call plug_vifs before the compute manager calls # ensure_filtering_rules_for_instance, to ensure bridge is set up # Retry operation is necessary because continuously request comes,