Merge "allow live migration in case of a booted from volume instance"

This commit is contained in:
Jenkins 2015-08-06 05:55:52 +00:00 committed by Gerrit Code Review
commit 70165ed7dc
2 changed files with 52 additions and 4 deletions

View File

@ -5459,8 +5459,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',
@ -5475,6 +5477,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)
@ -5549,7 +5558,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}]')
@ -5559,6 +5567,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>"

View File

@ -2661,6 +2661,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
@ -5065,6 +5079,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']):
@ -5077,9 +5097,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