From 07dd49babecf9585dca464525f8577850a1124a2 Mon Sep 17 00:00:00 2001 From: inori Date: Thu, 19 Oct 2023 21:33:53 -0400 Subject: [PATCH] Fujitsu driver: Improve volume deletion To improve the volume deletion process, add a step to check associated copy sessions. Additionally, it also improves the process of retrieving storage-managed volume numbers. There was a problem where the volume could not be deleted because the copy session information acquired by SMI-S IF from ETERNUS DX Storage, which was cached and did not reflect the information that had just been executed. This problem has been addressed through improvements in information retrieval. Change-Id: I21d5c1fa4f13e688a5f73535c8d6fdec613adc03 --- .../unit/volume/drivers/test_fujitsu_dx.py | 104 +++++++++++++- .../fujitsu/eternus_dx/eternus_dx_cli.py | 92 ++++++++++++ .../fujitsu/eternus_dx/eternus_dx_common.py | 132 ++++++++++++++---- .../fujitsu/eternus_dx/eternus_dx_fc.py | 6 + .../fujitsu/eternus_dx/eternus_dx_iscsi.py | 6 + ...mprove-delete-volume-8fa509f0424deb8e.yaml | 15 ++ 6 files changed, 324 insertions(+), 31 deletions(-) create mode 100644 releasenotes/notes/fujitsu-improve-delete-volume-8fa509f0424deb8e.yaml diff --git a/cinder/tests/unit/volume/drivers/test_fujitsu_dx.py b/cinder/tests/unit/volume/drivers/test_fujitsu_dx.py index c43ac09c87d..56d52bd486a 100644 --- a/cinder/tests/unit/volume/drivers/test_fujitsu_dx.py +++ b/cinder/tests/unit/volume/drivers/test_fujitsu_dx.py @@ -175,7 +175,7 @@ FAKE_POOLS = [{ }] FAKE_STATS = { - 'driver_version': '1.4.1', + 'driver_version': '1.4.2', 'storage_protocol': 'iSCSI', 'vendor_name': 'FUJITSU', 'QoS_support': True, @@ -185,7 +185,7 @@ FAKE_STATS = { 'pools': FAKE_POOLS, } FAKE_STATS2 = { - 'driver_version': '1.4.1', + 'driver_version': '1.4.2', 'storage_protocol': 'FC', 'vendor_name': 'FUJITSU', 'QoS_support': True, @@ -375,8 +375,11 @@ class FakeCIMInstanceName(dict): snaps = FakeCIMInstanceName() snaps['ElementName'] = 'FJosv_OgEZj1mSvKRvIKOExKktlg==' snaps['Name'] = None + snaps['DeviceID'] = FAKE_LUN_ID2 + snaps['SystemName'] = STORAGE_SYSTEM ret.append(snaps) snaps.path = '' + snaps.classname = 'FUJITSU_StorageVolume' map = FakeCIMInstanceName() map['ElementName'] = 'FJosv_hhJsV9lcMBvAPADrGqucwg==' @@ -1037,6 +1040,16 @@ class FJFCDriverTestCase(test.TestCase): '0002\t\r\n0000\tFJosv_0qJ4rpOHgFE8ipcJOMfBmg==\t0F' '\t\r\n0001\tFJosv_OgEZj1mSvKRvIKOExKktlg==\t0D' '\t\r\nCLI> ' % exec_cmdline) + elif exec_cmdline.startswith('show copy-sessions'): + ret = ('\r\nCLI> %s\r\n00\r\n0001\t\r\n' + '0001\tFFFF\t01\t08\tFF\tFF\t03\t02\tFF\tFF\t05ABD7D2\t' + '########################################\t' + '########################################\t' + '00000281\t00000286\t0001\t00\tFF\t0000000000000800\t' + '0000000000000000\t0000000000000100\t0000000000000800\t' + '04\t00\t00000000\t2020101009341400\t01\t10\tFFFF\tFFFF\t' + '0000000000000000\tFFFFFFFFFFFFFFFF\tFFFFFFFFFFFFFFFF\tFF\t' + 'FF\t64\t00\t07\t00\t00\t00\r\nCLI> ' % exec_cmdline) elif exec_cmdline.startswith('show qos-bandwidth-limit'): ret = ('\r\nCLI> %s\r\n00\r\n0010\t\r\n00\t0000ffff\t0000ffff' '\t0000ffff\t0000ffff\t0000ffff\t0000ffff\t0000ffff' @@ -1080,6 +1093,8 @@ class FJFCDriverTestCase(test.TestCase): '\r\nCLI> ' % exec_cmdline) elif exec_cmdline.startswith('set qos-bandwidth-limit'): ret = '%s\r\n00\r\n0001\r\nCLI> ' % exec_cmdline + elif exec_cmdline.startswith('stop copy-session'): + ret = '%s\r\n00\r\nCLI> ' % exec_cmdline else: ret = None return ret @@ -1284,6 +1299,16 @@ class FJISCSIDriverTestCase(test.TestCase): '0002\t\r\n0000\tFJosv_0qJ4rpOHgFE8ipcJOMfBmg==\t0F' '\t\r\n0001\tFJosv_OgEZj1mSvKRvIKOExKktlg==\t0D' '\t\r\nCLI> ' % exec_cmdline) + elif exec_cmdline.startswith('show copy-sessions'): + ret = ('\r\nCLI> %s\r\n00\r\n0001\t\r\n' + '0001\tFFFF\t01\t08\tFF\tFF\t03\t02\tFF\tFF\t05ABD7D2\t' + '########################################\t' + '########################################\t' + '00000281\t00000286\t0001\t00\tFF\t0000000000000800\t' + '0000000000000000\t0000000000000100\t0000000000000800\t' + '04\t00\t00000000\t2020101009341400\t01\t10\tFFFF\tFFFF\t' + '0000000000000000\tFFFFFFFFFFFFFFFF\tFFFFFFFFFFFFFFFF\tFF\t' + 'FF\t64\t00\t07\t00\t00\t00\r\nCLI> ' % exec_cmdline) elif exec_cmdline.startswith('show qos-bandwidth-limit'): ret = ('\r\nCLI> %s\r\n00\r\n0010\t\r\n00\t0000ffff\t0000ffff' '\t0000ffff\t0000ffff\t0000ffff\t0000ffff\t0000ffff' @@ -1515,6 +1540,16 @@ class FJCLITestCase(test.TestCase): ret = ('\r\nCLI> %s\r\n00\r\n' '0001\r\n0000\tFJosv_0qJ4rpOHgFE8ipcJOMfBmg==\t01\t00\t00' '\r\nCLI> ' % exec_cmdline) + elif exec_cmdline.startswith('show copy-sessions'): + ret = ('\r\nCLI> %s\r\n00\r\n0001\t\r\n' + '0001\tFFFF\t01\t08\tFF\tFF\t03\t02\tFF\tFF\t05ABD7D2\t' + '########################################\t' + '########################################\t' + '00000281\t00000286\t0001\t00\tFF\t0000000000000800\t' + '0000000000000000\t0000000000000100\t0000000000000800\t' + '04\t00\t00000000\t2020101009341400\t01\t10\tFFFF\tFFFF\t' + '0000000000000000\tFFFFFFFFFFFFFFFF\tFFFFFFFFFFFFFFFF\tFF\t' + 'FF\t64\t00\t07\t00\t00\t00\r\nCLI> ' % exec_cmdline) elif exec_cmdline.startswith('show qos-bandwidth-limit'): ret = ('\r\nCLI> %s\r\n00\r\n0001\t\r\n00\t0000ffff\t0000ffff' '\t0000ffff\t0000ffff\t0000ffff\t0000ffff\t0000ffff' @@ -1522,6 +1557,8 @@ class FJCLITestCase(test.TestCase): 'CLI> ' % exec_cmdline) elif exec_cmdline.startswith('set qos-bandwidth-limit'): ret = '%s\r\n00\r\n0001\r\nCLI> ' % exec_cmdline + elif exec_cmdline.startswith('stop copy-session'): + ret = '%s\r\n00\r\nCLI> ' % exec_cmdline elif exec_cmdline.startswith('delete volume'): ret = '%s\r\n00\r\nCLI> ' % exec_cmdline else: @@ -1608,6 +1645,21 @@ class FJCLITestCase(test.TestCase): volume_number = self.cli._set_volume_qos(**FAKE_QOS_OPTION) self.assertEqual(FAKE_QOS_OUTPUT, volume_number) + def test_show_copy_sessions(self): + FAKE_COPY_SESSION = [{ + 'Source Num': 641, + 'Dest Num': 646, + 'Type': 'Snap', + 'Status': 'Active', + 'Phase': 'Tracking', + 'Session ID': 1, + }] + FAKE_COPY_SESSION_OUTPUT = {**FAKE_CLI_OUTPUT, + 'message': FAKE_COPY_SESSION} + + cpdatalist = self.cli._show_copy_sessions() + self.assertEqual(FAKE_COPY_SESSION_OUTPUT, cpdatalist) + def test_show_pool_provision(self): FAKE_POOL_PROVIOSN_OPTION = self.create_fake_options( pool_name='abcd1234_TPP') @@ -1666,6 +1718,15 @@ class FJCLITestCase(test.TestCase): versioninfo = self.cli._show_enclosure_status() self.assertEqual(FAKE_VERSION_INFO, versioninfo) + def test_stop_copy_session(self): + FAKE_SESSION_ID = '0001' + FAKE_STOP_OUTPUT = {**FAKE_CLI_OUTPUT, 'message': []} + FAKE_STOP_COPY_SESSION_OPTION = self.create_fake_options( + session_id=FAKE_SESSION_ID) + stop_output = self.cli._stop_copy_session( + **FAKE_STOP_COPY_SESSION_OPTION) + self.assertEqual(FAKE_STOP_OUTPUT, stop_output) + def test_delete_volume(self): FAKE_VOLUME_NAME = 'FJosv_0qJ4rpOHgFE8ipcJOMfBmg==' FAKE_DELETE_OUTPUT = {**FAKE_CLI_OUTPUT, 'message': []} @@ -1746,13 +1807,25 @@ class FJCommonTestCase(test.TestCase): ret = ('\r\nCLI> %s\r\n00\r\n' '0001\r\n0000\tFJosv_0qJ4rpOHgFE8ipcJOMfBmg==\t01\t00\t00' '\r\nCLI> ' % exec_cmdline) + elif exec_cmdline.startswith('show copy-sessions'): + ret = ('\r\nCLI> %s\r\n00\r\n0001\t\r\n' + '0001\tFFFF\t01\t08\tFF\tFF\t03\t02\tFF\tFF\t05ABD7D2\t' + '########################################\t' + '########################################\t' + '00000281\t00000286\t0001\t00\tFF\t0000000000000800\t' + '0000000000000000\t0000000000000100\t0000000000000800\t' + '04\t00\t00000000\t2020101009341400\t01\t10\tFFFF\tFFFF\t' + '0000000000000000\tFFFFFFFFFFFFFFFF\tFFFFFFFFFFFFFFFF\tFF\t' + 'FF\t64\t00\t07\t00\t00\t00\r\nCLI> ' % exec_cmdline) elif exec_cmdline.startswith('show qos-bandwidth-limit'): ret = ('\r\nCLI> %s\r\n00\r\n0001\t\r\n00\t0000ffff\t0000ffff' '\t0000ffff\t0000ffff\t0000ffff\t0000ffff\t0000ffff' '\t0000ffff\t0000ffff\t0000ffff\t0000ffff\t0000ffff\r\n' 'CLI> ' % exec_cmdline) elif exec_cmdline.startswith('set qos-bandwidth-limit'): - ret = '\r\nCLI> %s\r\n00\r\n0001\r\nCLI> ' % exec_cmdline + ret = '%s\r\n00\r\n0001\r\nCLI> ' % exec_cmdline + elif exec_cmdline.startswith('stop copy-session'): + ret = '%s\r\n00\r\nCLI> ' % exec_cmdline else: ret = None return ret @@ -1764,6 +1837,19 @@ class FJCommonTestCase(test.TestCase): conn = FakeEternusConnection() return conn + def test_get_volume_number(self): + vol_instance = FakeCIMInstanceName() + vol_instance['ElementName'] = 'FJosv_0qJ4rpOHgFE8ipcJOMfBmg==' + vol_instance['Purpose'] = '00228+0x06' + vol_instance['Name'] = None + vol_instance['DeviceID'] = FAKE_LUN_ID1 + vol_instance['SystemName'] = STORAGE_SYSTEM + vol_instance.path = '' + vol_instance.classname = 'FUJITSU_StorageVolume' + + volume_no = self.driver.common._get_volume_number(vol_instance) + self.assertEqual(FAKE_LUN_NO1, volume_no) + def test_get_eternus_model(self): ETERNUS_MODEL = self.driver.common._get_eternus_model() self.assertEqual(3, ETERNUS_MODEL) @@ -1846,3 +1932,15 @@ class FJCommonTestCase(test.TestCase): self.driver.common._set_limit(FAKE_MODE, FAKE_LIMIT, FAKE_IOPS, FAKE_THROUGHOUTPUT) mock_exec_cli_with_eternus.assert_called_with(exec_cmdline) + + def test_get_copy_sessions_list(self): + FAKE_COPY_SESSION = [{ + 'Source Num': 641, + 'Dest Num': 646, + 'Type': 'Snap', + 'Status': 'Active', + 'Phase': 'Tracking', + 'Session ID': 1, + }] + copy_session_list = self.driver.common._get_copy_sessions_list() + self.assertEqual(FAKE_COPY_SESSION, copy_session_list) diff --git a/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_cli.py b/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_cli.py index 1e9ccc982ce..e4f0c82adb2 100644 --- a/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_cli.py +++ b/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_cli.py @@ -50,8 +50,10 @@ class FJDXCLI(object): 'show_qos_bandwidth_limit': self._show_qos_bandwidth_limit, 'set_qos_bandwidth_limit': self._set_qos_bandwidth_limit, 'set_volume_qos': self._set_volume_qos, + 'show_copy_sessions': self._show_copy_sessions, 'show_volume_qos': self._show_volume_qos, 'show_enclosure_status': self._show_enclosure_status, + 'stop_copy_session': self._stop_copy_session, 'delete_volume': self._delete_volume } @@ -276,6 +278,92 @@ class FJDXCLI(object): return output + def _show_copy_sessions(self, **option): + """Get copy sessions.""" + try: + output = self._exec_cli("show copy-sessions", **option) + + # return error + rc = output['rc'] + + if rc != "0": + return output + + cpsdatalist = [] + clidatalist = output.get('message') + + for clidataline in clidatalist[1:]: + clidata = clidataline.split('\t') + # Get CopyType + if clidata[2] == '01': + # CopyKind: OPC + if bin(int(clidata[3], 16) & 16) != 0: + # eg. 0b10010000 + temp_type = 'Snap' + elif bin(int(clidata[3], 16) & 64) != 0: + # eg. 0b11000000 + temp_type = 'Snap+' + else: + temp_type = 'Other' + elif clidata[2] == '02': + # CopyKind: EC + if clidata[5] == 'FF': + temp_type = 'EC' + elif clidata[5] == '10': + temp_type = 'Sync_REC' + else: + temp_type = 'Other' + else: + temp_type = 'Other' + + # Get Phases + if clidata[6] == '00': + temp_phase = 'No_Pair' + elif clidata[6] == '01': + temp_phase = 'Copying' + elif clidata[6] == '02': + temp_phase = 'Equivalent' + elif clidata[6] == '03': + temp_phase = 'Tracking' + elif clidata[6] == '04': + temp_phase = 'Tracking_Copying' + elif clidata[6] == '06': + temp_phase = 'Readying' + else: + temp_phase = 'Other' + + # Get CopyStatus + if clidata[7] == '00': + temp_status = 'Idle' + elif clidata[7] == '01': + temp_status = 'Reserve' + elif clidata[7] == '02': + temp_status = 'Active' + elif clidata[7] == '03': + temp_status = 'Error_Suspend' + elif clidata[7] == '04': + temp_status = 'Suspend' + elif clidata[7] == '05': + temp_status = 'Halt' + else: + temp_status = 'Other' + + cpsdatalist.append({'Source Num': int(clidata[13], 16), + 'Dest Num': int(clidata[14], 16), + 'Type': temp_type, + 'Status': temp_status, + 'Phase': temp_phase, + 'Session ID': int(clidata[0], 16)}) + + output['message'] = cpsdatalist + except Exception as ex: + output = {'result': 0, + 'rc': '4', + 'message': "Show copy sessions error: %s" + % str(ex)} + + return output + def _show_qos_bandwidth_limit(self, **option): """Get qos bandwidth limit.""" clidata = None @@ -394,6 +482,10 @@ class FJDXCLI(object): return output + def _stop_copy_session(self, **option): + """Exec stop copy-session.""" + return self._exec_cli("stop copy-session", **option) + def _delete_volume(self, **option): """Exec delete volume.""" return self._exec_cli('delete volume', **option) diff --git a/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_common.py b/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_common.py index d883710b400..3acd3b28855 100644 --- a/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_common.py +++ b/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_common.py @@ -67,10 +67,11 @@ class FJDXCommon(object): 1.3.0 - Community base version 1.4.0 - Add support for QoS. 1.4.1 - Add the method for expanding RAID volumes by CLI. + 1.4.2 - Add the secondary check for copy-sessions when deleting volumes. """ - VERSION = "1.4.1" + VERSION = "1.4.2" stats = { 'driver_version': VERSION, 'storage_protocol': None, @@ -261,7 +262,7 @@ class FJDXCommon(object): 'vol_name': volumename, } - volume_no = "0x" + element['DeviceID'][24:28] + volume_no = self._get_volume_number(element) metadata = { 'FJ_Backend': systemnamelist[0]['IdentifyingNumber'], 'FJ_Volume_Name': volumename, @@ -445,36 +446,37 @@ class FJDXCommon(object): def delete_volume(self, volume): """Delete volume on ETERNUS.""" - LOG.debug('delete_volume, volume id: %s.', volume['id']) + LOG.debug('delete_volume, volume id: %(vid)s.', + {'vid': volume['id']}) - self.conn = self._get_eternus_connection() vol_exist = self._delete_volume_setting(volume) if not vol_exist: LOG.debug('delete_volume, volume not found in 1st check.') - return False + return - # Check volume existence on ETERNUS again - # because volume is deleted when SnapOPC copysession is deleted. - vol_instance = self._find_lun(volume) - if vol_instance is None: - LOG.debug('delete_volume, volume not found in 2nd check, ' - 'but no problem.') - return True - - self._delete_volume(vol_instance) - return True + try: + self._delete_volume(volume) + except Exception as ex: + msg = (_('delete_volume, ' + 'delete volume failed, ' + 'Error information: %s.') + % ex) + LOG.error(msg) + raise exception.VolumeBackendAPIException(data=msg) @lockutils.synchronized('ETERNUS-vol', 'cinder-', True) def _delete_volume_setting(self, volume): """Delete volume setting (HostAffinity, CopySession) on ETERNUS.""" - LOG.debug('_delete_volume_setting, volume id: %s.', volume['id']) + LOG.debug('_delete_volume_setting, ' + 'volume id: %(vid)s.', + {'vid': volume['id']}) # Check the existence of volume. volumename = self._get_volume_name(volume) vol_instance = self._find_lun(volume) - if vol_instance is None: + if not vol_instance: LOG.info('_delete_volume_setting, volumename:%(volumename)s, ' 'volume not found on ETERNUS.', {'volumename': volumename}) @@ -514,6 +516,33 @@ class FJDXCommon(object): for cpsession in delete_copysession_list: self._delete_copysession(cpsession) + volume_no = self._get_volume_number(vol_instance) + + cp_session_list = self._get_copy_sessions_list() + for cp in cp_session_list: + if cp['Dest Num'] != int(volume_no, 16): + continue + if cp['Type'] == 'Snap': + session_id = cp['Session ID'] + + param_dict = ({'session-id': session_id}) + rc, emsg, clidata = self._exec_eternus_cli( + 'stop_copy_session', + **param_dict) + + if rc != 0: + msg = (_('_delete_volume_setting, ' + 'stop_copy_session failed. ' + 'Return code: %(rc)lu, ' + 'Error: %(errormsg)s, ' + 'Message: %(clidata)s.') + % {'rc': rc, + 'errormsg': emsg, + 'clidata': clidata}) + LOG.error(msg) + raise exception.VolumeBackendAPIException(data=msg) + break + LOG.debug('_delete_volume_setting, ' 'wait_cpsession: %(wait_cpsession)s, ' 'delete_cpsession: %(delete_cpsession)s, complete.', @@ -522,15 +551,22 @@ class FJDXCommon(object): return True @lockutils.synchronized('ETERNUS-vol', 'cinder-', True) - def _delete_volume(self, vol_instance): + def _delete_volume(self, volume): """Delete volume on ETERNUS.""" - LOG.debug('_delete_volume, volume name: %s.', - vol_instance['ElementName']) + LOG.debug('_delete_volume, volume id: %(vid)s.', + {'vid': volume['id']}) + + vol_instance = self._find_lun(volume) + + if not vol_instance: + LOG.debug('_delete_volume, volume not found in 2nd check, ' + 'but no problem.') + return volumename = vol_instance['ElementName'] configservice = self._find_eternus_service(CONSTANTS.STOR_CONF) - if configservice is None: + if not configservice: msg = (_('_delete_volume, volumename: %(volumename)s, ' 'Storage Configuration Service not found.') % {'volumename': volumename}) @@ -698,7 +734,7 @@ class FJDXCommon(object): 'vol_name': d_volumename, } - sdv_no = "0x" + element['DeviceID'][24:28] + sdv_no = self._get_volume_number(element) metadata = {'FJ_SDV_Name': d_volumename, 'FJ_SDV_No': sdv_no, 'FJ_Pool_Name': eternus_pool} @@ -710,9 +746,7 @@ class FJDXCommon(object): 'snapshot id: %(sid)s, volume id: %(vid)s.', {'sid': snapshot['id'], 'vid': snapshot['volume_id']}) - vol_exist = self.delete_volume(snapshot) - LOG.debug('delete_snapshot, vol_exist: %s.', vol_exist) - return vol_exist + self.delete_volume(snapshot) def initialize_connection(self, volume, connector): """Allow connection to connector and return connection info.""" @@ -1421,8 +1455,7 @@ class FJDXCommon(object): 'classname: %s.', classname) try: - services = self._enum_eternus_instance_names( - str(classname)) + services = self._enum_eternus_instance_names(str(classname)) except Exception: msg = (_('_find_eternus_service, ' 'classname: %(classname)s, ' @@ -2426,7 +2459,7 @@ class FJDXCommon(object): for vol_instance in vollist: if src_id: - volume_no = "0x" + vol_instance['DeviceID'][24:28] + volume_no = self._get_volume_number(vol_instance) try: # Skip hidden tppv volumes. if int(src_id) == int(volume_no, 16): @@ -2536,6 +2569,22 @@ class FJDXCommon(object): return ret + def _get_volume_number(self, vol): + """Get volume no(return a hex string).""" + if self.model_name == CONSTANTS.DX_S2: + volume_number = "0x%04X" % int(vol['DeviceID'][-5:]) + else: + volume_number = "0x" + vol['DeviceID'][24:28] + + LOG.debug('_get_volume_number: %s.', volume_number) + return volume_number + + def _exec_eternus_smis_ReferenceNames(self, classname, + conn=None, + **param_dict): + ret = conn.ReferenceNames(classname, **param_dict) + return ret + def _check_user(self): """Check whether user's role is accessible to ETERNUS and Software.""" ret = True @@ -3131,3 +3180,30 @@ class FJDXCommon(object): 'clidata': clidata}) LOG.warning(msg) raise exception.VolumeBackendAPIException(data=msg) + + def _get_copy_sessions_list(self, **param): + """Get copy sessions list.""" + LOG.debug('_get_copy_sessions_list, Enter method.') + + rc, emsg, clidata = self._exec_eternus_cli( + 'show_copy_sessions', + **param + ) + + if rc != 0: + msg = (_('_get_copy_sessions_list, ' + 'get copy sessions failed. ' + 'Return code: %(rc)lu, ' + 'Error: %(emsg)s, ' + 'Message: %(clidata)s.') + % {'rc': rc, + 'emsg': emsg, + 'clidata': clidata}) + LOG.error(msg) + raise exception.VolumeBackendAPIException(data=msg) + + LOG.debug('_get_copy_sessions_list, Exit method, ' + 'copy sessions list: %(clidata)s. ', + {'clidata': clidata}) + + return clidata diff --git a/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_fc.py b/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_fc.py index 84f24d02185..68af9f17fe2 100644 --- a/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_fc.py +++ b/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_fc.py @@ -87,8 +87,14 @@ class FJDXFCDriver(driver.FibreChannelDriver): def delete_volume(self, volume): """Delete volume on ETERNUS.""" + LOG.debug('delete_volume, ' + 'volume id: %s, Enter method.', volume['id']) + self.common.delete_volume(volume) + LOG.debug('delete_volume, ' + 'volume id: %s, delete succeed.', volume['id']) + def create_snapshot(self, snapshot): """Creates a snapshot.""" location, metadata = self.common.create_snapshot(snapshot) diff --git a/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_iscsi.py b/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_iscsi.py index 49ef28a2982..e2dfeb4fa79 100644 --- a/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_iscsi.py +++ b/cinder/volume/drivers/fujitsu/eternus_dx/eternus_dx_iscsi.py @@ -94,8 +94,14 @@ class FJDXISCSIDriver(driver.ISCSIDriver): def delete_volume(self, volume): """Delete volume on ETERNUS.""" + LOG.debug('delete_volume, ' + 'volume id: %s, Enter method.', volume['id']) + self.common.delete_volume(volume) + LOG.debug('delete_volume, ' + 'volume id: %s, delete succeed.', volume['id']) + def create_snapshot(self, snapshot): """Creates a snapshot.""" element_path, metadata = self.common.create_snapshot(snapshot) diff --git a/releasenotes/notes/fujitsu-improve-delete-volume-8fa509f0424deb8e.yaml b/releasenotes/notes/fujitsu-improve-delete-volume-8fa509f0424deb8e.yaml new file mode 100644 index 00000000000..cf676e2714d --- /dev/null +++ b/releasenotes/notes/fujitsu-improve-delete-volume-8fa509f0424deb8e.yaml @@ -0,0 +1,15 @@ +--- +features: + - | + Fujitsu ETERNUS DX driver: Improve volume deletion + + To improve the volume deletion process, add a step to check associated copy + sessions. Additionally, it also improves the process of retrieving + storage-managed volume numbers. + + There was a problem where the volume could not be deleted because the copy + session information acquired by SMI-S IF from ETERNUS DX Storage, which was + cached and did not reflect the information that had just been executed. + + This problem has been addressed through improvements in information + retrieval.