Merge "VMAX driver - Errors extending replicated volumes"
This commit is contained in:
commit
2f23983353
@ -3072,10 +3072,17 @@ class VMAXProvisionTest(test.TestCase):
|
|||||||
device_id = self.data.device_id
|
device_id = self.data.device_id
|
||||||
new_size = '3'
|
new_size = '3'
|
||||||
extra_specs = self.data.extra_specs
|
extra_specs = self.data.extra_specs
|
||||||
with mock.patch.object(self.provision.rest, 'extend_volume'):
|
with mock.patch.object(self.provision.rest, 'extend_volume'
|
||||||
|
) as mock_ex:
|
||||||
self.provision.extend_volume(array, device_id, new_size,
|
self.provision.extend_volume(array, device_id, new_size,
|
||||||
extra_specs)
|
extra_specs)
|
||||||
self.provision.rest.extend_volume.assert_called_once_with(
|
mock_ex.assert_called_once_with(
|
||||||
|
array, device_id, new_size, extra_specs)
|
||||||
|
mock_ex.reset_mock()
|
||||||
|
# Pass in rdf group
|
||||||
|
self.provision.extend_volume(array, device_id, new_size,
|
||||||
|
extra_specs, self.data.rdf_group_no)
|
||||||
|
mock_ex.assert_called_once_with(
|
||||||
array, device_id, new_size, extra_specs)
|
array, device_id, new_size, extra_specs)
|
||||||
|
|
||||||
def test_get_srp_pool_stats(self):
|
def test_get_srp_pool_stats(self):
|
||||||
@ -3167,6 +3174,15 @@ class VMAXProvisionTest(test.TestCase):
|
|||||||
target_device = self.data.device_id2
|
target_device = self.data.device_id2
|
||||||
rdf_group_name = self.data.rdf_group_name
|
rdf_group_name = self.data.rdf_group_name
|
||||||
rep_extra_specs = self.data.rep_extra_specs
|
rep_extra_specs = self.data.rep_extra_specs
|
||||||
|
# State is suspended
|
||||||
|
self.provision.break_rdf_relationship(
|
||||||
|
array, device_id, target_device,
|
||||||
|
rdf_group_name, rep_extra_specs, "Suspended")
|
||||||
|
mock_mod.assert_not_called()
|
||||||
|
mock_del.assert_called_once_with(
|
||||||
|
array, device_id, rdf_group_name)
|
||||||
|
mock_del.reset_mock()
|
||||||
|
# State is synchronized
|
||||||
self.provision.break_rdf_relationship(
|
self.provision.break_rdf_relationship(
|
||||||
array, device_id, target_device,
|
array, device_id, target_device,
|
||||||
rdf_group_name, rep_extra_specs, "Synchronized")
|
rdf_group_name, rep_extra_specs, "Synchronized")
|
||||||
|
@ -2931,9 +2931,9 @@ class VMAXCommon(object):
|
|||||||
"""Extend a replication-enabled volume.
|
"""Extend a replication-enabled volume.
|
||||||
|
|
||||||
Cannot extend volumes in a synchronization pair where the source
|
Cannot extend volumes in a synchronization pair where the source
|
||||||
and/or target arrays are running HyperMax versions < 5978, or for
|
and/or target arrays are running HyperMax versions < 5978. Must first
|
||||||
Metro-enabled volumes. Must first break the relationship, extend
|
break the relationship, extend them separately, then recreate the
|
||||||
them separately, then recreate the pair.
|
pair. Extending Metro protected volumes is not supported.
|
||||||
:param array: the array serial number
|
:param array: the array serial number
|
||||||
:param volume: the volume objcet
|
:param volume: the volume objcet
|
||||||
:param device_id: the volume device id
|
:param device_id: the volume device id
|
||||||
@ -2949,8 +2949,7 @@ class VMAXCommon(object):
|
|||||||
__, remote_array = self.get_rdf_details(array)
|
__, remote_array = self.get_rdf_details(array)
|
||||||
if self.rest.is_next_gen_array(remote_array):
|
if self.rest.is_next_gen_array(remote_array):
|
||||||
ode_replication = True
|
ode_replication = True
|
||||||
if (self.utils.is_metro_device(self.rep_config, extra_specs)
|
if self.utils.is_metro_device(self.rep_config, extra_specs):
|
||||||
and not self.allow_delete_metro):
|
|
||||||
allow_extend = False
|
allow_extend = False
|
||||||
if allow_extend is True or ode_replication is True:
|
if allow_extend is True or ode_replication is True:
|
||||||
try:
|
try:
|
||||||
@ -2960,18 +2959,16 @@ class VMAXCommon(object):
|
|||||||
array, volume, device_id))
|
array, volume, device_id))
|
||||||
rep_extra_specs = self._get_replication_extra_specs(
|
rep_extra_specs = self._get_replication_extra_specs(
|
||||||
extra_specs, self.rep_config)
|
extra_specs, self.rep_config)
|
||||||
|
lock_rdf_group = rdf_group
|
||||||
if not ode_replication:
|
if not ode_replication:
|
||||||
# Volume must be removed from replication (storage) group
|
# Volume must be removed from replication (storage) group
|
||||||
# before the replication relationship can be ended (cannot
|
# before the replication relationship can be ended (cannot
|
||||||
# have a mix of replicated and non-replicated volumes as
|
# have a mix of replicated and non-replicated volumes as
|
||||||
# the SRDF groups become unmanageable), but
|
# the SRDF groups become unmanageable)
|
||||||
# leave the vol in metro management group for now
|
lock_rdf_group = None
|
||||||
metro_grp = self.utils.get_async_rdf_managed_grp_name(
|
|
||||||
self.rep_config) if self.utils.is_metro_device(
|
|
||||||
self.rep_config, rep_extra_specs) else None
|
|
||||||
self.masking.remove_and_reset_members(
|
self.masking.remove_and_reset_members(
|
||||||
array, volume, device_id, volume_name,
|
array, volume, device_id, volume_name,
|
||||||
extra_specs, False, async_grp=metro_grp)
|
extra_specs, False)
|
||||||
|
|
||||||
# Repeat on target side
|
# Repeat on target side
|
||||||
self.masking.remove_and_reset_members(
|
self.masking.remove_and_reset_members(
|
||||||
@ -2979,17 +2976,9 @@ class VMAXCommon(object):
|
|||||||
rep_extra_specs, False)
|
rep_extra_specs, False)
|
||||||
|
|
||||||
LOG.info("Breaking replication relationship...")
|
LOG.info("Breaking replication relationship...")
|
||||||
if self.utils.is_metro_device(
|
self.provision.break_rdf_relationship(
|
||||||
self.rep_config, rep_extra_specs):
|
array, device_id, target_device, rdf_group,
|
||||||
rep_extra_specs['allow_del_metro'] = (
|
rep_extra_specs, pair_state)
|
||||||
self.allow_delete_metro)
|
|
||||||
self._cleanup_metro_target(
|
|
||||||
array, device_id, target_device,
|
|
||||||
rdf_group, rep_extra_specs)
|
|
||||||
else:
|
|
||||||
self.provision.break_rdf_relationship(
|
|
||||||
array, device_id, target_device, rdf_group,
|
|
||||||
rep_extra_specs, pair_state)
|
|
||||||
|
|
||||||
# Extend the target volume
|
# Extend the target volume
|
||||||
LOG.info("Extending target volume...")
|
LOG.info("Extending target volume...")
|
||||||
@ -2997,13 +2986,14 @@ class VMAXCommon(object):
|
|||||||
r2_size = self.rest.get_size_of_device_on_array(
|
r2_size = self.rest.get_size_of_device_on_array(
|
||||||
remote_array, target_device)
|
remote_array, target_device)
|
||||||
if int(r2_size) < int(new_size):
|
if int(r2_size) < int(new_size):
|
||||||
self.provision.extend_volume(remote_array, target_device,
|
self.provision.extend_volume(
|
||||||
new_size, rep_extra_specs)
|
remote_array, target_device, new_size,
|
||||||
|
rep_extra_specs, lock_rdf_group)
|
||||||
|
|
||||||
# Extend the source volume
|
# Extend the source volume
|
||||||
LOG.info("Extending source volume...")
|
LOG.info("Extending source volume...")
|
||||||
self.provision.extend_volume(
|
self.provision.extend_volume(
|
||||||
array, device_id, new_size, extra_specs)
|
array, device_id, new_size, extra_specs, lock_rdf_group)
|
||||||
|
|
||||||
if not ode_replication:
|
if not ode_replication:
|
||||||
# Re-create replication relationship
|
# Re-create replication relationship
|
||||||
@ -3026,9 +3016,9 @@ class VMAXCommon(object):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
exception_message = (_(
|
exception_message = (_(
|
||||||
"Extending a replicated volume is not "
|
"Extending a replicated volume is not permitted on this "
|
||||||
"permitted on this backend. Please contact "
|
"backend. Please contact your administrator. Note that "
|
||||||
"your administrator."))
|
"you cannot extend SRDF/Metro protected volumes."))
|
||||||
LOG.error(exception_message)
|
LOG.error(exception_message)
|
||||||
raise exception.VolumeBackendAPIException(data=exception_message)
|
raise exception.VolumeBackendAPIException(data=exception_message)
|
||||||
|
|
||||||
|
@ -344,20 +344,29 @@ class VMAXProvision(object):
|
|||||||
list_volume_pairs=list_device_pairs)
|
list_volume_pairs=list_device_pairs)
|
||||||
self.delete_volume_snap(array, snap_name, source_devices)
|
self.delete_volume_snap(array, snap_name, source_devices)
|
||||||
|
|
||||||
def extend_volume(self, array, device_id, new_size, extra_specs):
|
def extend_volume(self, array, device_id, new_size, extra_specs,
|
||||||
|
rdf_group=None):
|
||||||
"""Extend a volume.
|
"""Extend a volume.
|
||||||
|
|
||||||
:param array: the array serial number
|
:param array: the array serial number
|
||||||
:param device_id: the volume device id
|
:param device_id: the volume device id
|
||||||
:param new_size: the new size (GB)
|
:param new_size: the new size (GB)
|
||||||
:param extra_specs: the extra specifications
|
:param extra_specs: the extra specifications
|
||||||
|
:param rdf_group: the rdf group number, if required
|
||||||
:returns: status_code
|
:returns: status_code
|
||||||
"""
|
"""
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
self.rest.extend_volume(array, device_id, new_size, extra_specs)
|
if rdf_group:
|
||||||
LOG.debug("Extend VMAX volume took: %(delta)s H:MM:SS.",
|
@coordination.synchronized('emc-rg-{rdf_group}')
|
||||||
{'delta': self.utils.get_time_delta(start_time,
|
def _extend_replicated_volume(rdf_group):
|
||||||
time.time())})
|
self.rest.extend_volume(array, device_id,
|
||||||
|
new_size, extra_specs)
|
||||||
|
_extend_replicated_volume(rdf_group)
|
||||||
|
else:
|
||||||
|
self.rest.extend_volume(array, device_id, new_size, extra_specs)
|
||||||
|
LOG.debug("Extend VMAX volume took: %(delta)s H:MM:SS.",
|
||||||
|
{'delta': self.utils.get_time_delta(start_time,
|
||||||
|
time.time())})
|
||||||
|
|
||||||
def get_srp_pool_stats(self, array, array_info):
|
def get_srp_pool_stats(self, array, array_info):
|
||||||
"""Get the srp capacity stats.
|
"""Get the srp capacity stats.
|
||||||
@ -495,8 +504,11 @@ class VMAXProvision(object):
|
|||||||
self.rest.wait_for_rdf_consistent_state(
|
self.rest.wait_for_rdf_consistent_state(
|
||||||
array, device_id, target_device,
|
array, device_id, target_device,
|
||||||
rep_extra_specs, state)
|
rep_extra_specs, state)
|
||||||
self.rest.modify_rdf_device_pair(
|
if state.lower() == utils.RDF_SUSPENDED_STATE:
|
||||||
array, device_id, rdf_group, rep_extra_specs, suspend=True)
|
LOG.info("RDF pair is already suspended")
|
||||||
|
else:
|
||||||
|
self.rest.modify_rdf_device_pair(
|
||||||
|
array, device_id, rdf_group, rep_extra_specs, suspend=True)
|
||||||
self.delete_rdf_pair(array, device_id, rdf_group,
|
self.delete_rdf_pair(array, device_id, rdf_group,
|
||||||
target_device, rep_extra_specs)
|
target_device, rep_extra_specs)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user