diff options
author | Zuul <zuul@review.opendev.org> | 2020-10-22 16:34:32 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2020-10-22 16:34:32 +0000 |
commit | 463c17a3f95f37c4c3edd1eadc5b474893c8adba (patch) | |
tree | 4d40a40ae46ed2db5617fcd4c76a0334e746bfdc | |
parent | ca0ebb6c925d8b6b33d9110b7dbad8dfe5142286 (diff) | |
parent | e8729dc65fdf84dea33192298d1614a585a29416 (diff) | |
download | cinder-463c17a3f95f37c4c3edd1eadc5b474893c8adba.tar.gz |
Merge "Fix revert snapshot issue" into stable/stein
-rw-r--r-- | cinder/tests/unit/volume/drivers/ibm/test_storwize_svc.py | 63 | ||||
-rw-r--r-- | cinder/volume/drivers/ibm/storwize_svc/storwize_svc_common.py | 39 |
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( |