Libvirt: disallow live-mig for volume-backed with local disk
This patch makes libvirt raise an error if a live migration was
requested without shared storage for a volume-backed instance, if that
instance has any local disks.
The reason is that without shared storage, local disks will be
re-created on the destination node which can result in loss of data.
Change-Id: Ic96dabf6020e957309280862b325792faf44b1f5
Closes-bug: 1236356
(cherry picked from commit cf89e78a1b
)
This commit is contained in:
parent
49d60d1f13
commit
c63f4af000
|
@ -2861,6 +2861,8 @@ class LibvirtConnTestCase(test.TestCase):
|
|||
|
||||
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
|
||||
conn._check_shared_storage_test_file("file").AndReturn(False)
|
||||
self.mox.StubOutWithMock(conn, "get_instance_disk_info")
|
||||
conn.get_instance_disk_info(instance_ref['name']).AndReturn('[]')
|
||||
|
||||
self.mox.StubOutWithMock(conn, "_assert_dest_node_has_enough_disk")
|
||||
conn._assert_dest_node_has_enough_disk(
|
||||
|
@ -2881,12 +2883,32 @@ class LibvirtConnTestCase(test.TestCase):
|
|||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
|
||||
conn._check_shared_storage_test_file("file").AndReturn(False)
|
||||
self.mox.StubOutWithMock(conn, "get_instance_disk_info")
|
||||
conn.get_instance_disk_info(instance_ref['name']).AndReturn('[]')
|
||||
self.mox.ReplayAll()
|
||||
ret = conn.check_can_live_migrate_source(self.context, instance_ref,
|
||||
dest_check_data)
|
||||
self.assertTrue(type(ret) == dict)
|
||||
self.assertTrue('is_shared_storage' in ret)
|
||||
|
||||
def test_check_can_live_migrate_source_vol_backed_w_disk_raises(self):
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
dest_check_data = {"filename": "file",
|
||||
"block_migration": False,
|
||||
"disk_over_commit": False,
|
||||
"disk_available_mb": 1024,
|
||||
"is_volume_backed": True}
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
|
||||
conn._check_shared_storage_test_file("file").AndReturn(False)
|
||||
self.mox.StubOutWithMock(conn, "get_instance_disk_info")
|
||||
conn.get_instance_disk_info(instance_ref['name']).AndReturn(
|
||||
'[{"fake_disk_attr": "fake_disk_val"}]')
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(exception.InvalidSharedStorage,
|
||||
conn.check_can_live_migrate_source, self.context,
|
||||
instance_ref, dest_check_data)
|
||||
|
||||
def test_check_can_live_migrate_source_vol_backed_fails(self):
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
dest_check_data = {"filename": "file",
|
||||
|
@ -2897,6 +2919,9 @@ class LibvirtConnTestCase(test.TestCase):
|
|||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
|
||||
conn._check_shared_storage_test_file("file").AndReturn(False)
|
||||
self.mox.StubOutWithMock(conn, "get_instance_disk_info")
|
||||
conn.get_instance_disk_info(instance_ref['name']).AndReturn(
|
||||
'[{"fake_disk_attr": "fake_disk_val"}]')
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(exception.InvalidSharedStorage,
|
||||
conn.check_can_live_migrate_source, self.context,
|
||||
|
@ -2912,6 +2937,8 @@ class LibvirtConnTestCase(test.TestCase):
|
|||
|
||||
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
|
||||
conn._check_shared_storage_test_file("file").AndReturn(True)
|
||||
self.mox.StubOutWithMock(conn, "get_instance_disk_info")
|
||||
conn.get_instance_disk_info(instance_ref['name']).AndReturn('[]')
|
||||
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(exception.InvalidLocalStorage,
|
||||
|
@ -2928,6 +2955,8 @@ class LibvirtConnTestCase(test.TestCase):
|
|||
|
||||
self.mox.StubOutWithMock(conn, "_check_shared_storage_test_file")
|
||||
conn._check_shared_storage_test_file("file").AndReturn(False)
|
||||
self.mox.StubOutWithMock(conn, "get_instance_disk_info")
|
||||
conn.get_instance_disk_info(instance_ref['name']).AndReturn('[]')
|
||||
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(exception.InvalidSharedStorage,
|
||||
|
@ -2944,6 +2973,8 @@ class LibvirtConnTestCase(test.TestCase):
|
|||
self.mox.StubOutWithMock(conn, "get_instance_disk_info")
|
||||
conn.get_instance_disk_info(instance_ref["name"]).AndReturn(
|
||||
'[{"virt_disk_size":2}]')
|
||||
conn.get_instance_disk_info(instance_ref["name"]).AndReturn(
|
||||
'[{"virt_disk_size":2}]')
|
||||
|
||||
dest_check_data = {"filename": "file",
|
||||
"disk_available_mb": 0,
|
||||
|
|
|
@ -3812,6 +3812,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
filename = dest_check_data["filename"]
|
||||
block_migration = dest_check_data["block_migration"]
|
||||
is_volume_backed = dest_check_data.get('is_volume_backed', False)
|
||||
has_local_disks = bool(
|
||||
jsonutils.loads(self.get_instance_disk_info(instance['name'])))
|
||||
|
||||
shared = self._check_shared_storage_test_file(filename)
|
||||
|
||||
|
@ -3824,7 +3826,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
dest_check_data['disk_available_mb'],
|
||||
dest_check_data['disk_over_commit'])
|
||||
|
||||
elif not shared and not is_volume_backed:
|
||||
elif not shared and (not is_volume_backed or has_local_disks):
|
||||
reason = _("Live migration can not be used "
|
||||
"without shared storage.")
|
||||
raise exception.InvalidSharedStorage(reason=reason, path=source)
|
||||
|
|
Loading…
Reference in New Issue