Merge "[SVf] : Enable support for mirror-pool option for replication volume-type"

This commit is contained in:
Zuul
2025-06-05 11:39:26 +00:00
committed by Gerrit Code Review
4 changed files with 154 additions and 21 deletions

View File

@ -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))

View File

@ -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']),

View File

@ -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,

View File

@ -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.