[SVF]: Fix extend issue for a clone of rep-volume

[Spectrum Virtualize Family] During extend operation the flashcopy
mapping between clone volume and its source volume having snapshots,
was not being deleted after copying, hence extend operation
is failing.

This fix is to properly stop the flashcopy mappings before extending.

Closes-Bug: #1920099

Change-Id: I336a8c92bfdd852cab42c9e5f992a30f3632bfaf
This commit is contained in:
amar7ibm 2021-03-23 16:11:41 +05:30
parent a01b5bb39e
commit 020944bada
3 changed files with 87 additions and 10 deletions

View File

@ -8949,11 +8949,15 @@ class StorwizeHelpersTestCase(test.TestCase):
'_get_flashcopy_mapping_attributes')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'_get_vdisk_fc_mappings')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'get_relationship_info')
def test_check_vdisk_fc_mappings(self,
fc_data,
get_relationship_info,
get_vdisk_fc_mappings,
get_fc_mapping_attributes,
rmfcmap, stopfcmap, chfcmap):
vol = 'testvol'
get_vdisk_fc_mappings.return_value = ['4']
get_fc_mapping_attributes.return_value = {
@ -8963,13 +8967,72 @@ class StorwizeHelpersTestCase(test.TestCase):
'target_vdisk_name': 'tar-testvol',
'rc_controlled': 'no',
'source_vdisk_name': 'testvol'}
get_relationship_info.return_value = None
if(fc_data['copy_rate'] != '0' and fc_data['progress'] == '100'
and fc_data['status'] == 'copying'):
(self.assertRaises(loopingcall.LoopingCallDone,
self.storwize_svc_common._check_vdisk_fc_mappings, vol, True,
False))
stopfcmap.assert_called_with('4')
stopfcmap.assert_called_with('4', False)
self.assertEqual(1, stopfcmap.call_count)
else:
self.storwize_svc_common._check_vdisk_fc_mappings(vol, True,
False)
stopfcmap.assert_not_called()
self.assertEqual(0, stopfcmap.call_count)
get_vdisk_fc_mappings.assert_called()
get_fc_mapping_attributes.assert_called_with('4')
rmfcmap.assert_not_called()
self.assertEqual(1, get_fc_mapping_attributes.call_count)
self.assertEqual(0, rmfcmap.call_count)
if(fc_data['copy_rate'] == '0' and fc_data['progress'] == '0'
and fc_data['status'] in ['copying', 'idle_or_copied']):
chfcmap.assert_called_with('4', copyrate='50', autodel='on')
self.assertEqual(1, chfcmap.call_count)
else:
chfcmap.assert_not_called()
self.assertEqual(0, chfcmap.call_count)
@ddt.data({'copy_rate': '50', 'progress': '3', 'status': 'copying'},
{'copy_rate': '50', 'progress': '100', 'status': 'copying'},
{'copy_rate': '0', 'progress': '0', 'status': 'copying'},
{'copy_rate': '50', 'progress': '0', 'status': 'copying'},
{'copy_rate': '0', 'progress': '0', 'status': 'idle_or_copied'})
@mock.patch.object(storwize_svc_common.StorwizeSSH, 'chfcmap')
@mock.patch.object(storwize_svc_common.StorwizeSSH, 'stopfcmap')
@mock.patch.object(storwize_svc_common.StorwizeSSH, 'rmfcmap')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'_get_flashcopy_mapping_attributes')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'_get_vdisk_fc_mappings')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'get_relationship_info')
def test_check_vdisk_fc_mappings_with_rcrel(self,
fc_data,
get_relationship_info,
get_vdisk_fc_mappings,
get_fc_mapping_attributes,
rmfcmap, stopfcmap, chfcmap):
vol = 'testvol'
get_vdisk_fc_mappings.return_value = ['4']
get_fc_mapping_attributes.return_value = {
'copy_rate': fc_data['copy_rate'],
'progress': fc_data['progress'],
'status': fc_data['status'],
'target_vdisk_name': 'tar-testvol',
'rc_controlled': 'no',
'source_vdisk_name': 'testvol'}
rel_info = {'name': 'rcrel232'}
get_relationship_info.return_value = rel_info
if(fc_data['copy_rate'] != '0' and fc_data['progress'] == '100'
and fc_data['status'] == 'copying'):
(self.assertRaises(loopingcall.LoopingCallDone,
self.storwize_svc_common._check_vdisk_fc_mappings, vol, True,
False, rel_info))
stopfcmap.assert_called_with('4', True)
self.assertEqual(1, stopfcmap.call_count)
else:
self.storwize_svc_common._check_vdisk_fc_mappings(vol, True,

View File

@ -2185,7 +2185,7 @@ class StorwizeHelpers(object):
@volume_utils.trace
def _check_delete_vdisk_fc_mappings(self, name, allow_snaps=True,
allow_fctgt=False):
allow_fctgt=False, rel_info=None):
"""FlashCopy mapping check helper."""
mapping_ids = self._get_vdisk_fc_mappings(name)
wait_for_copy = False
@ -2261,7 +2261,10 @@ class StorwizeHelpers(object):
self.ssh.rmfcmap(map_id)
elif (status in ['copying', 'prepared'] and
progress == '100'):
self.ssh.stopfcmap(map_id)
force = False
if rel_info:
force = True
self.ssh.stopfcmap(map_id, force)
else:
wait_for_copy = True
except exception.VolumeBackendAPIException as ex:
@ -2273,7 +2276,7 @@ class StorwizeHelpers(object):
@volume_utils.trace
def _check_vdisk_fc_mappings(self, name, allow_snaps=True,
allow_fctgt=False):
allow_fctgt=False, rel_info=None):
"""FlashCopy mapping check helper."""
# if this is a remove disk we need to be down to one fc clone
mapping_ids = self._get_vdisk_fc_mappings(name)
@ -2315,14 +2318,15 @@ class StorwizeHelpers(object):
if len(mapping_ids) - len(Rc_mapping_ids) > 1:
return
return self._check_delete_vdisk_fc_mappings(
name, allow_snaps=allow_snaps, allow_fctgt=allow_fctgt)
name, allow_snaps=allow_snaps, allow_fctgt=allow_fctgt,
rel_info=rel_info)
def ensure_vdisk_no_fc_mappings(self, name, allow_snaps=True,
allow_fctgt=False):
allow_fctgt=False, rel_info=None):
"""Ensure vdisk has no flashcopy mappings."""
timer = loopingcall.FixedIntervalLoopingCall(
self._check_vdisk_fc_mappings, name,
allow_snaps, allow_fctgt)
allow_snaps, allow_fctgt, rel_info)
# Create a timer greenthread. The default volume service heart
# beat is every 10 seconds. The flashcopy usually takes hours
# before it finishes. Don't set the sleep interval shorter
@ -3681,8 +3685,11 @@ class StorwizeSVCCommonDriver(san.SanDriver,
LOG.error(msg)
raise exception.InvalidInput(message=msg)
rel_info = self._helpers.get_relationship_info(volume_name)
ret = self._helpers.ensure_vdisk_no_fc_mappings(volume_name,
allow_snaps=False)
allow_snaps=False,
rel_info=rel_info)
if not ret:
msg = (_('_extend_volume_op: Extending a volume with snapshots is '
'not supported.'))
@ -3693,7 +3700,6 @@ class StorwizeSVCCommonDriver(san.SanDriver,
old_size = volume.size
extend_amt = int(new_size) - old_size
rel_info = self._helpers.get_relationship_info(volume_name)
if rel_info:
LOG.warning('_extend_volume_op: Extending a volume with '
'remote copy is not recommended.')

View File

@ -0,0 +1,8 @@
---
fixes:
- |
IBM Spectrum Virtualize Family driver `Bug #1920099
<https://bugs.launchpad.net/cinder/+bug/1920099>`_:
Fix issue where _check_delete_vdisk_fc_mappings was deleting flashcopy
mappings during extend operation of a clone volume where its
source volume already contained a snapshot.