Merge "[SVF]:Fix add volumes to GMCV group"
This commit is contained in:
commit
8e51c8dfd4
@ -10342,25 +10342,34 @@ class StorwizeSVCReplicationTestCase(test.TestCase):
|
||||
rel_info = self.driver._helpers.get_relationship_info(volume['name'])
|
||||
self.assertIsNone(rel_info)
|
||||
|
||||
def test_storwize_create_snapshot_volume_with_mirror_replica(self):
|
||||
@ddt.data(({'mirror_type': 'mm_type'}),
|
||||
({'mirror_type': 'gm_type'}),
|
||||
({'mirror_type': 'gmcv_default_type'}),
|
||||
({'mirror_type': 'gmcv_with_cps900_type'}))
|
||||
def test_storwize_create_snapshot_volume_with_mirror_replica(self,
|
||||
vol_spec):
|
||||
# Set replication target
|
||||
self.driver.configuration.set_override('replication_device',
|
||||
[self.rep_target])
|
||||
self.driver.do_setup(self.ctxt)
|
||||
rep_type = getattr(self, vol_spec['mirror_type'])
|
||||
|
||||
# Create metro mirror replication volume.
|
||||
vol1, model_update = self._create_test_volume(self.mm_type)
|
||||
vol1, model_update = self._create_test_volume(rep_type)
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
|
||||
snap = testutils.create_snapshot(self.ctxt, vol1.id)
|
||||
self.driver.create_snapshot(snap)
|
||||
|
||||
vol2 = self._generate_vol_info(self.mm_type)
|
||||
self._assert_vol_exists(snap['name'], True)
|
||||
vol2 = self._generate_vol_info(rep_type)
|
||||
model_update = self.driver.create_volume_from_snapshot(vol2, snap)
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
self._validate_replic_vol_creation(vol2)
|
||||
if "gmcv" in vol_spec['mirror_type']:
|
||||
self._validate_replic_vol_creation(vol2, isGMCV=True)
|
||||
else:
|
||||
self._validate_replic_vol_creation(vol2)
|
||||
|
||||
if self.USESIM:
|
||||
self.sim.error_injection('lsfcmap', 'speed_up')
|
||||
@ -10368,28 +10377,6 @@ class StorwizeSVCReplicationTestCase(test.TestCase):
|
||||
self.driver.delete_snapshot(snap)
|
||||
self.driver.delete_volume(vol1)
|
||||
|
||||
# Create gmcv replication volume.
|
||||
vol1, model_update = self._create_test_volume(self.gmcv_default_type)
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
self._validate_replic_vol_creation(vol1, True)
|
||||
snap = testutils.create_snapshot(self.ctxt, vol1.id)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.create_snapshot,
|
||||
snap)
|
||||
self.driver.delete_volume(vol1)
|
||||
|
||||
# gmcv with specified cycle_period_seconds
|
||||
vol1, model_update = self._create_test_volume(
|
||||
self.gmcv_with_cps900_type)
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
self._validate_replic_vol_creation(vol1, True)
|
||||
snap = testutils.create_snapshot(self.ctxt, vol1.id)
|
||||
self.assertRaises(exception.VolumeDriverException,
|
||||
self.driver.create_snapshot, snap)
|
||||
self.driver.delete_volume(vol1)
|
||||
|
||||
def test_storwize_create_cloned_volume_with_mirror_replica(self):
|
||||
# Set replication target
|
||||
self.driver.configuration.set_override('replication_device',
|
||||
|
@ -3634,16 +3634,6 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
|
||||
rep_type = self._get_volume_replicated_type(
|
||||
ctxt, None, source_vol['volume_type_id'])
|
||||
if rep_type == storwize_const.GMCV:
|
||||
# GMCV volume will have problem to failback
|
||||
# when it has flash copy relationship besides change volumes
|
||||
msg = _('create_snapshot: Create snapshot to '
|
||||
'gmcv replication volume is not allowed.')
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeDriverException(message=msg)
|
||||
|
||||
pool = volume_utils.extract_host(source_vol['host'], 'pool')
|
||||
opts = self._get_vdisk_params(source_vol['volume_type_id'])
|
||||
|
||||
@ -6285,47 +6275,71 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
"relationship of %(vol)s does not exist in "
|
||||
"backend.", {'vol': volume.id})
|
||||
model_update['status'] = fields.GroupStatus.ERROR
|
||||
elif (rccg['copy_type'] != 'empty_group' and
|
||||
(rccg['copy_type'] != rcrel['copy_type'] or
|
||||
rccg['state'] != rcrel['state'] or
|
||||
rccg['primary'] != rcrel['primary'] or
|
||||
rccg['cycling_mode'] != rcrel['cycling_mode'] or
|
||||
(rccg['cycle_period_seconds'] !=
|
||||
rcrel['cycle_period_seconds']))):
|
||||
LOG.error("Failed to update rccg %(rccg)s: remote copy "
|
||||
"type of %(vol)s is %(vol_rc_type)s, the rccg "
|
||||
"type is %(rccg_type)s. rcrel state is "
|
||||
"%(rcrel_state)s, rccg state is %(rccg_state)s. "
|
||||
"rcrel primary is %(rcrel_primary)s, rccg "
|
||||
"primary is %(rccg_primary)s. "
|
||||
"rcrel cycling mode is %(rcrel_cmode)s, rccg "
|
||||
"cycling mode is %(rccg_cmode)s. rcrel cycling "
|
||||
"period is %(rcrel_period)s, rccg cycling "
|
||||
"period is %(rccg_period)s. ",
|
||||
{'rccg': rccg_name,
|
||||
'vol': volume.id,
|
||||
'vol_rc_type': rcrel['copy_type'],
|
||||
'rccg_type': rccg['copy_type'],
|
||||
'rcrel_state': rcrel['state'],
|
||||
'rccg_state': rccg['state'],
|
||||
'rcrel_primary': rcrel['primary'],
|
||||
'rccg_primary': rccg['primary'],
|
||||
'rcrel_cmode': rcrel['cycling_mode'],
|
||||
'rccg_cmode': rccg['cycling_mode'],
|
||||
'rcrel_period': rcrel['cycle_period_seconds'],
|
||||
'rccg_period': rccg['cycle_period_seconds']})
|
||||
model_update['status'] = fields.GroupStatus.ERROR
|
||||
else:
|
||||
self._helpers.chrcrelationship(rcrel['name'], rccg_name)
|
||||
if rccg['copy_type'] == 'empty_group':
|
||||
rccg = self._helpers.get_rccg(rccg_name)
|
||||
added_vols.append({'id': volume.id,
|
||||
'group_id': group.id})
|
||||
if rccg and rccg.get('cycling_mode', None) == 'multi':
|
||||
self._helpers.stop_relationship(vol_name)
|
||||
rcrel = self._helpers.get_relationship_info(vol_name)
|
||||
if (rccg['state'] != 'empty' and
|
||||
rccg['state'] != 'consistent_stopped' or
|
||||
rccg['state'] != 'inconsistent_stopped'):
|
||||
self._helpers.stop_rccg(rccg_name)
|
||||
# To handle existing group updation, refresh rccg
|
||||
# state to avoid unnecessary stop_rccg calls.
|
||||
rccg = self._helpers.get_rccg(rccg_name)
|
||||
|
||||
if (rccg['copy_type'] != 'empty_group' and
|
||||
any(k for k in ('copy_type', 'state', 'primary',
|
||||
'cycling_mode', 'cycle_period_seconds')
|
||||
if rccg[k] != rcrel[k])):
|
||||
LOG.error("Failed to update rccg %(rccg)s: remote "
|
||||
"copy type of %(vol)s is %(vol_rc_type)s, "
|
||||
"the rccg type is %(rccg_type)s. rcrel "
|
||||
"state %(rcrel_state)s, rccg state is "
|
||||
"%(rccg_state)s rcrel primary is "
|
||||
"%(rcrel_primary)s, rccg primary is "
|
||||
"%(rccg_primary)s. rcrel cycling mode is "
|
||||
"%(rcrel_cmode)s, rccg cycling mode is "
|
||||
"%(rccg_cmode)s. rcrel cycling period is "
|
||||
"%(rcrel_period)s, rccg cycling "
|
||||
"period is %(rccg_period)s. ",
|
||||
{'rccg': rccg_name,
|
||||
'vol': volume.id,
|
||||
'vol_rc_type': rcrel['copy_type'],
|
||||
'rccg_type': rccg['copy_type'],
|
||||
'rcrel_state': rcrel['state'],
|
||||
'rccg_state': rccg['state'],
|
||||
'rcrel_primary': rcrel['primary'],
|
||||
'rccg_primary': rccg['primary'],
|
||||
'rcrel_cmode': rcrel['cycling_mode'],
|
||||
'rccg_cmode': rccg['cycling_mode'],
|
||||
'rcrel_period':
|
||||
rcrel['cycle_period_seconds'],
|
||||
'rccg_period':
|
||||
rccg['cycle_period_seconds']})
|
||||
# This rcrel updation failed ,it has to be started
|
||||
# explicitly.
|
||||
self._helpers.start_relationship(vol_name)
|
||||
model_update['status'] = fields.GroupStatus.ERROR
|
||||
else:
|
||||
self._helpers.chrcrelationship(rcrel['name'],
|
||||
rccg_name)
|
||||
if rccg['copy_type'] == 'empty_group':
|
||||
rccg = self._helpers.get_rccg(rccg_name)
|
||||
added_vols.append({'id': volume.id,
|
||||
'group_id': group.id})
|
||||
except exception.VolumeBackendAPIException as err:
|
||||
model_update['status'] = fields.GroupStatus.ERROR
|
||||
LOG.error("Failed to add the remote copy of volume %(vol)s to "
|
||||
"group. Exception: %(exception)s.",
|
||||
{'vol': volume.name, 'exception': err})
|
||||
self._helpers.start_relationship(vol_name)
|
||||
|
||||
if (rccg and len(add_volumes) > 0 and
|
||||
rccg.get('cycling_mode', None) == 'multi'):
|
||||
if rccg.get('primary', None) == 'aux':
|
||||
self._helpers.start_rccg(rccg_name, primary='aux')
|
||||
elif rccg.get('primary', None) == 'master':
|
||||
self._helpers.start_rccg(rccg_name, primary='master')
|
||||
|
||||
# Remove remote copy relationship from rccg
|
||||
removed_vols = []
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
IBM Spectrum Virtualize Family driver `Bug #1922013
|
||||
<https://bugs.launchpad.net/cinder/+bug/1922013>`_: Fixed issues in
|
||||
adding volumes to GMCV group.
|
Loading…
Reference in New Issue
Block a user