From 30919d2bac84191c0abcbcad758c40b027ee5bd6 Mon Sep 17 00:00:00 2001 From: haailani Date: Tue, 31 May 2022 21:33:27 +0000 Subject: [PATCH] [SVf] : Fix multiple SVC CLI calls for rc-relationship operations [Spectrum Virtualize family] There are several svcinfo calls such as lsvdisk and lsrcrelationship calls which are not necessary in several operations such as extend volume operation or convert global mirror volume to gmcv. Reducing these calls will optimize the code and reduce the load on storage. Using the stored data can reduce the compute time also. Closes-Bug: #1976400 Change-Id: I699e5cefe90d455f5435a848182a1352b71be978 --- .../volume/drivers/ibm/test_storwize_svc.py | 38 ++++++++---- .../drivers/ibm/storwize_svc/replication.py | 21 ++++--- .../ibm/storwize_svc/storwize_svc_common.py | 61 +++++++++++-------- ...ationship_operations-24d15dfccc922cdd.yaml | 8 +++ 4 files changed, 82 insertions(+), 46 deletions(-) create mode 100644 releasenotes/notes/bug-1976400-storwize-Fix_multiple_SVC_CLI_calls_for_rc-relationship_operations-24d15dfccc922cdd.yaml diff --git a/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py b/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py index 4a459f7de51..10af5b8dc2c 100644 --- a/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py +++ b/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py @@ -10626,7 +10626,7 @@ class StorwizeHelpersTestCase(test.TestCase): self.storwize_svc_common.start_relationship(opts['name']) get_vdisk_attributes.assert_called_with(opts['name']) if not opts['RC_name']: - stoprcrelationship.assert_not_called() + stoprcrelationship.assert_called() startrcrelationship.assert_called() else: stoprcrelationship.assert_called_once_with(opts['RC_name'], @@ -12548,10 +12548,12 @@ class StorwizeSVCReplicationTestCase(test.TestCase): delete_vdisk.assert_has_calls(calls, any_order=True) self.assertEqual(2, delete_vdisk.call_count) - rel_info = {'aux_vdisk_name': fake_name, + rel_info = {'name': 'fake_rcrel', + 'aux_vdisk_name': fake_name, 'master_vdisk_name': 'volume-%s' % fake.VOLUME_ID} self.driver._helpers.delete_rc_volume(fake_name, rel_info) - delete_relationship.assert_called_once_with(fake_name) + delete_relationship.assert_called_once_with(fake_name, + rcrel=rel_info['name']) @mock.patch.object(storwize_svc_common.StorwizeHelpers, 'delete_vdisk') @@ -12566,12 +12568,14 @@ class StorwizeSVCReplicationTestCase(test.TestCase): [self.rep_target]) self.driver.do_setup(self.ctxt) fake_name = 'aux_volume-%s' % fake.VOLUME_ID - rel_info = {'aux_vdisk_name': fake_name, + rel_info = {'name': 'fake_rcrel', + 'aux_vdisk_name': fake_name, 'master_vdisk_name': 'volume-%s' % fake.VOLUME_ID} self.driver._aux_backend_helpers.delete_rc_volume(fake_name, rel_info, target_vol=True) - delete_relationship.assert_called_with(fake_name) + delete_relationship.assert_called_with(fake_name, + rcrel=rel_info['name']) target_change_fake_name = ( storwize_const.REPLICA_CHG_VOL_PREFIX + fake_name) calls = [mock.call(target_change_fake_name, force_delete=False, @@ -12606,13 +12610,15 @@ class StorwizeSVCReplicationTestCase(test.TestCase): delete_vdisk): fake_id = fake.VOLUME_ID fake_name = 'aux_volume-%s' % fake_id - rel_info = {'aux_vdisk_name': fake_name, + rel_info = {'name': 'fake_rcrel', + 'aux_vdisk_name': fake_name, 'master_vdisk_name': 'volume-%s' % fake_id} delete_vdisk.side_effect = Exception self.assertRaises(exception.VolumeDriverException, self.driver._aux_backend_helpers.delete_rc_volume, fake_name, rel_info, target_vol=True) - delete_relationship.assert_called_once_with(fake_name) + delete_relationship.assert_called_once_with(fake_name, + rcrel=rel_info['name']) @mock.patch.object(storwize_svc_common.StorwizeHelpers, 'get_relationship_info') @@ -12666,7 +12672,8 @@ class StorwizeSVCReplicationTestCase(test.TestCase): [self.rep_target]) self.driver.do_setup(self.ctxt) fake_name = 'aux_volume-%s' % fake.VOLUME_ID - rel_info = {'aux_vdisk_name': fake_name, + rel_info = {'name': 'fakercrel', + 'aux_vdisk_name': fake_name, 'master_vdisk_name': 'volume-%s' % fake.VOLUME_ID} self.driver._aux_backend_helpers.delete_rc_volume( fake_name, rel_info, target_vol=target_vol, @@ -12676,7 +12683,8 @@ class StorwizeSVCReplicationTestCase(test.TestCase): change_vol_name = (storwize_const.REPLICA_CHG_VOL_PREFIX + vol_name) if rel_info: - delete_relationship.assert_called_once_with(vol_name) + delete_relationship.assert_called_once_with(vol_name, + rcrel=rel_info['name']) calls = [mock.call(change_vol_name, force_delete=False, force_unmap=True)] @@ -13350,7 +13358,8 @@ class StorwizeSVCReplicationTestCase(test.TestCase): fake_info = {'volume': 'fake', 'master_vdisk_name': 'fake', - 'aux_vdisk_name': 'fake'} + 'aux_vdisk_name': 'fake', + 'name': 'fake_rcrel'} sync_state = {'state': storwize_const.REP_CONSIS_SYNC, 'primary': 'fake'} sync_state.update(fake_info) @@ -13387,7 +13396,8 @@ class StorwizeSVCReplicationTestCase(test.TestCase): 'get_relationship_info', mock.Mock(return_value=disconn_state)): self.driver._sync_with_aux(self.ctxt, volumes) - calls = [mock.call(tgt_volume), mock.call(tgt_gmcv_volume)] + calls = [mock.call(tgt_volume, rcrel=fake_info['name']), + mock.call(tgt_gmcv_volume, rcrel=fake_info['name'])] start_relationship.assert_has_calls(calls, any_order=True) self.assertEqual(2, start_relationship.call_count) @@ -13396,8 +13406,10 @@ class StorwizeSVCReplicationTestCase(test.TestCase): 'get_relationship_info', mock.Mock(return_value=stop_state)): self.driver._sync_with_aux(self.ctxt, volumes) - calls = [mock.call(tgt_volume, primary='aux'), - mock.call(tgt_gmcv_volume, primary='aux')] + calls = [mock.call(tgt_volume, primary='aux', + rcrel=fake_info['name']), + mock.call(tgt_gmcv_volume, primary='aux', + rcrel=fake_info['name'])] start_relationship.assert_has_calls(calls, any_order=True) self.assertEqual(2, start_relationship.call_count) self.driver.delete_volume(mm_vol) diff --git a/cinder/volume/drivers/ibm/storwize_svc/replication.py b/cinder/volume/drivers/ibm/storwize_svc/replication.py index 0f95aed4dab..8815623a870 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/replication.py +++ b/cinder/volume/drivers/ibm/storwize_svc/replication.py @@ -98,20 +98,23 @@ class StorwizeSVCReplicationGlobalMirror(StorwizeSVCReplication): target_vol_name = storwize_const.REPLICA_AUX_VOL_PREFIX + vref['name'] try: - attr = self.target_helpers.get_vdisk_attributes(target_vol_name) - if not attr: - opts = self.driver._get_vdisk_params(vref['volume_type_id']) - pool = self.target.get('pool_name') - src_attr = self.driver._helpers.get_vdisk_attributes( - vref['name']) - opts['iogrp'] = src_attr['IO_group_id'] + opts = self.driver._get_vdisk_params(vref['volume_type_id']) + pool = self.target.get('pool_name') + src_attr = self.driver._helpers.get_vdisk_attributes( + vref['name']) + opts['iogrp'] = src_attr['IO_group_id'] + try: self.target_helpers.create_vdisk(target_vol_name, six.text_type(vref['size']), 'gb', pool, opts) + except exception.VolumeBackendAPIException as excp: + if "CMMVC6035E" in excp.msg: + LOG.info('Target Volume: %(vol)s already exists', + {'vol': target_vol_name}) - system_info = self.target_helpers.get_system_info() + target_system_id = self.driver._aux_state['system_id'] self.driver._helpers.create_relationship( - vref['name'], target_vol_name, system_info.get('system_id'), + vref['name'], target_vol_name, target_system_id, self.asyncmirror) except Exception as e: msg = (_("Unable to set up mirror mode replication for %(vol)s. " diff --git a/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py b/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py index e4153521308..43d48f22d33 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py +++ b/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py @@ -2565,10 +2565,11 @@ class StorwizeHelpers(object): rcrel = vol_attrs['RC_name'] self.ssh.startrcrelationship(rcrel, primary) - def stop_relationship(self, volume_name, access=False): - vol_attrs = self.get_vdisk_attributes(volume_name) - if vol_attrs['RC_name']: - self.ssh.stoprcrelationship(vol_attrs['RC_name'], access=access) + def stop_relationship(self, volume_name, access=False, rcrel=None): + if rcrel is None: + vol_attrs = self.get_vdisk_attributes(volume_name) + rcrel = vol_attrs['RC_name'] + self.ssh.stoprcrelationship(rcrel, access=access) def create_relationship(self, master, aux, system, asyncmirror, cyclingmode=False, masterchange=None, @@ -2640,10 +2641,11 @@ class StorwizeHelpers(object): self.ssh.ch_rcconsistgrp_cyclingmode(rccg_name, cyclingmode) - def delete_relationship(self, volume_name): - vol_attrs = self.get_vdisk_attributes(volume_name) - if vol_attrs['RC_name']: - self.ssh.rmrcrelationship(vol_attrs['RC_name'], True) + def delete_relationship(self, volume_name, rcrel=None): + if rcrel is None: + vol_attrs = self.get_vdisk_attributes(volume_name) + rcrel = vol_attrs['RC_name'] + self.ssh.rmrcrelationship(rcrel, True) def get_relationship_info(self, volume_name): vol_attrs = self.get_vdisk_attributes(volume_name) @@ -2689,7 +2691,8 @@ class StorwizeHelpers(object): try: # If relationship exists, will delete the relationship. if rel_info: - self.delete_relationship(volume_name) + self.delete_relationship(volume_name, + rcrel=rel_info['name']) # Delete change volume self.delete_vdisk( storwize_const.REPLICA_CHG_VOL_PREFIX + volume_name, @@ -4030,6 +4033,7 @@ class StorwizeSVCCommonDriver(san.SanDriver, 'not recommended.') rep_type = rel_info['copy_type'] cyclingmode = rel_info['cycling_mode'] + rc_name = rel_info['name'] master_helper = self._master_backend_helpers target_helper = self._aux_backend_helpers if rep_type == 'activeactive': @@ -4078,10 +4082,12 @@ class StorwizeSVCCommonDriver(san.SanDriver, rccg_name) master_helper.start_rccg(rccg_name) else: - master_helper.stop_relationship(volume.name) + master_helper.stop_relationship(volume.name, + rcrel=rc_name) master_helper.change_relationship_cyclingmode( - volume.name) - master_helper.start_relationship(volume.name) + volume.name, rcrel=rc_name) + master_helper.start_relationship(volume.name, + rcrel=rc_name) tgt_change_vol = ( storwize_const.REPLICA_CHG_VOL_PREFIX + tgt_vol) @@ -4163,7 +4169,7 @@ class StorwizeSVCCommonDriver(san.SanDriver, target_helper = self._aux_backend_helpers tgt_change_vol = (storwize_const.REPLICA_CHG_VOL_PREFIX + target_vol) src_change_vol = (storwize_const.REPLICA_CHG_VOL_PREFIX + volume.name) - + rc_name = rel_info['name'] # Create source change volume if it doesn't exist src_attr = master_helper.get_vdisk_attributes(volume.name) src_change_attr = master_helper.get_vdisk_attributes(src_change_vol) @@ -4195,33 +4201,34 @@ class StorwizeSVCCommonDriver(san.SanDriver, master_helper.change_consistgrp_cyclingmode(rccg_name, 'multi') else: # Update volume cyclingmode to 'multi' - master_helper.stop_relationship(volume.name) - master_helper.change_relationship_cyclingmode(volume.name, 'multi') + master_helper.stop_relationship(volume.name, rcrel=rc_name) + master_helper.change_relationship_cyclingmode(volume.name, 'multi', + rc_name) # Set source_change_volume and target_change_volume if rel_info["master_vdisk_name"] == volume.name: master_helper.change_relationship_changevolume(volume.name, src_change_vol, - True) + True, rc_name) target_helper.change_relationship_changevolume(target_vol, tgt_change_vol, - False) + False, rc_name) else: # Auxiliary volume is onboarded as source volume # [Reverse Replication Scenario] master_helper.change_relationship_changevolume(volume.name, src_change_vol, - False) + False, rc_name) target_helper.change_relationship_changevolume(target_vol, tgt_change_vol, - True) + True, rc_name) if rccg_name: # Start gmcv consistency group relationshi master_helper.start_rccg(rccg_name) else: # Start gmcv volume relationship - master_helper.start_relationship(volume.name) + master_helper.start_relationship(volume.name, rcrel=rc_name) def _qos_model_update(self, model_update, volume): """add volume wwn and IOThrottle_rate to the metadata of the volume""" @@ -4570,10 +4577,14 @@ class StorwizeSVCCommonDriver(san.SanDriver, [storwize_const.REP_CONSIS_SYNC, storwize_const.REP_CONSIS_COPYING]): if rep_info['primary'] == 'master': - self._helpers.start_relationship(tgt_volume) + self._helpers.start_relationship(tgt_volume, + rcrel= + rep_info['name']) else: self._helpers.start_relationship(tgt_volume, - primary='aux') + primary='aux', + rcrel= + rep_info['name']) except Exception as ex: LOG.warning('Fail to copy data from aux to master. master:' ' %(master)s and aux %(aux)s. Please ' @@ -6686,7 +6697,8 @@ class StorwizeSVCCommonDriver(san.SanDriver, model_update['status'] = fields.GroupStatus.ERROR else: if rccg and rccg.get('cycling_mode', None) == 'multi': - self._helpers.stop_relationship(vol_name) + self._helpers.stop_relationship(vol_name, + rcrel=rcrel['name']) rcrel = self._helpers.get_relationship_info(vol_name) if (rccg['state'] != 'empty' and rccg['state'] != 'consistent_stopped' or @@ -6727,7 +6739,8 @@ class StorwizeSVCCommonDriver(san.SanDriver, rccg['cycle_period_seconds']}) # This rcrel updation failed ,it has to be started # explicitly. - self._helpers.start_relationship(vol_name) + self._helpers.start_relationship(vol_name, + rcrel=rcrel['name']) model_update['status'] = fields.GroupStatus.ERROR else: self._helpers.chrcrelationship(rcrel['name'], diff --git a/releasenotes/notes/bug-1976400-storwize-Fix_multiple_SVC_CLI_calls_for_rc-relationship_operations-24d15dfccc922cdd.yaml b/releasenotes/notes/bug-1976400-storwize-Fix_multiple_SVC_CLI_calls_for_rc-relationship_operations-24d15dfccc922cdd.yaml new file mode 100644 index 00000000000..e4a5ccce13c --- /dev/null +++ b/releasenotes/notes/bug-1976400-storwize-Fix_multiple_SVC_CLI_calls_for_rc-relationship_operations-24d15dfccc922cdd.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + IBM Spectrum Virtualize Family driver: `Bug #1976400 + `_: + Optimize svcinfo CLI calls to reduce the + computational time for rc-relationship related + operations.