3PAR: fix cloning issue in create group from source.

When group or group snapshot is created from two
different volume types having provisioning set
one volume type and compression set on other
volume type and then if we create group from
existing group or group snapshot then we are
making use of source snapshot and online copy
feature of 3par for copying data from source
to destination.

But we have not kept mapping of source volume and
its snapshot and because of this, from any snapshot
of data gets copied to any destination volume and
created issues mentioned in bug.

This patch creates mapping of source volume and its
Snapshot, so correct snapshot get selected for correct
destination volume for copying of data.

Change-Id: I435cd47908fefaa767063fa4c61f3a4d76ffc4ae
Closes-Bug: #1744025
This commit is contained in:
kushal 2018-01-30 06:45:05 -08:00
parent bca658f4d9
commit ecc3e99163
2 changed files with 55 additions and 5 deletions

View File

@ -5654,7 +5654,11 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
typ_info.return_value = type_info
source_volume = self.volume_src_cg
volume = self.volume_tiramisu
volume['source_volid'] = source_volume['id']
common = hpecommon.HPE3PARCommon(None)
vol_name = common._get_3par_vol_name(volume.get('id'))
mock_client.getVolume.return_value = {'copyOf': vol_name}
group_snap_optional = (
{'expirationHours': 1})
@ -5681,6 +5685,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
self.SRC_CONSIS_GROUP_NAME,
optional=group_snap_optional),
mock.call.stopRemoteCopy(self.RCG_3PAR_GROUP_NAME),
mock.call.getVolume(mock.ANY),
mock.call.copyVolume(
mock.ANY,
self.VOLUME_NAME_3PAR,
@ -5704,7 +5709,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
# Create a consistency group from a source consistency group.
self.driver.create_group_from_src(
context.get_admin_context(), group,
[self.volume_tiramisu], source_group=source_grp,
[volume], source_group=source_grp,
source_vols=[source_volume])
mock_client.assert_has_calls(
@ -5733,6 +5738,11 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
'hpe3par_keys': {}}
typ_info.return_value = type_info
source_volume = self.volume_src_cg
volume.volume['source_volid'] = source_volume['id']
common = hpecommon.HPE3PARCommon(None)
vol_name = common._get_3par_vol_name(volume.id)
mock_client.getVolume.return_value = {'copyOf': vol_name}
group_snap_comment = Comment({
"group_id": "6044fedf-c889-4752-900f-2039d247a5df",
@ -5835,7 +5845,10 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
typ_info.return_value = type_info
source_volume = self.volume_src_cg
volume.volume['source_volid'] = source_volume['id']
common = hpecommon.HPE3PARCommon(None)
vol_name = common._get_3par_vol_name(volume.id)
mock_client.getVolume.return_value = {'copyOf': vol_name}
group_snap_optional = (
{'expirationHours': 1})
@ -5861,6 +5874,7 @@ class TestHPE3PARDriverBase(HPE3PARBaseDriver):
mock.ANY,
self.SRC_CONSIS_GROUP_NAME,
optional=group_snap_optional),
mock.call.getVolume(mock.ANY),
mock.call.copyVolume(
mock.ANY,
self.VOLUME_NAME_3PAR,

View File

@ -261,11 +261,14 @@ class HPE3PARCommon(object):
4.0.3 - Fixed create group from source functionality in case of
tiramisu. bug #1742092.
4.0.4 - Fixed setting of sync_period value in rcopygroup. bug #1746235
4.0.5 - Fixed volume created and added in cloned group,
differs from volume present in the source group in terms of
extra-specs. bug #1744025
"""
VERSION = "4.0.3"
VERSION = "4.0.5"
stats = {}
@ -595,6 +598,7 @@ class HPE3PARCommon(object):
volumes_model_update = []
task_id_list = []
volumes_cpg_map = []
snap_vol_dict = {}
replication_flag = False
model_update = {'status': fields.GroupStatus.AVAILABLE}
@ -623,8 +627,40 @@ class HPE3PARCommon(object):
# Stop remote copy, so we can add volumes in RCG.
self._stop_remote_copy_group(group)
for i, volume in enumerate(volumes):
for i in range(0, len(volumes)):
# In case of group created from group,we are mapping
# source volume with it's snapshot
snap_name = snap_base + "-" + six.text_type(i)
snap_detail = self.client.getVolume(snap_name)
vol_name = snap_detail.get('copyOf')
src_vol_name = vol_name
# In case of group created from group snapshots,we are mapping
# source volume with it's snapshot
if source_group is None:
for snapshot in snapshots:
# Getting vol_name from snapshot, in case of group created
# from group snapshot.
vol_name = (
self._get_3par_vol_name(snapshot.get('volume_id')))
if src_vol_name == vol_name:
vol_name = (
self._get_3par_vol_name(snapshot.get('id')))
break
LOG.debug("Source volume name: %(vol)s of snapshot: %(snap)s",
{'vol': src_vol_name, 'snap': snap_name})
snap_vol_dict[vol_name] = snap_name
for volume in volumes:
src_vol_name = volume.get('source_volid')
if src_vol_name is None:
src_vol_name = volume.get('snapshot_id')
# Finding source volume from volume and then use snap_vol_dict
# to get right snap name from source volume.
vol_name = self._get_3par_vol_name(src_vol_name)
snap_name = snap_vol_dict.get(vol_name)
volume_name = self._get_3par_vol_name(volume.get('id'))
type_info = self.get_volume_settings_from_type(volume)
cpg = type_info['cpg']