summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-10-22 16:34:32 +0000
committerGerrit Code Review <review@openstack.org>2020-10-22 16:34:32 +0000
commit463c17a3f95f37c4c3edd1eadc5b474893c8adba (patch)
tree4d40a40ae46ed2db5617fcd4c76a0334e746bfdc
parentca0ebb6c925d8b6b33d9110b7dbad8dfe5142286 (diff)
parente8729dc65fdf84dea33192298d1614a585a29416 (diff)
downloadcinder-463c17a3f95f37c4c3edd1eadc5b474893c8adba.tar.gz
Merge "Fix revert snapshot issue" into stable/stein
-rw-r--r--cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py63
-rw-r--r--cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py39
2 files changed, 100 insertions, 2 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 13ff879fc..b0ecce074 100644
--- a/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py
+++ b/cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py
@@ -8043,6 +8043,29 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
self.driver.retype, ctxt, volume,
new_type, diff, host)
+ @mock.patch.object(storwize_svc_common.StorwizeHelpers,
+ '_get_flashcopy_mapping_attributes')
+ @mock.patch.object(storwize_svc_common.StorwizeHelpers,
+ '_get_vdisk_fc_mappings')
+ def test_revert_to_snapshot_with_uncompleted_clone(
+ self,
+ _get_vdisk_fc_mappings,
+ _get_flashcopy_mapping_attributes):
+ vol1 = self._generate_vol_info()
+ snap1 = self._generate_snap_info(vol1.id)
+
+ self.driver._helpers._get_vdisk_fc_mappings.return_value = ['4']
+ self.driver._helpers._get_flashcopy_mapping_attributes.return_value = {
+ 'copy_rate': '50',
+ 'progress': '3',
+ 'status': 'copying',
+ 'target_vdisk_name': 'testvol'}
+
+ self.assertRaises(exception.VolumeBackendAPIException,
+ self.driver.revert_to_snapshot,
+ self.ctxt,
+ vol1, snap1)
+
class CLIResponseTestCase(test.TestCase):
def test_empty(self):
@@ -8237,6 +8260,46 @@ class StorwizeHelpersTestCase(test.TestCase):
self.assertTrue(iog in state['available_iogrps'])
self.assertEqual(1, iog)
+ @mock.patch.object(storwize_svc_common.StorwizeHelpers,
+ '_get_flashcopy_mapping_attributes')
+ @mock.patch.object(storwize_svc_common.StorwizeHelpers,
+ '_get_vdisk_fc_mappings')
+ def test_pretreatment_before_revert_uncompleted_clone(
+ self,
+ _get_vdisk_fc_mappings,
+ _get_flashcopy_mapping_attributes):
+ vol = 'testvol'
+ _get_vdisk_fc_mappings.return_value = ['4']
+ _get_flashcopy_mapping_attributes.return_value = {
+ 'copy_rate': '50',
+ 'progress': '3',
+ 'status': 'copying',
+ 'target_vdisk_name': 'testvol'}
+
+ self.assertRaises(exception.VolumeDriverException,
+ self.storwize_svc_common.pretreatment_before_revert,
+ vol)
+
+ @mock.patch.object(storwize_svc_common.StorwizeSSH, 'stopfcmap')
+ @mock.patch.object(storwize_svc_common.StorwizeHelpers,
+ '_get_flashcopy_mapping_attributes')
+ @mock.patch.object(storwize_svc_common.StorwizeHelpers,
+ '_get_vdisk_fc_mappings')
+ def test_pretreatment_before_revert_completed_clone(
+ self,
+ _get_vdisk_fc_mappings,
+ _get_flashcopy_mapping_attributes,
+ stopfcmap):
+ vol = 'testvol'
+ _get_vdisk_fc_mappings.return_value = ['4']
+ _get_flashcopy_mapping_attributes.return_value = {
+ 'copy_rate': '50',
+ 'progress': '100',
+ 'status': 'copying',
+ 'target_vdisk_name': 'testvol'}
+ self.storwize_svc_common.pretreatment_before_revert(vol)
+ stopfcmap.assert_called_once_with('4', split=True)
+
@ddt.ddt
class StorwizeSSHTestCase(test.TestCase):
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 72d5f24f5..43ea80b3f 100644
--- a/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py
+++ b/cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py
@@ -612,8 +612,13 @@ class StorwizeSSH(object):
'-autodelete', autodel, fc_map_id]
self.run_ssh_assert_no_output(ssh_cmd)
- def stopfcmap(self, fc_map_id):
- ssh_cmd = ['svctask', 'stopfcmap', fc_map_id]
+ def stopfcmap(self, fc_map_id, force=False, split=False):
+ ssh_cmd = ['svctask', 'stopfcmap']
+ if force:
+ ssh_cmd += ['-force']
+ if split:
+ ssh_cmd += ['-split']
+ ssh_cmd += [fc_map_id]
self.run_ssh_assert_no_output(ssh_cmd)
def rmfcmap(self, fc_map_id):
@@ -2509,6 +2514,28 @@ class StorwizeHelpers(object):
'same site as peer_pool %(peer_pool)s. ') %
{'pool': pool, 'peer_pool': peer_pool})
+ def pretreatment_before_revert(self, name):
+ mapping_ids = self._get_vdisk_fc_mappings(name)
+ for map_id in mapping_ids:
+ attrs = self._get_flashcopy_mapping_attributes(map_id)
+ if not attrs:
+ continue
+ target = attrs['target_vdisk_name']
+ copy_rate = attrs['copy_rate']
+ progress = attrs['progress']
+ status = attrs['status']
+ if status in ['copying', 'prepared'] and target == name:
+ if copy_rate != '0' and progress != '100':
+ msg = (_('Cannot start revert since fcmap %(map_id)s '
+ 'in progress, current progress is %(progress)s')
+ % {'map_id': map_id, 'progress': progress})
+ LOG.error(msg)
+ raise exception.VolumeDriverException(message=msg)
+ elif copy_rate != '0' and progress == '100':
+ LOG.debug('Split completed clone map_id=%(map_id)s fcmap',
+ {'map_id': map_id})
+ self.ssh.stopfcmap(map_id, split=True)
+
class CLIResponse(object):
"""Parse SVC CLI output and generate iterable."""
@@ -5469,6 +5496,14 @@ class StorwizeSVCCommonDriver(san.SanDriver,
if rep_type:
raise exception.InvalidInput(
reason=_('Reverting replication volume is not supported.'))
+ try:
+ self._helpers.pretreatment_before_revert(volume.name)
+ except Exception as err:
+ msg = (_("Pretreatment before revert volume %(vol)s to snapshot "
+ "%(snap)s failed due to: %(err)s.")
+ % {"vol": volume.name, "snap": snapshot.name, "err": err})
+ LOG.error(msg)
+ raise exception.VolumeBackendAPIException(data=msg)
opts = self._get_vdisk_params(volume.volume_type_id)
try:
self._helpers.run_flashcopy(