Merge "Fallback to legacy live migration if config error"
This commit is contained in:
commit
c5d9fc5b49
@ -5624,6 +5624,61 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
|
||||
db.instance_destroy(self.context, instance_ref['uuid'])
|
||||
|
||||
@mock.patch.object(libvirt, 'VIR_DOMAIN_XML_MIGRATABLE', 8675, create=True)
|
||||
def test_live_migration_raises_unsupported_config_exception(self):
|
||||
# Tests that when migrateToURI2 fails with VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
# migrateToURI is used instead.
|
||||
|
||||
# Preparing data
|
||||
instance_ref = fake_instance.fake_instance_obj(
|
||||
self.context, **self.test_instance)
|
||||
|
||||
# Preparing mocks
|
||||
vdmock = self.mox.CreateMock(libvirt.virDomain)
|
||||
self.mox.StubOutWithMock(vdmock, 'migrateToURI2')
|
||||
self.mox.StubOutWithMock(vdmock, 'migrateToURI')
|
||||
_bandwidth = CONF.libvirt.live_migration_bandwidth
|
||||
vdmock.XMLDesc(libvirt.VIR_DOMAIN_XML_MIGRATABLE).AndReturn(
|
||||
FakeVirtDomain().XMLDesc(0))
|
||||
unsupported_config_error = libvirt.libvirtError('ERR')
|
||||
unsupported_config_error.err = (libvirt.VIR_ERR_CONFIG_UNSUPPORTED,)
|
||||
# This is the first error we hit but since the error code is
|
||||
# VIR_ERR_CONFIG_UNSUPPORTED we'll try migrateToURI.
|
||||
vdmock.migrateToURI2(CONF.libvirt.live_migration_uri % 'dest', None,
|
||||
mox.IgnoreArg(), mox.IgnoreArg(), None,
|
||||
_bandwidth).AndRaise(unsupported_config_error)
|
||||
# This is the second and final error that will actually kill the run,
|
||||
# we use TestingException to make sure it's not the same libvirtError
|
||||
# above.
|
||||
vdmock.migrateToURI(CONF.libvirt.live_migration_uri % 'dest',
|
||||
mox.IgnoreArg(), None,
|
||||
_bandwidth).AndRaise(test.TestingException('oops'))
|
||||
|
||||
def fake_lookup(instance_name):
|
||||
if instance_name == instance_ref.name:
|
||||
return vdmock
|
||||
|
||||
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
|
||||
|
||||
def fake_recover_method(context, instance, dest, block_migration):
|
||||
pass
|
||||
|
||||
graphics_listen_addrs = {'vnc': '0.0.0.0', 'spice': '127.0.0.1'}
|
||||
migrate_data = {'pre_live_migration_result':
|
||||
{'graphics_listen_addrs': graphics_listen_addrs}}
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
|
||||
self.mox.StubOutWithMock(
|
||||
conn, '_check_graphics_addresses_can_live_migrate')
|
||||
conn._check_graphics_addresses_can_live_migrate(graphics_listen_addrs)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
# start test
|
||||
self.assertRaises(test.TestingException, conn._live_migration,
|
||||
self.context, instance_ref, 'dest', post_method=None,
|
||||
recover_method=fake_recover_method,
|
||||
migrate_data=migrate_data)
|
||||
|
||||
def test_rollback_live_migration_at_destination(self):
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
with mock.patch.object(conn, "destroy") as mock_destroy:
|
||||
|
@ -5353,13 +5353,40 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
old_xml_str = dom.XMLDesc(migratable_flag)
|
||||
new_xml_str = self._correct_listen_addr(old_xml_str,
|
||||
listen_addrs)
|
||||
|
||||
dom.migrateToURI2(CONF.libvirt.live_migration_uri % dest,
|
||||
None,
|
||||
new_xml_str,
|
||||
logical_sum,
|
||||
None,
|
||||
CONF.libvirt.live_migration_bandwidth)
|
||||
try:
|
||||
dom.migrateToURI2(CONF.libvirt.live_migration_uri % dest,
|
||||
None,
|
||||
new_xml_str,
|
||||
logical_sum,
|
||||
None,
|
||||
CONF.libvirt.live_migration_bandwidth)
|
||||
except libvirt.libvirtError as ex:
|
||||
# NOTE(mriedem): There is a bug in older versions of
|
||||
# libvirt where the VIR_DOMAIN_XML_MIGRATABLE flag causes
|
||||
# virDomainDefCheckABIStability to not compare the source
|
||||
# and target domain xml's correctly for the CPU model.
|
||||
# We try to handle that error here and attempt the legacy
|
||||
# migrateToURI path, which could fail if the console
|
||||
# addresses are not correct, but in that case we have the
|
||||
# _check_graphics_addresses_can_live_migrate check in place
|
||||
# to catch it.
|
||||
# TODO(mriedem): Remove this workaround when
|
||||
# Red Hat BZ #1141838 is closed.
|
||||
error_code = ex.get_error_code()
|
||||
if error_code == libvirt.VIR_ERR_CONFIG_UNSUPPORTED:
|
||||
LOG.warn(_LW('An error occurred trying to live '
|
||||
'migrate. Falling back to legacy live '
|
||||
'migrate flow. Error: %s'), ex,
|
||||
instance=instance)
|
||||
self._check_graphics_addresses_can_live_migrate(
|
||||
listen_addrs)
|
||||
dom.migrateToURI(
|
||||
CONF.libvirt.live_migration_uri % dest,
|
||||
logical_sum,
|
||||
None,
|
||||
CONF.libvirt.live_migration_bandwidth)
|
||||
else:
|
||||
raise
|
||||
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
Loading…
Reference in New Issue
Block a user