[SVf] : Enable support for mirror-pool option for replication volume-type
[Spectrum Virtualize family] Mirror-pool option is supported from SVC- Flashsystem, but was blocked in cinder IBM SVC driver code. As this is supported from the storage, needed to enable this from the IBM SVf driver code making sure volume operations do not break. Closes-Bug: #2003300 Change-Id: I4f2adace8cca0d4f7ecbba38257f43a300b3a4ca
This commit is contained in:
@@ -5747,6 +5747,7 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
|
||||
'flashcopy_rate': 49,
|
||||
'clean_rate': 50,
|
||||
'mirror_pool': None,
|
||||
'aux_mirror_pool': None,
|
||||
'volume_topology': None,
|
||||
'peer_pool': None,
|
||||
'storwize_portset': None,
|
||||
@@ -11797,21 +11798,6 @@ class StorwizeSVCReplicationTestCase(test.TestCase):
|
||||
self.driver._aux_backend_helpers)
|
||||
self.assertTrue(self.driver._replica_enabled)
|
||||
|
||||
@mock.patch.object(storwize_svc_common.StorwizeHelpers,
|
||||
'create_vdisk')
|
||||
def test_storwize_svc_create_stretch_volume_with_replication(self,
|
||||
create_vdisk):
|
||||
spec = {'mirror_pool': 'openstack1',
|
||||
'replication_enabled': '<is> True',
|
||||
'replication_type': '<in> global'
|
||||
}
|
||||
vol_type = self._create_replica_volume_type(
|
||||
False, opts=spec, vol_type_name='test_type')
|
||||
vol = self._generate_vol_info(vol_type)
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.driver.create_volume, vol)
|
||||
self.assertFalse(create_vdisk.called)
|
||||
|
||||
def test_storwize_create_volume_with_mirror_replication(self):
|
||||
# Set replication target.
|
||||
self.driver.configuration.set_override('replication_device',
|
||||
@@ -11855,6 +11841,105 @@ class StorwizeSVCReplicationTestCase(test.TestCase):
|
||||
self._create_test_volume,
|
||||
self.gmcv_with_cps86401_type)
|
||||
|
||||
def test_storwize_create_replication_volume_with_mirror_pool(self):
|
||||
"""Create a replication volume with mirror_pool option"""
|
||||
# Set replication target
|
||||
self.driver.configuration.set_override('replication_device',
|
||||
[self.rep_target])
|
||||
self.driver.do_setup(self.ctxt)
|
||||
|
||||
# Create MM volume with mirror_pool
|
||||
spec = {'replication_enabled': '<is> True',
|
||||
'replication_type': '<in> metro',
|
||||
'drivers:mirror_pool': 'openstack1'}
|
||||
mm_mirror_type = self._create_replica_volume_type(
|
||||
False, opts=spec, vol_type_name='mm_mirror_type')
|
||||
mm_volume, model_update = self._create_test_volume(
|
||||
mm_mirror_type)
|
||||
# Check the parameters and their values
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
self.assertEqual('inconsistent_copying',
|
||||
model_update['metadata']['Mirroring State'])
|
||||
# Delete the MM volume
|
||||
self.driver.delete_volume(mm_volume)
|
||||
|
||||
# Create GM volume with mirror_pool
|
||||
spec = {'replication_enabled': '<is> True',
|
||||
'replication_type': '<in> global',
|
||||
'drivers:mirror_pool': 'openstack1'}
|
||||
gm_mirror_type = self._create_replica_volume_type(
|
||||
False, opts=spec, vol_type_name='gm_mirror_type')
|
||||
gm_volume, model_update = self._create_test_volume(
|
||||
gm_mirror_type)
|
||||
# Check the parameters and their values
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
self.assertEqual('inconsistent_copying',
|
||||
model_update['metadata']['Mirroring State'])
|
||||
# Delete the GM volume
|
||||
self.driver.delete_volume(gm_volume)
|
||||
|
||||
def test_storwize_retype_mm_replication_volume_with_mirror_pool(self):
|
||||
"""Create a MM replication volume with mirror_pool option and retype
|
||||
|
||||
it to MM replication volume type without mirror pool option
|
||||
"""
|
||||
# Set replication target
|
||||
self.driver.configuration.set_override('replication_device',
|
||||
[self.rep_target])
|
||||
self.driver.do_setup(self.ctxt)
|
||||
host = {'host': 'openstack@svc#openstack'}
|
||||
|
||||
# Create MM volume
|
||||
mm_volume, model_update = self._create_test_volume(self.mm_type)
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
|
||||
# Create MM volume-type with mirror_pool option
|
||||
spec = {'replication_enabled': '<is> True',
|
||||
'replication_type': '<in> metro',
|
||||
'drivers:mirror_pool': 'openstack1'}
|
||||
mm_mirror_type = self._create_replica_volume_type(
|
||||
False, opts=spec, vol_type_name='mm_mirror_type')
|
||||
|
||||
# Retype the MM-volume to volume-type with mirror_pool option
|
||||
diff, _equal = volume_types.volume_types_diff(
|
||||
self.ctxt, mm_mirror_type['id'], self.mm_type['id'])
|
||||
retyped, model_update = self.driver.retype(
|
||||
self.ctxt, mm_volume, mm_mirror_type, diff, host)
|
||||
self.driver.delete_volume(mm_volume)
|
||||
|
||||
def test_storwize_retype_gm_replication_volume_with_mirror_pool(self):
|
||||
"""Create a GM replication volume with mirror_pool option and retype
|
||||
|
||||
it to GM replication volume type without mirror pool option
|
||||
"""
|
||||
# Set replication target
|
||||
self.driver.configuration.set_override('replication_device',
|
||||
[self.rep_target])
|
||||
self.driver.do_setup(self.ctxt)
|
||||
host = {'host': 'openstack@svc#openstack'}
|
||||
|
||||
# Create GM volume
|
||||
gm_volume, model_update = self._create_test_volume(self.gm_type)
|
||||
self.assertEqual(fields.ReplicationStatus.ENABLED,
|
||||
model_update['replication_status'])
|
||||
|
||||
# Create GM volume-type with mirror_pool option
|
||||
spec = {'replication_enabled': '<is> True',
|
||||
'replication_type': '<in> global',
|
||||
'drivers:mirror_pool': 'openstack1'}
|
||||
gm_mirror_type = self._create_replica_volume_type(
|
||||
False, opts=spec, vol_type_name='gm_mirror_type')
|
||||
|
||||
# Retype the GM-volume to volume-type with mirror_pool option
|
||||
diff, _equal = volume_types.volume_types_diff(
|
||||
self.ctxt, gm_mirror_type['id'], self.gm_type['id'])
|
||||
retyped, model_update = self.driver.retype(
|
||||
self.ctxt, gm_volume, gm_mirror_type, diff, host)
|
||||
self.driver.delete_volume(gm_volume)
|
||||
|
||||
@ddt.data((None, None),
|
||||
(None, SVC_TARGET_CHILD_POOL), (SVC_SOURCE_CHILD_POOL, None),
|
||||
(SVC_SOURCE_CHILD_POOL, SVC_TARGET_CHILD_POOL))
|
||||
|
||||
@@ -102,6 +102,7 @@ class StorwizeSVCReplicationGlobalMirror(StorwizeSVCReplication):
|
||||
src_attr = self.driver._helpers.get_vdisk_attributes(
|
||||
vref['name'])
|
||||
opts['iogrp'] = src_attr['IO_group_id']
|
||||
opts['mirror_pool'] = None
|
||||
try:
|
||||
self.target_helpers.create_vdisk(target_vol_name,
|
||||
str(vref['size']),
|
||||
|
||||
@@ -132,6 +132,10 @@ storwize_svc_opts = [
|
||||
default=None,
|
||||
help='Specifies the name of the pool in which mirrored copy '
|
||||
'is stored. Example: "pool2"'),
|
||||
cfg.StrOpt('storwize_svc_aux_mirror_pool',
|
||||
default=None,
|
||||
help='Specifies the name of the pool in which mirrored copy '
|
||||
'is stored for aux volume. Example: "pool2"'),
|
||||
cfg.StrOpt('storwize_portset',
|
||||
default=None,
|
||||
help='Specifies the name of the portset in which '
|
||||
@@ -1671,6 +1675,7 @@ class StorwizeHelpers(object):
|
||||
'flashcopy_rate': config.storwize_svc_flashcopy_rate,
|
||||
'clean_rate': config.storwize_svc_clean_rate,
|
||||
'mirror_pool': config.storwize_svc_mirror_pool,
|
||||
'aux_mirror_pool': config.storwize_svc_aux_mirror_pool,
|
||||
'volume_topology': None,
|
||||
'peer_pool': config.storwize_peer_pool,
|
||||
'storwize_portset': config.storwize_portset,
|
||||
@@ -2013,7 +2018,7 @@ class StorwizeHelpers(object):
|
||||
else:
|
||||
params.extend(['-grainsize', str(opts['grainsize'])])
|
||||
|
||||
if add_copies and opts['mirror_pool']:
|
||||
if add_copies and (opts['mirror_pool'] or opts['aux_mirror_pool']):
|
||||
params.extend(['-copies', '2'])
|
||||
|
||||
if not is_dr_pool:
|
||||
@@ -2032,6 +2037,15 @@ class StorwizeHelpers(object):
|
||||
# mdiskgrp for mirror volume
|
||||
mdiskgrp = '%s:%s' % (pool, opts['mirror_pool'])
|
||||
|
||||
if opts['aux_mirror_pool']:
|
||||
if not self.is_pool_defined(opts['aux_mirror_pool']):
|
||||
raise exception.InvalidInput(
|
||||
reason=_('The pool %s in which aux mirrored copy is '
|
||||
'stored is invalid') % opts['aux_mirror_pool'])
|
||||
# The syntax of pool SVC expects is pool:aux_mirror_pool in
|
||||
# mdiskgrp for aux mirror volume
|
||||
mdiskgrp = '%s:%s' % (pool, opts['aux_mirror_pool'])
|
||||
|
||||
is_dr_pool = False
|
||||
if opts['rsize'] != -1:
|
||||
is_dr_pool = self.is_volume_type_dr_pools(pool, opts)
|
||||
@@ -2039,7 +2053,8 @@ class StorwizeHelpers(object):
|
||||
self.check_data_reduction_pool_params(opts)
|
||||
params = self._get_vdisk_create_params(
|
||||
opts, is_dr_pool,
|
||||
add_copies=True if opts['mirror_pool'] else False)
|
||||
add_copies=True if (opts['mirror_pool'] or opts['aux_mirror_pool'])
|
||||
else False)
|
||||
self.ssh.mkvdisk(name, size, units, mdiskgrp, opts, params)
|
||||
LOG.debug('Leave: _create_vdisk: volume %s.', name)
|
||||
|
||||
@@ -3932,12 +3947,9 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
model_update = self._update_replication_properties(ctxt, volume,
|
||||
model_update)
|
||||
else:
|
||||
if opts['mirror_pool'] and rep_type:
|
||||
reason = _('Create mirror volume with replication enabled is '
|
||||
'not supported.')
|
||||
raise exception.InvalidInput(reason=reason)
|
||||
opts['iogrp'] = self._helpers.select_io_group(self._state,
|
||||
opts, pool)
|
||||
opts['aux_mirror_pool'] = None
|
||||
self._helpers.create_vdisk(volume['name'], str(volume['size']),
|
||||
'gb', pool, opts)
|
||||
if opts['qos']:
|
||||
@@ -5709,6 +5721,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
vdisk_changes,
|
||||
new_opts, self._state)
|
||||
|
||||
# flake8: noqa: C901
|
||||
def retype(self, ctxt, volume, new_type, diff, host):
|
||||
"""Convert the volume to be of the new type.
|
||||
|
||||
@@ -5745,6 +5758,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
vdisk_changes = []
|
||||
need_copy = False
|
||||
change_mirror = False
|
||||
aux_change_mirror = False
|
||||
|
||||
for key in all_keys:
|
||||
if old_opts[key] != new_opts[key]:
|
||||
@@ -5762,6 +5776,9 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
if old_opts['mirror_pool'] != new_opts['mirror_pool']:
|
||||
change_mirror = True
|
||||
|
||||
if old_opts['aux_mirror_pool'] != new_opts['aux_mirror_pool']:
|
||||
aux_change_mirror = True
|
||||
|
||||
# Check if retype affects volume replication
|
||||
model_update = dict()
|
||||
new_rep_type = self._get_specs_replicated_type(new_type)
|
||||
@@ -5881,6 +5898,8 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
self._helpers.delete_vdisk(
|
||||
storwize_const.REPLICA_CHG_VOL_PREFIX + volume['name'],
|
||||
force_unmap=force_unmap, force_delete=False)
|
||||
if aux_change_mirror:
|
||||
aux_change_mirror = False
|
||||
model_update['replication_status'] = (
|
||||
fields.ReplicationStatus.DISABLED)
|
||||
model_update['replication_driver_data'] = None
|
||||
@@ -5907,6 +5926,27 @@ class StorwizeSVCCommonDriver(san.SanDriver,
|
||||
model_update = self._update_replication_properties(ctxt, volume,
|
||||
model_update)
|
||||
|
||||
if aux_change_mirror:
|
||||
target_volume, rel_info = (
|
||||
self._helpers.get_target_volume_information(volume))
|
||||
aux_copies = self._aux_backend_helpers.get_vdisk_copies(
|
||||
target_volume)
|
||||
if (old_rep_type and new_rep_type) or (not old_rep_type
|
||||
and new_rep_type):
|
||||
# retype from non-mirror-rep to mirror-rep
|
||||
if (not old_opts['aux_mirror_pool'] and
|
||||
new_opts['aux_mirror_pool']):
|
||||
self._aux_backend_helpers.add_vdisk_copy(
|
||||
target_volume, new_opts['aux_mirror_pool'],
|
||||
new_type, self._aux_state, self.configuration)
|
||||
# retype from mirror-rep to non-mirror-rep
|
||||
elif (old_opts['aux_mirror_pool'] and not
|
||||
new_opts['aux_mirror_pool']):
|
||||
aux_secondary = aux_copies['secondary']
|
||||
if aux_secondary:
|
||||
self._aux_backend_helpers.rm_vdisk_copy(
|
||||
target_volume, aux_secondary['copy_id'])
|
||||
|
||||
LOG.debug('exit: retype: ild=%(id)s, new_type=%(new_type)s,'
|
||||
'diff=%(diff)s, host=%(host)s', {'id': volume['id'],
|
||||
'new_type': new_type,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
IBM Spectrum Virtualize Family driver: `Bug #2003300
|
||||
<https://bugs.launchpad.net/cinder/+bug/2003300>`_:
|
||||
Enable support for mirror-pool option for metro-mirror
|
||||
replication and global-mirror replication volume-types.
|
||||
Reference in New Issue
Block a user