VMAX driver - Deleting snapshot that is source of multiple volumes fails

Deleting a snapshot which is the source of multiple volumes fails with
the error: "The number of source and target devices must be equal". This
patch rectifies the issue by unlinking source and target volumes
individually where a single volume is a source of multiple targets.

Change-Id: I4b0c171051622f62aba1238c3b84d8a2c8bad6dc
Closes-bug: 1768047
This commit is contained in:
Ciara Stacke 2018-04-30 16:14:14 +01:00 committed by Helen Walsh
parent 1149fccb25
commit 6c3ab36479
2 changed files with 29 additions and 2 deletions

View File

@ -3732,6 +3732,26 @@ class VMAXProvisionTest(test.TestCase):
mock_mod.assert_called_once()
mock_del.assert_called_once()
@mock.patch.object(
rest.VMAXRest, 'get_snap_linked_device_list',
side_effect=[[{'targetDevice': VMAXCommonData.device_id2}],
[{'targetDevice': VMAXCommonData.device_id2},
{'targetDevice': VMAXCommonData.device_id3}]])
@mock.patch.object(provision.VMAXProvision, '_unlink_volume')
def test_delete_volume_snap_check_for_links(self, mock_unlink, mock_tgts):
self.provision.delete_volume_snap_check_for_links(
self.data.array, self.data.test_snapshot_snap_name,
self.data.device_id, self.data.extra_specs)
mock_unlink.assert_called_once_with(
self.data.array, "", "", self.data.test_snapshot_snap_name,
self.data.extra_specs, list_volume_pairs=[
(self.data.device_id, VMAXCommonData.device_id2)])
mock_unlink.reset_mock()
self.provision.delete_volume_snap_check_for_links(
self.data.array, self.data.test_snapshot_snap_name,
self.data.device_id, self.data.extra_specs)
self.assertEqual(2, mock_unlink.call_count)
class VMAXCommonTest(test.TestCase):
def setUp(self):

View File

@ -343,9 +343,16 @@ class VMAXProvision(object):
{'vol': source_device, 'snap_name': snap_name})
linked_list = self.rest.get_snap_linked_device_list(
array, source_device, snap_name)
for link in linked_list:
target_device = link['targetDevice']
if len(linked_list) == 1:
target_device = linked_list[0]['targetDevice']
list_device_pairs.append((source_device, target_device))
else:
for link in linked_list:
# If a single source volume has multiple targets,
# we must unlink each target individually
target_device = link['targetDevice']
self._unlink_volume(array, source_device, target_device,
snap_name, extra_specs)
if list_device_pairs:
self._unlink_volume(array, "", "", snap_name, extra_specs,
list_volume_pairs=list_device_pairs)