Handle snapshot delete conflict in 3par driver
Issue is most likely due to the fact that 3par uses online copy during create from snapshot. This process on the 3PAR creates temporary snapshots for doing the copy. They get deleted after the online (background) copy is completed. If user try and delete the volume during that process, user will get an HTTP Conflict and the "volume has a child" error. Fix is to detect conflict code and remove temporary online copies if they exist and delete snapshot again. Modified unit test to check HTTP conflict with error code Change-Id: If4a2cabb7afd0299c78e42a941b95a01c76b2b5b Closes-Bug: #1600104
This commit is contained in:
parent
c523afa0fd
commit
1e8204795e
@ -2297,6 +2297,7 @@ class HPE3PARBaseDriver(object):
|
||||
self.driver.create_volume_from_snapshot(self.volume, self.snapshot)
|
||||
|
||||
ex = hpeexceptions.HTTPConflict("In use")
|
||||
ex._error_code = 32
|
||||
mock_client.deleteVolume = mock.Mock(side_effect=ex)
|
||||
|
||||
# Deleting the snapshot that a volume is dependent on should fail
|
||||
|
@ -243,10 +243,11 @@ class HPE3PARCommon(object):
|
||||
characters. bug #1573647
|
||||
3.0.24 - Fix terminate connection on failover
|
||||
3.0.25 - Fix delete volume when online clone is active. bug #1349639
|
||||
3.0.26 - Fix concurrent snapshot delete conflict. bug #1600104
|
||||
|
||||
"""
|
||||
|
||||
VERSION = "3.0.25"
|
||||
VERSION = "3.0.26"
|
||||
|
||||
stats = {}
|
||||
|
||||
@ -2476,8 +2477,34 @@ class HPE3PARCommon(object):
|
||||
"cinder: %(id)s Ex: %(msg)s"),
|
||||
{'id': snapshot['id'], 'msg': ex})
|
||||
except hpeexceptions.HTTPConflict as ex:
|
||||
LOG.error(_LE("Exception: %s"), ex)
|
||||
raise exception.SnapshotIsBusy(snapshot_name=snapshot['id'])
|
||||
if (ex.get_code() == 32):
|
||||
# Error 32 means that the snapshot has children
|
||||
# see if we have any temp snapshots
|
||||
snaps = self.client.getVolumeSnapshots(snap_name)
|
||||
for snap in snaps:
|
||||
if snap.startswith('tss-'):
|
||||
LOG.info(
|
||||
_LI("Found a temporary snapshot %(name)s"),
|
||||
{'name': snap})
|
||||
try:
|
||||
self.client.deleteVolume(snap)
|
||||
except hpeexceptions.HTTPNotFound:
|
||||
# if the volume is gone, it's as good as a
|
||||
# successful delete
|
||||
pass
|
||||
except Exception:
|
||||
msg = _("Snapshot has a temporary snapshot that "
|
||||
"can't be deleted at this time.")
|
||||
raise exception.SnapshotIsBusy(message=msg)
|
||||
|
||||
try:
|
||||
self.client.deleteVolume(snap_name)
|
||||
except Exception:
|
||||
msg = _("Snapshot has children and cannot be deleted!")
|
||||
raise exception.SnapshotIsBusy(message=msg)
|
||||
else:
|
||||
LOG.error(_LE("Exception: %s"), ex)
|
||||
raise exception.SnapshotIsBusy(message=ex.get_description())
|
||||
|
||||
def _get_3par_hostname_from_wwn_iqn(self, wwns, iqns):
|
||||
if wwns is not None and not isinstance(wwns, list):
|
||||
|
Loading…
Reference in New Issue
Block a user