Merge "libvirt: Ignore volume exceptions during post_live_migration"
This commit is contained in:
commit
c067962ad7
@ -13631,6 +13631,33 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
_test()
|
_test()
|
||||||
|
|
||||||
|
@mock.patch.object(libvirt_driver.LibvirtDriver, '_disconnect_volume')
|
||||||
|
@mock.patch.object(driver, 'block_device_info_get_mapping')
|
||||||
|
def test_post_live_migration_exception_swallowed(self, mock_get_bdm,
|
||||||
|
mock_disconnect_volume):
|
||||||
|
vol_1_conn_info = {'data': {'volume_id': uuids.vol_1_id}}
|
||||||
|
vol_2_conn_info = {'data': {'volume_id': uuids.vol_2_id}}
|
||||||
|
mock_get_bdm.return_value = [{'connection_info': vol_1_conn_info},
|
||||||
|
{'connection_info': vol_2_conn_info}]
|
||||||
|
|
||||||
|
# Raise an exception with the first call to disconnect_volume
|
||||||
|
mock_disconnect_volume.side_effect = [test.TestingException, None]
|
||||||
|
|
||||||
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||||
|
drvr.post_live_migration(mock.sentinel.ctxt, mock.sentinel.instance,
|
||||||
|
mock.sentinel.bdi)
|
||||||
|
|
||||||
|
# Assert disconnect_volume is called twice despite the exception
|
||||||
|
mock_disconnect_volume.assert_has_calls([
|
||||||
|
mock.call(mock.sentinel.ctxt, vol_1_conn_info,
|
||||||
|
mock.sentinel.instance),
|
||||||
|
mock.call(mock.sentinel.ctxt, vol_2_conn_info,
|
||||||
|
mock.sentinel.instance)])
|
||||||
|
|
||||||
|
# Assert that we log the failure to disconnect the first volume
|
||||||
|
self.assertIn("Ignoring exception while attempting to disconnect "
|
||||||
|
"volume %s" % uuids.vol_1_id, self.stdlog.logger.output)
|
||||||
|
|
||||||
@mock.patch('os.stat')
|
@mock.patch('os.stat')
|
||||||
@mock.patch('os.path.getsize')
|
@mock.patch('os.path.getsize')
|
||||||
@mock.patch('nova.virt.disk.api.get_disk_info')
|
@mock.patch('nova.virt.disk.api.get_disk_info')
|
||||||
|
@ -9335,15 +9335,25 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||||||
|
|
||||||
def post_live_migration(self, context, instance, block_device_info,
|
def post_live_migration(self, context, instance, block_device_info,
|
||||||
migrate_data=None):
|
migrate_data=None):
|
||||||
# Disconnect from volume server
|
# NOTE(mdbooth): The block_device_info we were passed was initialized
|
||||||
|
# with BDMs from the source host before they were updated to point to
|
||||||
|
# the destination. We can safely use this to disconnect the source
|
||||||
|
# without re-fetching.
|
||||||
block_device_mapping = driver.block_device_info_get_mapping(
|
block_device_mapping = driver.block_device_info_get_mapping(
|
||||||
block_device_info)
|
block_device_info)
|
||||||
|
|
||||||
for vol in block_device_mapping:
|
for vol in block_device_mapping:
|
||||||
# NOTE(mdbooth): The block_device_info we were passed was
|
connection_info = vol['connection_info']
|
||||||
# initialized with BDMs from the source host before they were
|
# NOTE(lyarwood): Ignore exceptions here to avoid the instance
|
||||||
# updated to point to the destination. We can safely use this to
|
# being left in an ERROR state and still marked on the source.
|
||||||
# disconnect the source without re-fetching.
|
try:
|
||||||
self._disconnect_volume(context, vol['connection_info'], instance)
|
self._disconnect_volume(context, connection_info, instance)
|
||||||
|
except Exception as ex:
|
||||||
|
volume_id = driver_block_device.get_volume_id(connection_info)
|
||||||
|
LOG.exception("Ignoring exception while attempting to "
|
||||||
|
"disconnect volume %s from the source host "
|
||||||
|
"during post_live_migration", volume_id,
|
||||||
|
instance=instance)
|
||||||
|
|
||||||
def post_live_migration_at_source(self, context, instance, network_info):
|
def post_live_migration_at_source(self, context, instance, network_info):
|
||||||
"""Unplug VIFs from networks at source.
|
"""Unplug VIFs from networks at source.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user