compute: Ensure updates to bdms during pre_live_migration are saved

When connecting volumes to the underlying host the virt drivers can
attempt to stash additional metadata returned from os-brick into the
connection_info associated with a bdm. This pretty janky behaviour
relies on someone later calling .save() against the underlying
BlockDeviceMapping object to persist these changes into the database as
happens in the driver block device layer during a standard volume
attach.

However during pre_live_migration no call was made to .save() resulting
in the changes made to the connection_info being lost. This change
simply introduces this call at the end of the pre_live_migration method
on the destination via the driver bdm objects we provide in
block_device_info.

Closes-Bug: #1939545
Change-Id: Iea8896682fc28e3a5cd25afa45238272bee745e1
(cherry picked from commit 962eda94d5)
This commit is contained in:
Lee Yarwood
2021-08-11 12:04:11 +01:00
committed by Artom Lifshitz
parent 9f7b81c4cf
commit 9bccc5a043
3 changed files with 18 additions and 3 deletions

View File

@@ -8214,6 +8214,14 @@ class ComputeManager(manager.Manager):
self.network_api.setup_networks_on_host(context, instance,
self.host)
# NOTE(lyarwood): The above call to driver.pre_live_migration
# can result in the virt drivers attempting to stash additional
# metadata into the connection_info of the underlying bdm.
# Ensure this is saved to the database by calling .save() against
# the driver BDMs we passed down via block_device_info.
for driver_bdm in block_device_info['block_device_mapping']:
driver_bdm.save()
except Exception:
# If we raise, migrate_data with the updated attachment ids
# will not be returned to the source host for rollback.

View File

@@ -103,9 +103,9 @@ class TestLiveMigrateUpdateDevicePath(
# Live migrate the instance to another host
self._live_migrate(self.server)
# FIXME(lyarwood): This is bug #1939545, again get the volume bdm and
# assert that the saved connection_info doesn't contain device_path.
# Again get the volume bdm and assert that the saved connection_info
# contains device_path.
bdm = objects.BlockDeviceMapping.get_by_volume_and_instance(
ctxt, volume_id, self.server['id'])
connection_info = jsonutils.loads(bdm.connection_info)
self.assertNotIn('device_path', connection_info.get('data'))
self.assertIn('device_path', connection_info.get('data'))

View File

@@ -9220,6 +9220,10 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase,
mock_gibdi, mock_plm, mock_nwapi, mock_notify,
mock_bdm_save, mock_attach_complete, mock_notify_about_inst):
mock_driver_bdm = mock.Mock(spec=driver_bdm_volume)
mock_gibdi.return_value = {
'block_device_mapping': [mock_driver_bdm]}
mock_get_bdms.return_value = [vol_bdm, image_bdm]
mock_attach.return_value = {'id': new_attachment_id}
mock_plm.return_value = migrate_data
@@ -9244,7 +9248,10 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase,
self.assertEqual(vol_bdm.attachment_id, new_attachment_id)
self.assertEqual(migrate_data.old_vol_attachment_ids[volume_id],
orig_attachment_id)
# Initially save of the attachment_id
mock_bdm_save.assert_called_once_with()
# Later save via the driver bdm for connection_info updates etc.
mock_driver_bdm.save.assert_called_once_with()
mock_attach_complete.assert_called_once_with(self.context,
new_attachment_id)