From e274de52dd291a6e5a99a514ac6c71326fca560f Mon Sep 17 00:00:00 2001 From: "yixuan.zhang" Date: Wed, 23 May 2018 14:07:19 +0800 Subject: [PATCH] Storwize:clone volume with iogrp value as expected Currently, clone a volume with a new volume type, the iogrp is the same as source volume. With this patch, create_cloned_volme, the iogrp will be the value specified in extra_spec. Change-Id: I8f349b4813a2a9b817bf924e6ed052b48842bea3 Closes-Bug: 1754760 --- .../volume/drivers/ibm/test_storwize_svc.py | 22 +++++++++-- .../ibm/storwize_svc/storwize_svc_common.py | 39 ++++++++++--------- 2 files changed, 39 insertions(+), 22 deletions(-) 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 4b634ecabbb..29c696390b8 100644 --- a/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py +++ b/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py @@ -5101,6 +5101,23 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase): if fcmap['target'] == vol1['name']: self.assertEqual('149', fcmap['copyrate']) + # create cloned volume with new type diffrent iogrp + key_specs_old = {'iogrp': '0'} + key_specs_new = {'iogrp': '1'} + old_type_ref = volume_types.create(ctxt, 'oldio', key_specs_old) + new_type_ref = volume_types.create(ctxt, 'newio', key_specs_new) + old_io_type = objects.VolumeType.get_by_id(ctxt, + old_type_ref['id']) + new_io_type = objects.VolumeType.get_by_id(ctxt, + new_type_ref['id']) + + volume3 = self._generate_vol_info(old_io_type) + self.driver.create_volume(volume3) + volume4 = self._generate_vol_info(new_io_type) + self.driver.create_cloned_volume(volume4, volume) + attributes = self.driver._helpers.get_vdisk_attributes(volume4['name']) + self.assertEqual('1', attributes['IO_group_id']) + def test_storwize_svc_create_volume_from_snapshot(self): vol1 = self._create_volume() snap1 = self._generate_snap_info(vol1.id) @@ -7143,9 +7160,8 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase): pool = 'openstack3' opts['iogrp'] = '0,1' state['available_iogrps'] = [0, 1, 2, 3] - self.assertRaises(exception.InvalidInput, - self.driver._helpers.select_io_group, - state, opts, pool) + iog = self.driver._helpers.select_io_group(state, opts, pool) + self.assertEqual(0, iog) state['storage_nodes']['2']['site_id'] = '2' pool = 'openstack2' 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 6bc67815537..ea805602300 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py +++ b/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py @@ -864,22 +864,23 @@ class StorwizeHelpers(object): if pool_data['site_id'] == node['site_id']: site_iogrp.append(node['IO_group']) site_iogrp = list(map(int, site_iogrp)) - iog_list = list(set(site_iogrp).intersection(iog_list)) - if len(iog_list) == 0: - raise exception.InvalidInput( - reason=_('The storage system topology is hyperswap or ' - 'stretched, The site_id of pool %(pool)s is ' - '%(site_id)s, the available I/O groups on this ' - 'site is %(site_iogrp)s, but the given I/O' - ' group(s) is %(iogrp)s.') - % {'pool': pool, 'site_id': pool_data['site_id'], - 'site_iogrp': site_iogrp, 'iogrp': opts['iogrp']}) - + iogroup_list = list(set(site_iogrp).intersection(iog_list)) + if len(iogroup_list) == 0: + LOG.warning('The storage system topology is hyperswap or ' + 'stretched, The site_id of pool %(pool)s is ' + '%(site_id)s, the available I/O groups on this ' + 'site is %(site_iogrp)s, but the given I/O' + ' group(s) is %(iogrp)s.', + {'pool': pool, 'site_id': pool_data['site_id'], + 'site_iogrp': site_iogrp, 'iogrp': opts['iogrp']}) + iogroup_list = iog_list + else: + iogroup_list = iog_list iog_vdc = self.get_vdisk_count_by_io_group() LOG.debug("IO group current balance %s", iog_vdc) - min_vdisk_count = iog_vdc[iog_list[0]] - selected_iog = iog_list[0] - for iog in iog_list: + min_vdisk_count = iog_vdc[iogroup_list[0]] + selected_iog = iogroup_list[0] + for iog in iogroup_list: if iog_vdc[iog] < min_vdisk_count: min_vdisk_count = iog_vdc[iog] selected_iog = iog @@ -2267,7 +2268,7 @@ class StorwizeHelpers(object): LOG.debug('Leave: delete_vdisk: vdisk %s.', vdisk) def create_copy(self, src, tgt, src_id, config, opts, - full_copy, pool=None): + full_copy, state, pool=None): """Create a new snapshot using FlashCopy.""" LOG.debug('Enter: create_copy: snapshot %(src)s to %(tgt)s.', {'tgt': tgt, 'src': src}) @@ -2284,7 +2285,7 @@ class StorwizeHelpers(object): if not pool: pool = src_attrs['mdisk_grp_name'] - opts['iogrp'] = src_attrs['IO_group_id'] + opts['iogrp'] = self.select_io_group(state, opts, pool) self.create_vdisk(tgt, src_size, 'b', pool, opts) timeout = config.storwize_svc_flashcopy_timeout try: @@ -3128,7 +3129,7 @@ class StorwizeSVCCommonDriver(san.SanDriver, self._helpers.create_copy(snapshot['volume_name'], snapshot['name'], snapshot['volume_id'], self.configuration, - opts, False, pool=pool) + opts, False, self._state, pool=pool) def delete_snapshot(self, snapshot): self._helpers.delete_vdisk(snapshot['name'], False) @@ -3143,7 +3144,7 @@ class StorwizeSVCCommonDriver(san.SanDriver, pool = utils.extract_host(volume['host'], 'pool') self._helpers.create_copy(snapshot['name'], volume['name'], snapshot['id'], self.configuration, - opts, True, pool=pool) + opts, True, self._state, pool=pool) # The volume size is equal to the snapshot size in most # of the cases. But in some scenario, the volume size # may be bigger than the source volume size. @@ -3182,7 +3183,7 @@ class StorwizeSVCCommonDriver(san.SanDriver, pool = utils.extract_host(tgt_volume['host'], 'pool') self._helpers.create_copy(src_volume['name'], tgt_volume['name'], src_volume['id'], self.configuration, - opts, True, pool=pool) + opts, True, self._state, pool=pool) # The source volume size is equal to target volume size # in most of the cases. But in some scenarios, the target