Skip to content

Commit bd1ca29

Browse files
Fix rollback disk snapshots on instance snapshot failure
1 parent 4708121 commit bd1ca29

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.apache.cloudstack.storage.vmsnapshot;
2020

2121
import java.util.ArrayList;
22+
import java.util.HashMap;
2223
import java.util.List;
2324
import java.util.Map;
2425
import java.util.concurrent.TimeUnit;
@@ -111,7 +112,7 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
111112
FreezeThawVMAnswer freezeAnswer = null;
112113
FreezeThawVMCommand thawCmd = null;
113114
FreezeThawVMAnswer thawAnswer = null;
114-
List<SnapshotInfo> forRollback = new ArrayList<>();
115+
Map<Long, SnapshotInfo> volumeToSnapshotInfoMapForRollback = new HashMap<>();
115116
long startFreeze = 0;
116117
try {
117118
vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshotVO, VMSnapshot.Event.CreateRequested);
@@ -165,7 +166,7 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
165166
logger.info("The virtual machine is frozen");
166167
for (VolumeInfo vol : vinfos) {
167168
long startSnapshtot = System.nanoTime();
168-
SnapshotInfo snapInfo = createDiskSnapshot(vmSnapshot, forRollback, vol);
169+
SnapshotInfo snapInfo = createDiskSnapshot(vmSnapshot, volumeToSnapshotInfoMapForRollback, vol);
169170

170171
if (snapInfo == null) {
171172
thawAnswer = (FreezeThawVMAnswer) agentMgr.send(hostId, thawCmd);
@@ -222,7 +223,7 @@ public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
222223
}
223224
}
224225
if (!result) {
225-
for (SnapshotInfo snapshotInfo : forRollback) {
226+
for (SnapshotInfo snapshotInfo : volumeToSnapshotInfoMapForRollback.values()) {
226227
rollbackDiskSnapshot(snapshotInfo);
227228
}
228229
try {
@@ -388,10 +389,16 @@ private long elapsedTime(long startTime) {
388389

389390
//Rollback if one of disks snapshot fails
390391
protected void rollbackDiskSnapshot(SnapshotInfo snapshotInfo) {
392+
if (snapshotInfo == null) {
393+
return;
394+
}
391395
Long snapshotID = snapshotInfo.getId();
392396
SnapshotVO snapshot = snapshotDao.findById(snapshotID);
397+
if (snapshot == null) {
398+
return;
399+
}
393400
deleteSnapshotByStrategy(snapshot);
394-
logger.debug("Rollback is executed: deleting snapshot with id:" + snapshotID);
401+
logger.debug("Rollback is executed: deleting snapshot with id: {}", snapshotID);
395402
}
396403

397404
protected void deleteSnapshotByStrategy(SnapshotVO snapshot) {
@@ -434,7 +441,7 @@ protected void revertDiskSnapshot(VMSnapshot vmSnapshot) {
434441
}
435442
}
436443

437-
protected SnapshotInfo createDiskSnapshot(VMSnapshot vmSnapshot, List<SnapshotInfo> forRollback, VolumeInfo vol) {
444+
protected SnapshotInfo createDiskSnapshot(VMSnapshot vmSnapshot, Map<Long, SnapshotInfo> volumeToSnapshotInfoMapForRollback, VolumeInfo vol) {
438445
String snapshotName = vmSnapshot.getId() + "_" + vol.getUuid();
439446
SnapshotVO snapshot = new SnapshotVO(vol.getDataCenterId(), vol.getAccountId(), vol.getDomainId(), vol.getId(), vol.getDiskOfferingId(),
440447
snapshotName, (short) Snapshot.Type.GROUP.ordinal(), Snapshot.Type.GROUP.name(), vol.getSize(), vol.getMinIops(), vol.getMaxIops(), Hypervisor.HypervisorType.KVM, null);
@@ -448,6 +455,7 @@ protected SnapshotInfo createDiskSnapshot(VMSnapshot vmSnapshot, List<SnapshotIn
448455
vol.addPayload(setPayload(vol, snapshot, quiescevm));
449456
SnapshotInfo snapshotInfo = snapshotDataFactory.getSnapshot(snapshot.getId(), vol.getDataStore());
450457
snapshotInfo.addPayload(vol.getpayload());
458+
volumeToSnapshotInfoMapForRollback.put(vol.getId(), snapshotInfo);
451459
SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshotInfo, SnapshotOperation.TAKE);
452460
if (snapshotStrategy == null) {
453461
throw new CloudRuntimeException("Could not find strategy for snapshot uuid:" + snapshotInfo.getUuid());
@@ -456,7 +464,7 @@ protected SnapshotInfo createDiskSnapshot(VMSnapshot vmSnapshot, List<SnapshotIn
456464
if (snapshotInfo == null) {
457465
throw new CloudRuntimeException("Failed to create snapshot");
458466
} else {
459-
forRollback.add(snapshotInfo);
467+
volumeToSnapshotInfoMapForRollback.put(vol.getId(), snapshotInfo);
460468
}
461469
vmSnapshotDetailsDao.persist(new VMSnapshotDetailsVO(vmSnapshot.getId(), STORAGE_SNAPSHOT, String.valueOf(snapshot.getId()), true));
462470
snapshotInfo.markBackedUp();

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import java.io.IOException;
2525
import java.util.ArrayList;
2626
import java.util.Date;
27+
import java.util.HashMap;
2728
import java.util.List;
29+
import java.util.Map;
2830
import java.util.UUID;
2931

3032
import javax.inject.Inject;
@@ -153,7 +155,7 @@ public void setUp() throws Exception {
153155
@Test
154156
public void testCreateDiskSnapshotBasedOnStrategy() throws Exception {
155157
VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
156-
List<SnapshotInfo> forRollback = new ArrayList<>();
158+
Map<Long, SnapshotInfo> volumeToSnapshotInfoMapForRollback = new HashMap<>();
157159
VolumeInfo vol = Mockito.mock(VolumeInfo.class);
158160
SnapshotInfo snapshotInfo = Mockito.mock(SnapshotInfo.class);
159161
SnapshotStrategy strategy = Mockito.mock(SnapshotStrategy.class);
@@ -177,7 +179,7 @@ public void testCreateDiskSnapshotBasedOnStrategy() throws Exception {
177179
VMSnapshotDetailsVO vmDetails = new VMSnapshotDetailsVO(vmSnapshot.getId(), volUuid, String.valueOf(snapshot.getId()), false);
178180
when(vmSnapshotDetailsDao.persist(any())).thenReturn(vmDetails);
179181

180-
info = vmStrategy.createDiskSnapshot(vmSnapshot, forRollback, vol);
182+
info = vmStrategy.createDiskSnapshot(vmSnapshot, volumeToSnapshotInfoMapForRollback, vol);
181183
assertNotNull(info);
182184
}
183185

0 commit comments

Comments
 (0)