[SVF] Update volume replication properties

[Spectrum Virtualize Family] Updated replication properties for
HyperSwap volumes and volumes with replication enabled that were
missing from volume metadata.

closes bug: #1912451

Change-Id: I394343fc2db128f3cead741846cde684196c3c05
This commit is contained in:
Venkata Krishna Thumu 2021-01-20 07:10:40 +00:00 committed by venkatakrishnathumu
parent e39c0406de
commit 01c9aba1fa
3 changed files with 103 additions and 14 deletions

View File

@ -9475,7 +9475,7 @@ class StorwizeSVCReplicationTestCase(test.TestCase):
self.assertEqual( self.assertEqual(
storwize_const.REPLICA_AUX_VOL_PREFIX + volume['name'], storwize_const.REPLICA_AUX_VOL_PREFIX + volume['name'],
rel_info['aux_vdisk_name']) rel_info['aux_vdisk_name'])
self.assertEqual('inconsistent_copying', rel_info['state']) self.assertIn(rel_info['state'], ['consistent_copying'])
self.assertEqual( self.assertEqual(
storwize_const.REPLICA_CHG_VOL_PREFIX + volume['name'], storwize_const.REPLICA_CHG_VOL_PREFIX + volume['name'],
rel_info['master_change_vdisk_name']) rel_info['master_change_vdisk_name'])
@ -9483,7 +9483,7 @@ class StorwizeSVCReplicationTestCase(test.TestCase):
storwize_const.REPLICA_CHG_VOL_PREFIX + storwize_const.REPLICA_CHG_VOL_PREFIX +
storwize_const.REPLICA_AUX_VOL_PREFIX + volume['name'], storwize_const.REPLICA_AUX_VOL_PREFIX + volume['name'],
rel_info['aux_change_vdisk_name']) rel_info['aux_change_vdisk_name'])
self.assertEqual('inconsistent_copying', rel_info['state']) self.assertIn(rel_info['state'], ['consistent_copying'])
self.sim._rc_state_transition('wait', rel_info) self.sim._rc_state_transition('wait', rel_info)
self.assertEqual('consistent_copying', rel_info['state']) self.assertEqual('consistent_copying', rel_info['state'])
else: else:
@ -9497,7 +9497,8 @@ class StorwizeSVCReplicationTestCase(test.TestCase):
self.assertEqual( self.assertEqual(
storwize_const.REPLICA_AUX_VOL_PREFIX + volume['name'], storwize_const.REPLICA_AUX_VOL_PREFIX + volume['name'],
rel_info['aux_vdisk_name']) rel_info['aux_vdisk_name'])
self.assertEqual('inconsistent_copying', rel_info['state']) self.assertIn(rel_info['state'],
['consistent_synchronized', 'inconsistent_copying'])
self.sim._rc_state_transition('wait', rel_info) self.sim._rc_state_transition('wait', rel_info)
self.assertEqual('consistent_synchronized', rel_info['state']) self.assertEqual('consistent_synchronized', rel_info['state'])

View File

@ -3196,6 +3196,50 @@ class StorwizeSVCCommonDriver(san.SanDriver,
LOG.error(msg) LOG.error(msg)
raise exception.VolumeDriverException(reason=msg) raise exception.VolumeDriverException(reason=msg)
def _update_replication_properties(self, ctxt, volume, model_update):
metadata = self.db.volume_admin_metadata_get(ctxt.elevated(),
volume['id'])
model_update['metadata'] = metadata
rel_info = self._helpers.get_relationship_info(volume.name)
rep_properties = {
'Id': 'id',
'Relationship Name': 'name',
'Master Cluster Id': 'master_cluster_id',
'Master Cluster Name': 'master_cluster_name',
'Master Volume Id': 'master_vdisk_id',
'Master Volume Name': 'master_vdisk_name',
'Aux Cluster Id': 'aux_cluster_id',
'Aux Cluster Name': 'aux_cluster_name',
'Aux Volume Id': 'aux_vdisk_id',
'Aux Volume Name': 'aux_vdisk_name',
'Consistency Group Id': 'consistency_group_id',
'Consistency Group Name': 'consistency_group_name',
'Bg Copy Priority': 'bg_copy_priority',
'Primary': 'primary',
'Progress': 'progress',
'Mirroring State': 'state',
'Status': 'status',
'Sync': 'sync',
'Copy Type': 'copy_type',
'Cycling Mode': 'cycling_mode',
'Cycle Period Seconds': 'cycle_period_seconds',
'Master Change Volume Id': 'master_change_vdisk_id',
'Master Change Volume Name': 'master_change_vdisk_name',
'Aux Change Volume Id': 'aux_change_vdisk_id',
'Aux Change Volume Name': 'aux_change_vdisk_name',
'Freeze Time': 'freeze_time'
}
# Update model for replication
if not rel_info:
for key in rep_properties.keys():
if key in model_update['metadata']:
del model_update['metadata'][key]
else:
for key, value in rep_properties.items():
if rel_info.get(value):
model_update['metadata'][key] = rel_info[value]
return model_update
def create_volume(self, volume): def create_volume(self, volume):
LOG.debug('enter: create_volume: volume %s', volume['name']) LOG.debug('enter: create_volume: volume %s', volume['name'])
# Create a replication or hyperswap volume with group_id is not # Create a replication or hyperswap volume with group_id is not
@ -3208,7 +3252,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
rep_type = self._get_volume_replicated_type(ctxt, volume) rep_type = self._get_volume_replicated_type(ctxt, volume)
pool = volume_utils.extract_host(volume['host'], 'pool') pool = volume_utils.extract_host(volume['host'], 'pool')
model_update = None model_update = dict()
if opts['volume_topology'] == 'hyperswap': if opts['volume_topology'] == 'hyperswap':
LOG.debug('Volume %s to be created is a hyperswap volume.', LOG.debug('Volume %s to be created is a hyperswap volume.',
@ -3229,6 +3273,9 @@ class StorwizeSVCCommonDriver(san.SanDriver,
self._helpers.check_hyperswap_pool(pool, opts['peer_pool']) self._helpers.check_hyperswap_pool(pool, opts['peer_pool'])
self._helpers.create_hyperswap_volume(volume.name, volume.size, self._helpers.create_hyperswap_volume(volume.name, volume.size,
'gb', pool, opts) 'gb', pool, opts)
# Updating Hyperswap volume replication properties
model_update = self._update_replication_properties(ctxt, volume,
model_update)
else: else:
if opts['mirror_pool'] and rep_type: if opts['mirror_pool'] and rep_type:
reason = _('Create mirror volume with replication enabled is ' reason = _('Create mirror volume with replication enabled is '
@ -3241,14 +3288,18 @@ class StorwizeSVCCommonDriver(san.SanDriver,
if opts['qos']: if opts['qos']:
self._helpers.add_vdisk_qos(volume['name'], opts['qos']) self._helpers.add_vdisk_qos(volume['name'], opts['qos'])
model_update = {'replication_status': model_update[
fields.ReplicationStatus.NOT_CAPABLE} 'replication_status'] = fields.ReplicationStatus.NOT_CAPABLE
if rep_type: if rep_type:
replica_obj = self._get_replica_obj(rep_type) replica_obj = self._get_replica_obj(rep_type)
replica_obj.volume_replication_setup(ctxt, volume) replica_obj.volume_replication_setup(ctxt, volume)
model_update = {'replication_status': model_update[
fields.ReplicationStatus.ENABLED} 'replication_status'] = fields.ReplicationStatus.ENABLED
# Updating replication properties for a volume with replication
# enabled.
model_update = self._update_replication_properties(ctxt, volume,
model_update)
LOG.debug('leave: create_volume:\n volume: %(vol)s\n ' LOG.debug('leave: create_volume:\n volume: %(vol)s\n '
'model_update %(model_update)s', 'model_update %(model_update)s',
@ -3392,10 +3443,15 @@ class StorwizeSVCCommonDriver(san.SanDriver,
replica_obj.volume_replication_setup(ctxt, volume) replica_obj.volume_replication_setup(ctxt, volume)
model_update = {'replication_status': model_update = {'replication_status':
fields.ReplicationStatus.ENABLED} fields.ReplicationStatus.ENABLED}
# Updating replication properties for a volume with replication
# enabled.
model_update = self._update_replication_properties(ctxt, volume,
model_update)
return model_update return model_update
def create_cloned_volume(self, tgt_volume, src_volume): def create_cloned_volume(self, tgt_volume, src_volume):
"""Creates a clone of the specified volume.""" """Creates a clone of the specified volume."""
model_update = dict()
# Create a cloned volume with a replication or hyperswap group_id is # Create a cloned volume with a replication or hyperswap group_id is
# not allowed. # not allowed.
self._check_if_group_type_cg_snapshot(tgt_volume) self._check_if_group_type_cg_snapshot(tgt_volume)
@ -3414,6 +3470,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
# with two different sizes. So use source volume size to # with two different sizes. So use source volume size to
# create target volume first and then extend target # create target volume first and then extend target
# volume to original size. # volume to original size.
ctxt = context.get_admin_context()
if tgt_volume['size'] > src_volume['size']: if tgt_volume['size'] > src_volume['size']:
# extend the new created target volume to expected size. # extend the new created target volume to expected size.
self._extend_volume_op(tgt_volume, tgt_volume['size'], self._extend_volume_op(tgt_volume, tgt_volume['size'],
@ -3434,18 +3491,26 @@ class StorwizeSVCCommonDriver(san.SanDriver,
self._helpers.convert_volume_to_hyperswap(tgt_volume['name'], self._helpers.convert_volume_to_hyperswap(tgt_volume['name'],
opts, opts,
self._state) self._state)
# Updating Hyperswap volume replication properties
model_update = self._update_replication_properties(ctxt,
tgt_volume,
model_update)
ctxt = context.get_admin_context() model_update[
model_update = {'replication_status': 'replication_status'] = fields.ReplicationStatus.NOT_CAPABLE
fields.ReplicationStatus.NOT_CAPABLE}
rep_type = self._get_volume_replicated_type(ctxt, tgt_volume) rep_type = self._get_volume_replicated_type(ctxt, tgt_volume)
if rep_type: if rep_type:
self._validate_replication_enabled() self._validate_replication_enabled()
replica_obj = self._get_replica_obj(rep_type) replica_obj = self._get_replica_obj(rep_type)
replica_obj.volume_replication_setup(ctxt, tgt_volume) replica_obj.volume_replication_setup(ctxt, tgt_volume)
model_update = {'replication_status': model_update[
fields.ReplicationStatus.ENABLED} 'replication_status'] = fields.ReplicationStatus.ENABLED
# Updating replication properties for a volume with replication
# enabled.
model_update = self._update_replication_properties(ctxt,
tgt_volume,
model_update)
return model_update return model_update
def extend_volume(self, volume, new_size): def extend_volume(self, volume, new_size):
@ -4890,7 +4955,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
change_mirror = True change_mirror = True
# Check if retype affects volume replication # Check if retype affects volume replication
model_update = None model_update = dict()
new_rep_type = self._get_specs_replicated_type(new_type) new_rep_type = self._get_specs_replicated_type(new_type)
old_rep_type = self._get_volume_replicated_type(ctxt, volume) old_rep_type = self._get_volume_replicated_type(ctxt, volume)
old_io_grp = self._helpers.get_volume_io_group(volume['name']) old_io_grp = self._helpers.get_volume_io_group(volume['name'])
@ -4909,6 +4974,9 @@ class StorwizeSVCCommonDriver(san.SanDriver,
self._retype_hyperswap_volume(volume, host, old_opts, new_opts, self._retype_hyperswap_volume(volume, host, old_opts, new_opts,
old_pool, new_pool, vdisk_changes, old_pool, new_pool, vdisk_changes,
need_copy, new_type) need_copy, new_type)
# Updating Hyperswap volume replication properties
model_update = self._update_replication_properties(ctxt, volume,
model_update)
else: else:
# hyperswap volume will select iogrp by storage. ignore iogrp here. # hyperswap volume will select iogrp by storage. ignore iogrp here.
if old_io_grp != new_io_grp: if old_io_grp != new_io_grp:
@ -4996,6 +5064,10 @@ class StorwizeSVCCommonDriver(san.SanDriver,
fields.ReplicationStatus.DISABLED, fields.ReplicationStatus.DISABLED,
'replication_driver_data': None, 'replication_driver_data': None,
'replication_extended_status': None} 'replication_extended_status': None}
# Updating replication properties for a volume with replication
# enabled.
model_update = self._update_replication_properties(ctxt, volume,
model_update)
# Add replica if needed # Add replica if needed
if not old_rep_type and new_rep_type: if not old_rep_type and new_rep_type:
replica_obj = self._get_replica_obj(new_rep_type) replica_obj = self._get_replica_obj(new_rep_type)
@ -5007,6 +5079,10 @@ class StorwizeSVCCommonDriver(san.SanDriver,
new_opts.get('cycle_period_seconds')) new_opts.get('cycle_period_seconds'))
model_update = {'replication_status': model_update = {'replication_status':
fields.ReplicationStatus.ENABLED} fields.ReplicationStatus.ENABLED}
# Updating replication properties for a volume with replication
# enabled.
model_update = self._update_replication_properties(ctxt, volume,
model_update)
LOG.debug('exit: retype: ild=%(id)s, new_type=%(new_type)s,' LOG.debug('exit: retype: ild=%(id)s, new_type=%(new_type)s,'
'diff=%(diff)s, host=%(host)s', {'id': volume['id'], 'diff=%(diff)s, host=%(host)s', {'id': volume['id'],
@ -5567,6 +5643,11 @@ class StorwizeSVCCommonDriver(san.SanDriver,
replica_obj.volume_replication_setup(context, vol) replica_obj.volume_replication_setup(context, vol)
volumes_model[volumes.index(vol)]['replication_status'] = ( volumes_model[volumes.index(vol)]['replication_status'] = (
fields.ReplicationStatus.ENABLED) fields.ReplicationStatus.ENABLED)
# Updating replication properties for a volume with replication
# enabled.
volumes_model[volumes.index(vol)] = (
self._update_replication_properties(
context, vol, volumes_model[volumes.index(vol)]))
LOG.debug("Leave: create_group_from_src.") LOG.debug("Leave: create_group_from_src.")
return model_update, volumes_model return model_update, volumes_model

View File

@ -0,0 +1,7 @@
---
fixes:
- |
`Bug #1912451 <https://bugs.launchpad.net/cinder/+bug/1912451>`_:
IBM Spectrum Virtualize Family driver: Updated replication
properties for HyperSwap volumes and volumes with replication
enabled that were missing from volume metadata.