Rollback snapshot's status when backup failed

When create backup from snapshot, if the backup action failed
in driver layer. The snapshot's status will be backing-up forever.

We should rollback the snapshot's status to its previous status
(available) like volume does when backup failed.

Change-Id: I77ac4e546c9a33003b7a52a5c924f70ad809cac0
Closes-bug: #1683258
This commit is contained in:
wangxiyuan 2017-04-17 15:59:23 +08:00
parent 956fd42eed
commit 754d4c6c1f
2 changed files with 29 additions and 3 deletions

View File

@ -418,9 +418,14 @@ class BackupManager(manager.ThreadPoolManager):
self._run_backup(context, backup, volume)
except Exception as err:
with excutils.save_and_reraise_exception():
self.db.volume_update(context, volume_id,
{'status': previous_status,
'previous_status': 'error_backing-up'})
if snapshot_id:
snapshot.status = fields.SnapshotStatus.AVAILABLE
snapshot.save()
else:
self.db.volume_update(
context, volume_id,
{'status': previous_status,
'previous_status': 'error_backing-up'})
self._update_backup_error(backup, six.text_type(err))
# Restore the original status.

View File

@ -573,6 +573,27 @@ class BackupTestCase(BaseBackupTest):
self.assertEqual(fields.BackupStatus.ERROR, backup['status'])
self.assertTrue(mock_run_backup.called)
@mock.patch('cinder.backup.manager.BackupManager._run_backup',
side_effect=FakeBackupException(str(uuid.uuid4())))
def test_create_backup_with_snapshot_error(self, mock_run_backup):
"""Test error handling when error occurs during backup creation."""
vol_id = self._create_volume_db_entry(size=1)
snapshot = self._create_snapshot_db_entry(status='backing-up',
volume_id=vol_id)
backup = self._create_backup_db_entry(volume_id=vol_id,
snapshot_id=snapshot.id)
self.assertRaises(FakeBackupException,
self.backup_mgr.create_backup,
self.ctxt,
backup)
snapshot.refresh()
self.assertEqual('available', snapshot.status)
backup.refresh()
self.assertEqual(fields.BackupStatus.ERROR, backup.status)
self.assertTrue(mock_run_backup.called)
@mock.patch('cinder.utils.brick_get_connector_properties')
@mock.patch('cinder.volume.rpcapi.VolumeAPI.get_backup_device')
@mock.patch('cinder.utils.temporary_chown')