From c05d12875fb989fc786b3c91a1ea1ce722d0f382 Mon Sep 17 00:00:00 2001 From: Nilesh Thathagar Date: Wed, 9 Oct 2024 08:26:24 +0000 Subject: [PATCH] Dell PowerMax: Added exception handling after the masking view REST call. Added exception handling after the masking view REST call to retry fetching the host lunid if it is not returned by the REST call Updated the retry count based on trial and error. The maximum observed retries reached the 8th attempt, so we have set it to 8 retries. Closes-Bug: #2081742 Change-Id: I9e8e5f38c8ab8804c5e7ae4ad5e0f650768e93c3 --- .../dell_emc/powermax/test_powermax_rest.py | 15 +++---- .../volume/drivers/dell_emc/powermax/rest.py | 42 ++++++++++++------- ...x-rest-api-hostlunid-ee22d0105c990ea0.yaml | 8 ++++ 3 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 releasenotes/notes/bug-2081742-dell-powermax-rest-api-hostlunid-ee22d0105c990ea0.yaml diff --git a/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_rest.py b/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_rest.py index 583848770af..49540fd2433 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_rest.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_rest.py @@ -869,10 +869,10 @@ class PowerMaxRestTest(test.TestCase): def test_find_mv_connections_for_vol_missing_host_lun_address(self): with mock.patch.object(self.rest, 'get_resource', return_value=self.data.maskingview_no_lun): - host_lun_id = self.rest.find_mv_connections_for_vol( - self.data.array, self.data.masking_view_name_f, - self.data.device_id) - self.assertIsNone(host_lun_id) + self.assertRaises(exception.VolumeBackendAPIException, + self.rest.find_mv_connections_for_vol, + self.data.array, self.data.masking_view_name_f, + self.data.device_id) def test_find_mv_connections_for_vol_failed(self): # no masking view info retrieved @@ -883,9 +883,10 @@ class PowerMaxRestTest(test.TestCase): # no connection info received with mock.patch.object(self.rest, 'get_resource', return_value={'no_conn': 'no_info'}): - host_lun_id2 = self.rest.find_mv_connections_for_vol( - self.data.array, self.data.masking_view_name_f, device_id) - self.assertIsNone(host_lun_id2) + self.assertRaises(exception.VolumeBackendAPIException, + self.rest.find_mv_connections_for_vol, + self.data.array, self.data.masking_view_name_f, + self.data.device_id) def test_get_storage_groups_from_volume(self): array = self.data.array diff --git a/cinder/volume/drivers/dell_emc/powermax/rest.py b/cinder/volume/drivers/dell_emc/powermax/rest.py index 96767063820..e47d233c8af 100644 --- a/cinder/volume/drivers/dell_emc/powermax/rest.py +++ b/cinder/volume/drivers/dell_emc/powermax/rest.py @@ -1621,7 +1621,7 @@ class PowerMaxRest(object): self.delete_resource(array, SLOPROVISIONING, "volume", device_id) - @retry(retry_exc_tuple, interval=2, retries=3) + @retry(retry_exc_tuple, interval=2, retries=8) def find_mv_connections_for_vol(self, array, maskingview, device_id): """Find the host_lun_id for a volume in a masking view. @@ -1644,28 +1644,42 @@ class PowerMaxRest(object): try: masking_view_conn = connection_info.get( 'maskingViewConnection') - if masking_view_conn and isinstance( - masking_view_conn, list): + if (masking_view_conn and isinstance( + masking_view_conn, list) and + len(masking_view_conn) > 0): host_lun_id = masking_view_conn[0].get( 'host_lun_address') if host_lun_id: host_lun_id = int(host_lun_id, 16) else: - exception_message = ( - _('Unable to get host_lun_address for ' - 'device %(dev)s on masking view %(mv)s. ' - 'Retrying...') - % {'dev': device_id, 'mv': maskingview}) + exception_message = (_("Unable to get " + "host_lun_address for device " + "%(dev)s on masking view " + "%(mv)s. Retrying...") + % {"dev": device_id, + "mv": maskingview}) LOG.warning(exception_message) raise exception.VolumeBackendAPIException( message=exception_message) + else: + exception_message = (_("Unable to retrieve connection " + "information for volume %(vol)s " + "in masking view %(mv)s. " + "Retrying...") + % {"vol": device_id, + "mv": maskingview}) + LOG.warning(exception_message) + raise exception.VolumeBackendAPIException( + message=exception_message) except Exception as e: - exception_message = ( - _("Unable to retrieve connection information " - "for volume %(vol)s in masking view %(mv)s. " - "Exception received: %(e)s. Retrying...") - % {'vol': device_id, 'mv': maskingview, - 'e': e}) + exception_message = (_("Unable to retrieve connection " + "information for volume %(vol)s " + "in masking view %(mv)s. " + "Exception received: %(e)s. " + "Retrying...") + % {"vol": device_id, + "mv": maskingview, + "e": e}) LOG.warning(exception_message) raise exception.VolumeBackendAPIException( message=exception_message) diff --git a/releasenotes/notes/bug-2081742-dell-powermax-rest-api-hostlunid-ee22d0105c990ea0.yaml b/releasenotes/notes/bug-2081742-dell-powermax-rest-api-hostlunid-ee22d0105c990ea0.yaml new file mode 100644 index 00000000000..686400f9ead --- /dev/null +++ b/releasenotes/notes/bug-2081742-dell-powermax-rest-api-hostlunid-ee22d0105c990ea0.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Dell PowerMax Driver `bug #2081742 + `_: The REST + API calls for the masking view connection do not return + the HostLUN ID immediately. To address this, an exception + has been added to implement a retry mechanism.