Merge "[SVf] : Enable support for mirror-pool option for replication volume-type"
This commit is contained in:
@ -5746,6 +5746,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,
|
||||
@ -11796,21 +11797,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',
|
||||
@ -11854,6 +11840,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