allow live migration in case of a booted from volume instance
A BadRequest error always occurr in case of a non shared storage environment even if the instance is booted from volume. We should allow user to execute live migration in case of a booted from volume instance. Closes-Bug: #1469006 Change-Id: I7989128d5bfa027c8f566c9d66956b1c4d328db5
This commit is contained in:
parent
91f8cc9c15
commit
177e9ff722
|
@ -5373,8 +5373,10 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
def _mock_can_live_migrate_source(self, block_migration=False,
|
||||
is_shared_block_storage=False,
|
||||
is_shared_instance_path=False,
|
||||
is_booted_from_volume=False,
|
||||
disk_available_mb=1024,
|
||||
block_device_info=None):
|
||||
block_device_info=None,
|
||||
block_device_text=None):
|
||||
instance = objects.Instance(**self.test_instance)
|
||||
dest_check_data = {'filename': 'file',
|
||||
'image_type': 'default',
|
||||
|
@ -5389,6 +5391,13 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
self.mox.StubOutWithMock(drvr, '_check_shared_storage_test_file')
|
||||
drvr._check_shared_storage_test_file('file').AndReturn(
|
||||
is_shared_instance_path)
|
||||
self.mox.StubOutWithMock(drvr, "get_instance_disk_info")
|
||||
drvr.get_instance_disk_info(instance,
|
||||
block_device_info=block_device_info).\
|
||||
AndReturn(block_device_text)
|
||||
self.mox.StubOutWithMock(drvr, '_is_booted_from_volume')
|
||||
drvr._is_booted_from_volume(instance, block_device_text).AndReturn(
|
||||
is_booted_from_volume)
|
||||
|
||||
return (instance, dest_check_data, drvr)
|
||||
|
||||
|
@ -5463,7 +5472,6 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
block_migration=True,
|
||||
disk_available_mb=0)
|
||||
|
||||
self.mox.StubOutWithMock(drvr, "get_instance_disk_info")
|
||||
drvr.get_instance_disk_info(instance,
|
||||
block_device_info=None).AndReturn(
|
||||
'[{"virt_disk_size":2}]')
|
||||
|
@ -5473,6 +5481,23 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
|||
drvr.check_can_live_migrate_source,
|
||||
self.context, instance, dest_check_data)
|
||||
|
||||
def test_check_can_live_migrate_source_booted_from_volume(self):
|
||||
instance, dest_check_data, drvr = self._mock_can_live_migrate_source(
|
||||
is_booted_from_volume=True,
|
||||
block_device_text='[]')
|
||||
self.mox.ReplayAll()
|
||||
drvr.check_can_live_migrate_source(self.context, instance,
|
||||
dest_check_data)
|
||||
|
||||
def test_check_can_live_migrate_source_booted_from_volume_with_swap(self):
|
||||
instance, dest_check_data, drvr = self._mock_can_live_migrate_source(
|
||||
is_booted_from_volume=True,
|
||||
block_device_text='[{"path":"disk.swap"}]')
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(exception.InvalidSharedStorage,
|
||||
drvr.check_can_live_migrate_source,
|
||||
self.context, instance, dest_check_data)
|
||||
|
||||
def _is_shared_block_storage_test_create_mocks(self, disks):
|
||||
# Test data
|
||||
instance_xml = ("<domain type='kvm'><name>instance-0000000a</name>"
|
||||
|
|
|
@ -2630,6 +2630,20 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
return ((not bool(instance.get('image_ref')))
|
||||
or 'disk' not in disk_mapping)
|
||||
|
||||
@staticmethod
|
||||
def _has_local_disk(instance, disk_mapping):
|
||||
"""Determines whether the VM has a local disk
|
||||
|
||||
Determines whether the disk mapping indicates that the VM
|
||||
has a local disk (e.g. ephemeral, swap disk and config-drive).
|
||||
"""
|
||||
if disk_mapping:
|
||||
if ('disk.local' in disk_mapping or
|
||||
'disk.swap' in disk_mapping or
|
||||
'disk.config' in disk_mapping):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _inject_data(self, instance, network_info, admin_pass, files, suffix):
|
||||
"""Injects data in a disk image
|
||||
|
||||
|
@ -5034,6 +5048,12 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
self._is_shared_block_storage(instance, dest_check_data,
|
||||
block_device_info)})
|
||||
|
||||
disk_info_text = self.get_instance_disk_info(
|
||||
instance, block_device_info=block_device_info)
|
||||
booted_from_volume = self._is_booted_from_volume(instance,
|
||||
disk_info_text)
|
||||
has_local_disk = self._has_local_disk(instance, disk_info_text)
|
||||
|
||||
if dest_check_data['block_migration']:
|
||||
if (dest_check_data['is_shared_block_storage'] or
|
||||
dest_check_data['is_shared_instance_path']):
|
||||
|
@ -5046,9 +5066,12 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
block_device_info)
|
||||
|
||||
elif not (dest_check_data['is_shared_block_storage'] or
|
||||
dest_check_data['is_shared_instance_path']):
|
||||
dest_check_data['is_shared_instance_path'] or
|
||||
(booted_from_volume and not has_local_disk)):
|
||||
reason = _("Live migration can not be used "
|
||||
"without shared storage.")
|
||||
"without shared storage except "
|
||||
"a booted from volume VM which "
|
||||
"does not have a local disk.")
|
||||
raise exception.InvalidSharedStorage(reason=reason, path=source)
|
||||
|
||||
# NOTE(mikal): include the instance directory name here because it
|
||||
|
|
Loading…
Reference in New Issue