Skip to content

Commit d75acb6

Browse files
Fix rollback disk snapshots on instance snapshot failure (#12949)
1 parent 38abe2d commit d75acb6

File tree

2 files changed

+14
-9
lines changed

2 files changed

+14
-9
lines changed

engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/StorageVMSnapshotStrategy.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
111111
FreezeThawVMAnswer freezeAnswer = null;
112112
FreezeThawVMCommand thawCmd = null;
113113
FreezeThawVMAnswer thawAnswer = null;
114-
List<SnapshotInfo> forRollback = new ArrayList<>();
114+
List<SnapshotInfo> snapshotsForRollback = new ArrayList<>();
115115
long startFreeze = 0;
116116
try {
117117
vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshotVO, VMSnapshot.Event.CreateRequested);
@@ -165,7 +165,7 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
165165
logger.info("The virtual machine is frozen");
166166
for (VolumeInfo vol : vinfos) {
167167
long startSnapshtot = System.nanoTime();
168-
SnapshotInfo snapInfo = createDiskSnapshot(vmSnapshot, forRollback, vol);
168+
SnapshotInfo snapInfo = createDiskSnapshot(vmSnapshot, snapshotsForRollback, vol);
169169

170170
if (snapInfo == null) {
171171
thawAnswer = (FreezeThawVMAnswer) agentMgr.send(hostId, thawCmd);
@@ -222,7 +222,7 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
222222
}
223223
}
224224
if (!result) {
225-
for (SnapshotInfo snapshotInfo : forRollback) {
225+
for (SnapshotInfo snapshotInfo : snapshotsForRollback) {
226226
rollbackDiskSnapshot(snapshotInfo);
227227
}
228228
try {
@@ -388,10 +388,16 @@ private long elapsedTime(long startTime) {
388388

389389
//Rollback if one of disks snapshot fails
390390
protected void rollbackDiskSnapshot(SnapshotInfo snapshotInfo) {
391+
if (snapshotInfo == null) {
392+
return;
393+
}
391394
Long snapshotID = snapshotInfo.getId();
392395
SnapshotVO snapshot = snapshotDao.findById(snapshotID);
396+
if (snapshot == null) {
397+
return;
398+
}
393399
deleteSnapshotByStrategy(snapshot);
394-
logger.debug("Rollback is executed: deleting snapshot with id:" + snapshotID);
400+
logger.debug("Rollback is executed: deleting snapshot with id: {}", snapshotID);
395401
}
396402

397403
protected void deleteSnapshotByStrategy(SnapshotVO snapshot) {
@@ -434,7 +440,7 @@ protected void revertDiskSnapshot(VMSnapshot vmSnapshot) {
434440
}
435441
}
436442

437-
protected SnapshotInfo createDiskSnapshot(VMSnapshot vmSnapshot, List<SnapshotInfo> forRollback, VolumeInfo vol) {
443+
protected SnapshotInfo createDiskSnapshot(VMSnapshot vmSnapshot, List<SnapshotInfo> snapshotsForRollback, VolumeInfo vol) {
438444
String snapshotName = vmSnapshot.getId() + "_" + vol.getUuid();
439445
SnapshotVO snapshot = new SnapshotVO(vol.getDataCenterId(), vol.getAccountId(), vol.getDomainId(), vol.getId(), vol.getDiskOfferingId(),
440446
snapshotName, (short) Snapshot.Type.GROUP.ordinal(), Snapshot.Type.GROUP.name(), vol.getSize(), vol.getMinIops(), vol.getMaxIops(), Hypervisor.HypervisorType.KVM, null);
@@ -448,15 +454,14 @@ protected SnapshotInfo createDiskSnapshot(VMSnapshot vmSnapshot, List<SnapshotIn
448454
vol.addPayload(setPayload(vol, snapshot, quiescevm));
449455
SnapshotInfo snapshotInfo = snapshotDataFactory.getSnapshot(snapshot.getId(), vol.getDataStore());
450456
snapshotInfo.addPayload(vol.getpayload());
457+
snapshotsForRollback.add(snapshotInfo);
451458
SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshotInfo, SnapshotOperation.TAKE);
452459
if (snapshotStrategy == null) {
453460
throw new CloudRuntimeException("Could not find strategy for snapshot uuid:" + snapshotInfo.getUuid());
454461
}
455462
snapshotInfo = snapshotStrategy.takeSnapshot(snapshotInfo);
456463
if (snapshotInfo == null) {
457464
throw new CloudRuntimeException("Failed to create snapshot");
458-
} else {
459-
forRollback.add(snapshotInfo);
460465
}
461466
vmSnapshotDetailsDao.persist(new VMSnapshotDetailsVO(vmSnapshot.getId(), STORAGE_SNAPSHOT, String.valueOf(snapshot.getId()), true));
462467
snapshotInfo.markBackedUp();

engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyKVMTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ public void setUp() throws Exception {
153153
@Test
154154
public void testCreateDiskSnapshotBasedOnStrategy() throws Exception {
155155
VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
156-
List<SnapshotInfo> forRollback = new ArrayList<>();
156+
List<SnapshotInfo> snapshotsForRollback = new ArrayList<>();
157157
VolumeInfo vol = Mockito.mock(VolumeInfo.class);
158158
SnapshotInfo snapshotInfo = Mockito.mock(SnapshotInfo.class);
159159
SnapshotStrategy strategy = Mockito.mock(SnapshotStrategy.class);
@@ -177,7 +177,7 @@ public void testCreateDiskSnapshotBasedOnStrategy() throws Exception {
177177
VMSnapshotDetailsVO vmDetails = new VMSnapshotDetailsVO(vmSnapshot.getId(), volUuid, String.valueOf(snapshot.getId()), false);
178178
when(vmSnapshotDetailsDao.persist(any())).thenReturn(vmDetails);
179179

180-
info = vmStrategy.createDiskSnapshot(vmSnapshot, forRollback, vol);
180+
info = vmStrategy.createDiskSnapshot(vmSnapshot, snapshotsForRollback, vol);
181181
assertNotNull(info);
182182
}
183183

0 commit comments

Comments
 (0)