Skip to content

Commit 9f961b7

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "manager: Reduce unnecessary calls"
2 parents f810b41 + 2b3fe47 commit 9f961b7

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed

nova/compute/manager.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,6 +3009,7 @@ def _shutdown_instance(self, context, instance,
30093009
self._try_deallocate_network(context, instance, requested_networks)
30103010

30113011
timer.restart()
3012+
connector = None
30123013
for bdm in vol_bdms:
30133014
try:
30143015
if bdm.attachment_id:
@@ -3017,7 +3018,8 @@ def _shutdown_instance(self, context, instance,
30173018
else:
30183019
# NOTE(vish): actual driver detach done in driver.destroy,
30193020
# so just tell cinder that we are done with it.
3020-
connector = self.driver.get_volume_connector(instance)
3021+
if connector is None:
3022+
connector = self.driver.get_volume_connector(instance)
30213023
self.volume_api.terminate_connection(context,
30223024
bdm.volume_id,
30233025
connector)
@@ -8270,7 +8272,7 @@ def pre_live_migration(self, context, instance, disk, migrate_data):
82708272
action=fields.NotificationAction.LIVE_MIGRATION_PRE,
82718273
phase=fields.NotificationPhase.START, bdms=bdms)
82728274

8273-
connector = self.driver.get_volume_connector(instance)
8275+
connector = None
82748276
try:
82758277
for bdm in bdms:
82768278
if bdm.is_volume and bdm.attachment_id is not None:
@@ -8284,6 +8286,8 @@ def pre_live_migration(self, context, instance, disk, migrate_data):
82848286
#
82858287
# Also note that attachment_update is not needed as we
82868288
# are providing the connector in the create call.
8289+
if connector is None:
8290+
connector = self.driver.get_volume_connector(instance)
82878291
attach_ref = self.volume_api.attachment_create(
82888292
context, bdm.volume_id, bdm.instance_uuid,
82898293
connector=connector, mountpoint=bdm.device_name)
@@ -8808,7 +8812,7 @@ def _post_live_migration_remove_source_vol_connections(
88088812
volumes with connection_info set for the source host
88098813
"""
88108814
# Detaching volumes.
8811-
connector = self.driver.get_volume_connector(instance)
8815+
connector = None
88128816
for bdm in source_bdms:
88138817
if bdm.is_volume:
88148818
# Detaching volumes is a call to an external API that can fail.
@@ -8828,6 +8832,9 @@ def _post_live_migration_remove_source_vol_connections(
88288832
# remove the volume connection without detaching from
88298833
# hypervisor because the instance is not running
88308834
# anymore on the current host
8835+
if connector is None:
8836+
connector = self.driver.get_volume_connector(
8837+
instance)
88318838
self.volume_api.terminate_connection(context,
88328839
bdm.volume_id,
88338840
connector)

nova/tests/unit/compute/test_compute.py

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11559,13 +11559,61 @@ def fake_volume_get(self, context, volume_id, microversion=None):
1155911559
mock_detach.assert_called_once_with(mock.ANY, uuids.volume,
1156011560
instance.uuid, None)
1156111561

11562+
@mock.patch.object(context.RequestContext, 'elevated')
11563+
@mock.patch.object(cinder.API, 'detach')
11564+
@mock.patch.object(cinder.API, 'terminate_connection')
11565+
@mock.patch.object(compute_manager.ComputeManager,
11566+
'_get_instance_block_device_info')
11567+
@mock.patch('nova.virt.fake.FakeDriver.get_volume_connector')
11568+
def test_shutdown_with_legacy_volume_detach(
11569+
self, mock_get_connector, mock_info, mock_terminate, mock_detach,
11570+
mock_elevated,
11571+
):
11572+
# test _shutdown_instance with legacy BDMs without a volume
11573+
# attachment ID
11574+
admin = context.get_admin_context()
11575+
mock_elevated.return_value = admin
11576+
instance = self._create_fake_instance_obj()
11577+
connector = 'fake-connector'
11578+
mock_get_connector.return_value = connector
11579+
11580+
vol_a_bdm = block_device_obj.BlockDeviceMapping(
11581+
instance_uuid=instance['uuid'],
11582+
source_type='volume', destination_type='volume',
11583+
delete_on_termination=False,
11584+
volume_id=uuids.volume_a_id,
11585+
attachment_id=None)
11586+
vol_b_bdm = block_device_obj.BlockDeviceMapping(
11587+
instance_uuid=instance['uuid'],
11588+
source_type='volume', destination_type='volume',
11589+
delete_on_termination=False,
11590+
volume_id=uuids.volume_b_id,
11591+
attachment_id=None)
11592+
bdms = [vol_a_bdm, vol_b_bdm]
11593+
11594+
self.compute._shutdown_instance(admin, instance, bdms)
11595+
11596+
# we should only got the connector once, regardless of the number of
11597+
# volumes
11598+
mock_get_connector.assert_called_once_with(instance)
11599+
# but we should have separate terminate and detach calls
11600+
mock_terminate.assert_has_calls([
11601+
mock.call(admin, uuids.volume_a_id, connector),
11602+
mock.call(admin, uuids.volume_b_id, connector),
11603+
])
11604+
mock_detach.assert_has_calls([
11605+
mock.call(admin, uuids.volume_a_id, instance.uuid),
11606+
mock.call(admin, uuids.volume_b_id, instance.uuid),
11607+
])
11608+
1156211609
@mock.patch.object(context.RequestContext, 'elevated')
1156311610
@mock.patch.object(cinder.API, 'attachment_delete')
1156411611
@mock.patch.object(compute_manager.ComputeManager,
1156511612
'_get_instance_block_device_info')
11566-
def test_shutdown_with_attachment_delete(self, mock_info,
11567-
mock_attach_delete,
11568-
mock_elevated):
11613+
@mock.patch('nova.virt.fake.FakeDriver.get_volume_connector')
11614+
def test_shutdown_with_attachment_delete(
11615+
self, mock_get_connector, mock_info, mock_attach_delete, mock_elevated,
11616+
):
1156911617
# test _shutdown_instance with volume bdm containing an
1157011618
# attachment id. This should use the v3 cinder api.
1157111619
admin = context.get_admin_context()
@@ -11585,14 +11633,18 @@ def test_shutdown_with_attachment_delete(self, mock_info,
1158511633
self.compute._shutdown_instance(admin, instance, bdms)
1158611634

1158711635
mock_attach_delete.assert_called_once_with(admin, attachment_id)
11636+
# we shouldn't try to get a connector for a cinder v3-style attachment
11637+
mock_get_connector.assert_not_called()
1158811638

1158911639
@mock.patch.object(compute_manager.LOG, 'debug')
1159011640
@mock.patch.object(cinder.API, 'attachment_delete')
1159111641
@mock.patch.object(compute_manager.ComputeManager,
1159211642
'_get_instance_block_device_info')
11593-
def test_shutdown_with_attachment_not_found(self, mock_info,
11594-
mock_attach_delete,
11595-
mock_debug_log):
11643+
@mock.patch('nova.virt.fake.FakeDriver.get_volume_connector')
11644+
def test_shutdown_with_attachment_not_found(
11645+
self, mock_get_connector, mock_info, mock_attach_delete,
11646+
mock_debug_log,
11647+
):
1159611648
# test _shutdown_instance with attachment_delete throwing
1159711649
# a VolumeAttachmentNotFound exception. This should not
1159811650
# cause _shutdown_instance to fail. Only a debug log
@@ -11618,6 +11670,8 @@ def test_shutdown_with_attachment_not_found(self, mock_info,
1161811670
# get last call to LOG.debug and verify correct exception is in there
1161911671
self.assertIsInstance(mock_debug_log.call_args[0][1],
1162011672
exception.VolumeAttachmentNotFound)
11673+
# we shouldn't try to get a connector for a cinder v3-style attachment
11674+
mock_get_connector.assert_not_called()
1162111675

1162211676
def test_terminate_with_volumes(self):
1162311677
# Make sure that volumes get detached during instance termination.

0 commit comments

Comments
 (0)