[Storwize] Option to retain the auxiliary volume

If storwize svc backend parameter 'storwize_svc_retain_aux_volume'
is set to True, the secondary volume will not be deleted(retained)
when the primary volume with replication enabled is deleted
or retyped from mirror to non-mirror state.

Change-Id: I8d56376231412b5b6191ff10035642e84b3daf4b
This commit is contained in:
venkatakrishnathumu 2020-08-21 06:37:36 +00:00
parent 9ae4e48279
commit 3b0e9e0cda
3 changed files with 164 additions and 8 deletions

View File

@ -9569,6 +9569,134 @@ class StorwizeSVCReplicationTestCase(test.TestCase):
get_relationship_info.assert_called_once_with(fake_name)
delete_relationship.assert_called_once_with(fake_name)
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'delete_vdisk')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'delete_relationship')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'get_relationship_info')
def test_retain_target_volume(self, get_relationship_info,
delete_relationship,
delete_vdisk):
# Set replication target.
self.driver.configuration.set_override('replication_device',
[self.rep_target])
self.driver.do_setup(self.ctxt)
fake_name = 'volume-%s' % fake.VOLUME_ID
target_volume_fake_name = (
storwize_const.REPLICA_AUX_VOL_PREFIX + fake_name)
target_change_fake_name = (
storwize_const.REPLICA_CHG_VOL_PREFIX + target_volume_fake_name)
get_relationship_info.return_value = {'aux_vdisk_name':
fake_name}
self.driver._helpers.delete_rc_volume(fake_name,
target_vol=True,
retain_aux_volume=True)
get_relationship_info.assert_called_once_with(target_volume_fake_name)
delete_relationship.assert_called_once_with(target_volume_fake_name)
calls = [mock.call(target_change_fake_name, force_delete=False,
force_unmap=True)]
delete_vdisk.assert_has_calls(calls, any_order=True)
self.assertEqual(1, delete_vdisk.call_count)
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'delete_vdisk')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'delete_relationship')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'get_relationship_info')
def test_retain_target_volume_invalid_parameters_1(
self, get_relationship_info,
delete_relationship,
delete_vdisk):
# Set replication target.
self.driver.configuration.set_override('replication_device',
[self.rep_target])
self.driver.do_setup(self.ctxt)
fake_name = 'volume-%s' % fake.VOLUME_ID
master_change_fake_name = (
storwize_const.REPLICA_CHG_VOL_PREFIX + fake_name)
get_relationship_info.return_value = {'aux_vdisk_name':
fake_name}
self.driver._helpers.delete_rc_volume(fake_name,
target_vol=False,
retain_aux_volume=True)
get_relationship_info.assert_called_once_with(fake_name)
delete_relationship.assert_called_once_with(fake_name)
calls = [mock.call(master_change_fake_name, force_delete=False,
force_unmap=True),
mock.call(fake_name, force_delete=False, force_unmap=True)]
delete_vdisk.assert_has_calls(calls, any_order=True)
self.assertEqual(2, delete_vdisk.call_count)
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'delete_vdisk')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'delete_relationship')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'get_relationship_info')
def test_retain_target_volume_invalid_parameters_2(
self, get_relationship_info,
delete_relationship,
delete_vdisk):
# Set replication target.
self.driver.configuration.set_override('replication_device',
[self.rep_target])
self.driver.do_setup(self.ctxt)
fake_name = 'volume-%s' % fake.VOLUME_ID
target_volume_fake_name = (
storwize_const.REPLICA_AUX_VOL_PREFIX + fake_name)
target_change_fake_name = (
storwize_const.REPLICA_CHG_VOL_PREFIX + target_volume_fake_name)
get_relationship_info.return_value = {'aux_vdisk_name':
fake_name}
self.driver._helpers.delete_rc_volume(fake_name,
target_vol=True,
retain_aux_volume=False)
get_relationship_info.assert_called_once_with(target_volume_fake_name)
delete_relationship.assert_called_once_with(target_volume_fake_name)
calls = [mock.call(target_change_fake_name, force_delete=False,
force_unmap=True),
mock.call(target_volume_fake_name, force_delete=False,
force_unmap=True)]
delete_vdisk.assert_has_calls(calls, any_order=True)
self.assertEqual(2, delete_vdisk.call_count)
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'delete_vdisk')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'delete_relationship')
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
'get_relationship_info')
def test_retain_target_volume_invalid_parameters_3(
self, get_relationship_info,
delete_relationship,
delete_vdisk):
# Set replication target.
self.driver.configuration.set_override('replication_device',
[self.rep_target])
self.driver.do_setup(self.ctxt)
fake_name = 'volume-%s' % fake.VOLUME_ID
master_change_fake_name = (
storwize_const.REPLICA_CHG_VOL_PREFIX + fake_name)
get_relationship_info.return_value = {'aux_vdisk_name':
fake_name}
self.driver._helpers.delete_rc_volume(fake_name,
target_vol=False,
retain_aux_volume=False)
get_relationship_info.assert_called_once_with(fake_name)
delete_relationship.assert_called_once_with(fake_name)
calls = [mock.call(master_change_fake_name, force_delete=False,
force_unmap=True),
mock.call(fake_name, force_delete=False, force_unmap=True)]
delete_vdisk.assert_has_calls(calls, any_order=True)
self.assertEqual(2, delete_vdisk.call_count)
def test_storwize_failover_host_backend_error(self):
self.driver.configuration.set_override('replication_device',
[self.rep_target])

View File

@ -147,6 +147,13 @@ storwize_svc_opts = [
'performs a complete cycle at most once each period. '
'The default is 300 seconds, and the valid seconds '
'are 60-86400.'),
cfg.BoolOpt('storwize_svc_retain_aux_volume',
default=False,
help='Enable or disable retaining of aux volume on secondary '
'storage during delete of the volume on primary storage '
'or moving the primary volume from mirror to non-mirror '
'with replication enabled. This option is valid for '
'SVC.'),
]
CONF = cfg.CONF
@ -2196,7 +2203,7 @@ class StorwizeHelpers(object):
return relationship[0] if len(relationship) > 0 else None
def delete_rc_volume(self, volume_name, target_vol=False,
force_unmap=True):
force_unmap=True, retain_aux_volume=False):
vol_name = volume_name
if target_vol:
vol_name = storwize_const.REPLICA_AUX_VOL_PREFIX + volume_name
@ -2210,9 +2217,15 @@ class StorwizeHelpers(object):
storwize_const.REPLICA_CHG_VOL_PREFIX + vol_name,
force_unmap=force_unmap,
force_delete=False)
self.delete_vdisk(vol_name,
force_unmap=force_unmap,
force_delete=False)
# We want to retain the aux volume after retyping
# from mirror to non mirror storage template or
# on delete of the primary volume based on user's
# choice of config value for storwize_svc_retain_aux_volume.
# Default value is False.
if (retain_aux_volume is False and target_vol) or not target_vol:
self.delete_vdisk(vol_name,
force_unmap=force_unmap,
force_delete=False)
except Exception as e:
msg = (_('Unable to delete the volume for '
'volume %(vol)s. Exception: %(err)s.'),
@ -3132,7 +3145,11 @@ class StorwizeSVCCommonDriver(san.SanDriver,
if rep_type:
if self._aux_backend_helpers:
self._aux_backend_helpers.delete_rc_volume(
volume['name'], target_vol=True, force_unmap=force_unmap)
volume['name'],
target_vol=True,
force_unmap=force_unmap,
retain_aux_volume=self.configuration.safe_get(
'storwize_svc_retain_aux_volume'))
if not self._active_backend_id:
self._master_backend_helpers.delete_rc_volume(
volume['name'], force_unmap=force_unmap)
@ -4890,9 +4907,12 @@ class StorwizeSVCCommonDriver(san.SanDriver,
force_unmap = True
if old_rep_type and not new_rep_type:
self._aux_backend_helpers.delete_rc_volume(volume['name'],
target_vol=True,
force_unmap=force_unmap)
self._aux_backend_helpers.delete_rc_volume(
volume['name'],
target_vol=True,
force_unmap=force_unmap,
retain_aux_volume=self.configuration.safe_get(
'storwize_svc_retain_aux_volume'))
if storwize_const.GMCV == old_rep_type:
self._helpers.delete_vdisk(
storwize_const.REPLICA_CHG_VOL_PREFIX + volume['name'],

View File

@ -0,0 +1,8 @@
---
features:
- |
Added the option ``storwize_svc_retain_aux_volume`` to IBM Storwize Driver
which takes ``True`` or ``False``. This option is to enable or disable
retaining of auxiliary volume on secondary storage during delete of the
volume on primary storage or moving the primary volume from mirror to
non-mirror with replication enabled. The default value is ``False``.