Merge "Dell PowerMax: RDF consistency exempt"
This commit is contained in:
@@ -2085,12 +2085,14 @@ class PowerMaxRestTest(test.TestCase):
|
||||
rdf_group_no = self.data.rdf_group_no_1
|
||||
sg_name = self.data.default_sg_re_enabled
|
||||
rep_extra_specs = self.data.rep_extra_specs
|
||||
|
||||
self.rest.srdf_suspend_replication(
|
||||
array_id, sg_name, rdf_group_no, rep_extra_specs)
|
||||
# Replication mode in this test is synchronous, so the expecation
|
||||
# is that the consistency exempt flag is false.
|
||||
mck_modify.assert_called_once_with(
|
||||
array_id, rdf_group_no, sg_name,
|
||||
{'suspend': {'force': 'true'}, 'action': 'Suspend'},
|
||||
{'suspend': {'force': 'true', 'consExempt': 'false'},
|
||||
'action': 'Suspend'},
|
||||
rep_extra_specs, 'Suspend SRDF Group Replication')
|
||||
|
||||
@mock.patch.object(rest.PowerMaxRest, 'srdf_modify_group')
|
||||
@@ -2102,12 +2104,14 @@ class PowerMaxRestTest(test.TestCase):
|
||||
rdf_group_no = self.data.rdf_group_no_1
|
||||
sg_name = self.data.default_sg_re_enabled
|
||||
rep_extra_specs = self.data.rep_extra_specs
|
||||
|
||||
self.rest.srdf_suspend_replication(
|
||||
array_id, sg_name, rdf_group_no, rep_extra_specs)
|
||||
# Replication mode in this test is synchronous, so the expecation
|
||||
# is that the consistency exempt flag is false.
|
||||
mck_modify.assert_called_once_with(
|
||||
array_id, rdf_group_no, sg_name,
|
||||
{'suspend': {'force': 'true'}, 'action': 'Suspend'},
|
||||
{'suspend': {'force': 'true', 'consExempt': 'false'},
|
||||
'action': 'Suspend'},
|
||||
rep_extra_specs, 'Suspend SRDF Group Replication')
|
||||
|
||||
@mock.patch.object(rest.PowerMaxRest, 'srdf_modify_group')
|
||||
|
@@ -2906,21 +2906,6 @@ class PowerMaxRest(object):
|
||||
number = None
|
||||
return number
|
||||
|
||||
def _get_async_payload_info(self, array, rdf_group_no):
|
||||
"""Get the payload details for an async create pair.
|
||||
|
||||
:param array: the array serial number
|
||||
:param rdf_group_no: the rdf group number
|
||||
:returns: payload_update
|
||||
"""
|
||||
num_vols, payload_update = 0, {}
|
||||
rdfg_details = self.get_rdf_group(array, rdf_group_no)
|
||||
if rdfg_details is not None and rdfg_details.get('numDevices'):
|
||||
num_vols = int(rdfg_details['numDevices'])
|
||||
if num_vols > 0:
|
||||
payload_update = {'exempt': 'true'}
|
||||
return payload_update
|
||||
|
||||
def get_metro_payload_info(self, array, payload,
|
||||
rdf_group_no, extra_specs, next_gen):
|
||||
"""Get the payload details for a metro active create pair.
|
||||
@@ -3026,15 +3011,48 @@ class PowerMaxRest(object):
|
||||
|
||||
if group_state:
|
||||
group_state = [x.lower() for x in group_state]
|
||||
|
||||
if len(group_state) == 1 and utils.RDF_SUSPENDED_STATE in group_state:
|
||||
LOG.info('SRDF Group %(grp_num)s is already in a suspended state',
|
||||
{'grp_num': rdf_group_no})
|
||||
else:
|
||||
cons_exempt = self._get_cons_exempt(
|
||||
array_id, storage_group, rdf_group_no,
|
||||
rep_extra_specs['rep_mode'])
|
||||
payload = {"suspend": {"force": "true"}, "action": "Suspend"}
|
||||
payload["suspend"]["consExempt"] = (
|
||||
"true" if cons_exempt else "false")
|
||||
self.srdf_modify_group(
|
||||
array_id, rdf_group_no, storage_group,
|
||||
{"suspend": {"force": "true"}, "action": "Suspend"},
|
||||
rep_extra_specs, 'Suspend SRDF Group Replication')
|
||||
payload, rep_extra_specs,
|
||||
'Suspend SRDF Group Replication')
|
||||
|
||||
def _get_cons_exempt(self, array_id, storage_group, rdf_group_no,
|
||||
rep_mode=None):
|
||||
"""Get the consistency exempt flag for a storage group.
|
||||
|
||||
:param array_id: array serial number
|
||||
:param storage_group: storage group name
|
||||
:param rdf_group_no: RDF group number
|
||||
:param rep_mode: Replication mode of the SRDF session
|
||||
:returns: A boolean indicating if consistency is exempt
|
||||
"""
|
||||
if not rep_mode:
|
||||
return False
|
||||
|
||||
resource = ('storagegroup/%(sg)s/rdf_group/%(rdfg)s' % {
|
||||
'sg': storage_group, 'rdfg': rdf_group_no})
|
||||
rdf_group = self.get_resource(array_id, REPLICATION, resource)
|
||||
modes = list(rep_mode)
|
||||
|
||||
if rdf_group and rdf_group.get('modes'):
|
||||
modes.append(rdf_group.get('modes'))
|
||||
# Ensure we don't see the error message:
|
||||
# "A problem occurred modifying the Storage Group
|
||||
# SRDF Group resource: The device is not in
|
||||
# asynchronous mode"
|
||||
cons_exempt = utils.REP_ASYNC in modes
|
||||
LOG.debug("Consistency exempt: %s", cons_exempt)
|
||||
return cons_exempt
|
||||
|
||||
def srdf_resume_replication(self, array_id, storage_group, rdf_group_no,
|
||||
rep_extra_specs, async_call=True):
|
||||
|
17
releasenotes/notes/bp-dell-powermax-consistency-exempt.yaml
Normal file
17
releasenotes/notes/bp-dell-powermax-consistency-exempt.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Dell PowerMax Driver: use consistency exempt flag consistently
|
||||
PowerMax allows volumes to be added, removed, or suspended without
|
||||
affecting the state of the SRDF/A or SRDF/Metro session or requiring
|
||||
that other volumes in the session be suspended. Known as --exempt for
|
||||
symcli and editStorageGroupActionParam in the PowerMax REST API,
|
||||
this capability is available for an SRDF group supporting an active
|
||||
SRDF/A session or an active SRDF/Metro session.
|
||||
|
||||
The PowerMax Cinder driver currently uses the exempt flag when
|
||||
volumes are added to SRDF groups, but not when volumes are
|
||||
removed. This incurs an unnecessary performance penalty that is
|
||||
resolved by this change.
|
||||
|
||||
Blueprint: dell-powermax-srdf-exempt
|
Reference in New Issue
Block a user