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 cb95d2e4e98..4a459f7de51 100644 --- a/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py +++ b/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py @@ -2226,7 +2226,8 @@ port_speed!N/A if 'obj' in kwargs: name = kwargs['obj'] for k, v in self._rcrelationship_list.items(): - if six.text_type(v['name']) == name: + if ((str(v['name']) == name) or + (str(v['id']) == name)): self._rc_state_transition('wait', v) if self._next_cmd_error['lsrcrelationship'] == 'speed_up': @@ -10626,7 +10627,7 @@ class StorwizeHelpersTestCase(test.TestCase): get_vdisk_attributes.assert_called_with(opts['name']) if not opts['RC_name']: stoprcrelationship.assert_not_called() - startrcrelationship.assert_not_called() + startrcrelationship.assert_called() else: stoprcrelationship.assert_called_once_with(opts['RC_name'], access=access) @@ -12440,7 +12441,6 @@ class StorwizeSVCReplicationTestCase(test.TestCase): self.driver.configuration.set_override('replication_device', [self.rep_target]) self.driver.do_setup(self.ctxt) - # Create replication volume. backend_volume, model_update = self._create_test_volume(self.mm_type) volume, model_update = self._create_test_volume(self.mm_type) @@ -12989,11 +12989,13 @@ class StorwizeSVCReplicationTestCase(test.TestCase): start_relationship): replica_obj = self.driver._get_replica_obj(storwize_const.METRO) mm_vol, model_update = self._create_test_volume(self.mm_type) + mm_vol_attrs = self.driver._helpers.get_vdisk_attributes(mm_vol.name) target_vol = storwize_const.REPLICA_AUX_VOL_PREFIX + mm_vol.name context = mock.Mock replica_obj.failover_volume_host(context, mm_vol) stop_relationship.assert_called_once_with(target_vol, access=True) - calls = [mock.call(mm_vol.name), mock.call(target_vol, 'aux')] + calls = [mock.call(mm_vol.name, rcrel=mm_vol_attrs['RC_name']), + mock.call(target_vol, 'aux')] start_relationship.assert_has_calls(calls, any_order=True) self.assertEqual(2, start_relationship.call_count) diff --git a/cinder/volume/drivers/ibm/storwize_svc/replication.py b/cinder/volume/drivers/ibm/storwize_svc/replication.py index 2437397d58c..0f95aed4dab 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/replication.py +++ b/cinder/volume/drivers/ibm/storwize_svc/replication.py @@ -167,81 +167,93 @@ class StorwizeSVCReplicationGMCV(StorwizeSVCReplicationGlobalMirror): new_type['id'], volume_type=new_type) src_attr = self.driver._helpers.get_vdisk_attributes( vref['name']) - # Create source change volume if it doesn't exist - src_change_attr = self.driver._helpers.get_vdisk_attributes( - source_change_vol_name) - if not src_change_attr: - src_change_opts = self.driver._get_vdisk_params( - vref['volume_type_id']) - src_change_opts['iogrp'] = src_attr['IO_group_id'] - # Change volumes would usually be thin-provisioned - src_change_opts['autoexpand'] = True - src_change_pool = src_attr['mdisk_grp_name'] - if new_type: - src_child_pool = ( - new_type_opts['storwize_svc_src_child_pool']) - else: - src_child_pool = ( - src_change_opts['storwize_svc_src_child_pool']) - if src_child_pool: - src_change_pool = src_child_pool + # Source change volume creation + src_change_opts = self.driver._get_vdisk_params( + vref['volume_type_id']) + src_change_opts['iogrp'] = src_attr['IO_group_id'] + # Change volumes would usually be thin-provisioned + src_change_opts['autoexpand'] = True + src_change_pool = src_attr['mdisk_grp_name'] + if new_type: + src_child_pool = ( + new_type_opts['storwize_svc_src_child_pool']) + else: + src_child_pool = ( + src_change_opts['storwize_svc_src_child_pool']) + if src_child_pool: + src_change_pool = src_child_pool + try: self.driver._helpers.create_vdisk(source_change_vol_name, six.text_type(vref['size']), 'gb', src_change_pool, src_change_opts) - # Create target volume if it doesn't exist - target_attr = self.target_helpers.get_vdisk_attributes( - target_vol_name) - if not target_attr: - target_opts = self.driver._get_vdisk_params( - vref['volume_type_id']) - target_pool = self.target.get('pool_name') - target_opts['iogrp'] = src_attr['IO_group_id'] + except exception.VolumeBackendAPIException as excp: + if "CMMVC6035E" in excp.msg: + msg = ('Source change volume: %s already exists' + % source_change_vol_name) + LOG.info(msg) + + # Target volume creation + target_opts = self.driver._get_vdisk_params( + vref['volume_type_id']) + target_pool = self.target.get('pool_name') + target_opts['iogrp'] = src_attr['IO_group_id'] + try: self.target_helpers.create_vdisk(target_vol_name, six.text_type(vref['size']), 'gb', target_pool, target_opts) + except exception.VolumeBackendAPIException as excp: + if "CMMVC6035E" in excp.msg: + msg = ('Target Volume: %s already exists' + % target_vol_name) + LOG.info(msg) - # Create target change volume if it doesn't exist - target_change_attr = self.target_helpers.get_vdisk_attributes( - target_change_vol_name) - if not target_change_attr: - target_change_opts = self.driver._get_vdisk_params( - vref['volume_type_id']) - target_change_pool = self.target.get('pool_name') - if new_type: - target_child_pool = ( - new_type_opts['storwize_svc_target_child_pool']) - else: - target_child_pool = ( - target_change_opts['storwize_svc_target_child_pool']) - if target_child_pool: - target_change_pool = target_child_pool - target_change_opts['iogrp'] = src_attr['IO_group_id'] - # Change Volumes would usually be thin-provisioned - target_change_opts['autoexpand'] = True + # Target change volume creation + target_change_opts = self.driver._get_vdisk_params( + vref['volume_type_id']) + target_change_pool = self.target.get('pool_name') + if new_type: + target_child_pool = ( + new_type_opts['storwize_svc_target_child_pool']) + else: + target_child_pool = ( + target_change_opts['storwize_svc_target_child_pool']) + if target_child_pool: + target_change_pool = target_child_pool + target_change_opts['iogrp'] = src_attr['IO_group_id'] + # Change Volumes would usually be thin-provisioned + target_change_opts['autoexpand'] = True + try: self.target_helpers.create_vdisk(target_change_vol_name, six.text_type(vref['size']), 'gb', target_change_pool, target_change_opts) + except exception.VolumeBackendAPIException as excp: + if "CMMVC6035E" in excp.msg: + msg = ('Target Change Volume: %s already exists' + % target_change_vol_name) + LOG.info(msg) - system_info = self.target_helpers.get_system_info() + target_system_id = self.driver._aux_state['system_id'] # Get cycle_period_seconds src_change_opts = self.driver._get_vdisk_params( vref['volume_type_id']) cycle_period_seconds = src_change_opts.get('cycle_period_seconds') - self.driver._helpers.create_relationship( - vref['name'], target_vol_name, system_info.get('system_id'), + rc_name = self.driver._helpers.create_relationship( + vref['name'], target_vol_name, target_system_id, self.asyncmirror, True, source_change_vol_name, cycle_period_seconds) # Set target change volume self.target_helpers.change_relationship_changevolume( - target_vol_name, target_change_vol_name, False) + target_vol_name, target_change_vol_name, False, + rc_name) # Start gmcv relationship - self.driver._helpers.start_relationship(vref['name']) + self.driver._helpers.start_relationship(vref['name'], + rcrel=rc_name) except Exception as e: msg = (_("Unable to set up gmcv mode replication for %(vol)s. " "Exception: %(err)s.") % {'vol': vref['id'], 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 c7104ea009b..e4153521308 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py +++ b/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py @@ -2558,10 +2558,12 @@ class StorwizeHelpers(object): timer.stop() return ret - def start_relationship(self, volume_name, primary=None): - vol_attrs = self.get_vdisk_attributes(volume_name) - if vol_attrs['RC_name']: - self.ssh.startrcrelationship(vol_attrs['RC_name'], primary) + def start_relationship(self, volume_name, primary=None, + rcrel=None): + if rcrel is None: + vol_attrs = self.get_vdisk_attributes(volume_name) + 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) @@ -2588,34 +2590,49 @@ class StorwizeHelpers(object): # We need setup master and aux change volumes for gmcv # before we can start remote relationship # aux change volume must be set on target site + rel_info = self.ssh.lsrcrelationship(rc_id) + rc_name = rel_info[0]['name'] if cycle_period_seconds: self.change_relationship_cycleperiod(master, - cycle_period_seconds) + cycle_period_seconds, + rc_name) if masterchange: self.change_relationship_changevolume(master, - masterchange, True) + masterchange, True, + rc_name) else: - self.start_relationship(master) + self.start_relationship(master, rcrel=rc_name) + return rc_name def change_relationship_changevolume(self, volume_name, - change_volume, master): - vol_attrs = self.get_vdisk_attributes(volume_name) - if vol_attrs['RC_name'] and change_volume: - self.ssh.ch_rcrelationship_changevolume(vol_attrs['RC_name'], - change_volume, master) + change_volume, master, + rcrel=None): + if rcrel is None: + vol_attrs = self.get_vdisk_attributes(volume_name) + rcrel = vol_attrs['RC_name'] + if rcrel and change_volume: + self.ssh.ch_rcrelationship_changevolume(rcrel, + change_volume, + master) def change_relationship_cycleperiod(self, volume_name, - cycle_period_seconds): - vol_attrs = self.get_vdisk_attributes(volume_name) - if vol_attrs['RC_name'] and cycle_period_seconds: - self.ssh.ch_rcrelationship_cycleperiod(vol_attrs['RC_name'], + cycle_period_seconds, + rcrel=None): + if rcrel is None: + vol_attrs = self.get_vdisk_attributes(volume_name) + rcrel = vol_attrs['RC_name'] + if rcrel and cycle_period_seconds: + self.ssh.ch_rcrelationship_cycleperiod(rcrel, cycle_period_seconds) def change_relationship_cyclingmode(self, volume_name, - cyclingmode='none'): - vol_attrs = self.get_vdisk_attributes(volume_name) - if vol_attrs['RC_name'] and cyclingmode: - self.ssh.ch_rcrelationship_cyclingmode(vol_attrs['RC_name'], + cyclingmode='none', + rcrel=None): + if rcrel is None: + vol_attrs = self.get_vdisk_attributes(volume_name) + rcrel = vol_attrs['RC_name'] + if rcrel and cyclingmode: + self.ssh.ch_rcrelationship_cyclingmode(rcrel, cyclingmode) def change_consistgrp_cyclingmode(self, rccg_name, diff --git a/releasenotes/notes/bug-1961548-ibm-svf-Fix_multiple_SVC_CLI_calls_for_create_volume_operation-338b009bca72ee60.yaml b/releasenotes/notes/bug-1961548-ibm-svf-Fix_multiple_SVC_CLI_calls_for_create_volume_operation-338b009bca72ee60.yaml new file mode 100644 index 00000000000..fc68589f7cf --- /dev/null +++ b/releasenotes/notes/bug-1961548-ibm-svf-Fix_multiple_SVC_CLI_calls_for_create_volume_operation-338b009bca72ee60.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + IBM Spectrum Virtualize Family driver: `Bug #1961548 + `_: + Optimize lsvdisk and lssystem calls to reduce the + computational time for creating GMCV volumes.