Skip to content

Commit 3dd52c6

Browse files
committed
Fix bulk delete
1 parent b8b6b8c commit 3dd52c6

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ public long getVolumeSize() {
234234

235235
@Override
236236
public String toString() {
237-
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "snapshotId", "dataStoreId", "installPath", "kvmCheckpointPath");
237+
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "snapshotId", "dataStoreId", "state", "installPath", "kvmCheckpointPath");
238238
}
239239

240240
public long getUpdatedCount() {

engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@
2020
import java.util.Arrays;
2121
import java.util.List;
2222
import java.util.Objects;
23+
import java.util.concurrent.ConcurrentHashMap;
24+
import java.util.concurrent.ConcurrentMap;
25+
import java.util.concurrent.locks.Lock;
26+
import java.util.concurrent.locks.ReentrantLock;
2327

2428
import javax.inject.Inject;
2529

30+
import com.cloud.utils.db.TransactionCallback;
2631
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
2732
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
2833
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
@@ -101,6 +106,13 @@ public class DefaultSnapshotStrategy extends SnapshotStrategyBase {
101106

102107
private final List<Snapshot.State> snapshotStatesAbleToDeleteSnapshot = Arrays.asList(Snapshot.State.Destroying, Snapshot.State.Destroyed, Snapshot.State.Error, Snapshot.State.Hidden);
103108

109+
private ConcurrentMap<Long, Lock> locks = new ConcurrentHashMap<>();
110+
111+
private Lock getLock(Long id) {
112+
locks.putIfAbsent(id, new ReentrantLock());
113+
return locks.get(id);
114+
}
115+
104116
public SnapshotDataStoreVO getSnapshotImageStoreRef(long snapshotId, long zoneId) {
105117
List<SnapshotDataStoreVO> snaps = snapshotStoreDao.listReadyBySnapshot(snapshotId, DataStoreRole.Image);
106118
for (SnapshotDataStoreVO ref : snaps) {
@@ -187,6 +199,8 @@ public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
187199
}
188200

189201
protected boolean deleteSnapshotChain(SnapshotInfo snapshot, String storageToString) {
202+
long rootSnapshotId = getRootSnapshotId(snapshot);
203+
snapshotDao.acquireInLockTable(rootSnapshotId);
190204
DataTO snapshotTo = snapshot.getTO();
191205
logger.debug(String.format("Deleting %s chain of snapshots.", snapshotTo));
192206

@@ -248,9 +262,17 @@ protected boolean deleteSnapshotChain(SnapshotInfo snapshot, String storageToStr
248262
} catch (Exception e) {
249263
logger.error(String.format("Failed to delete snapshot [%s] on storage [%s] due to [%s].", snapshotTo, storageToString, e.getMessage()), e);
250264
}
265+
snapshotDao.releaseFromLockTable(rootSnapshotId);
251266
return result;
252267
}
253268

269+
private Long getRootSnapshotId(SnapshotInfo snapshotInfo) {
270+
while (snapshotInfo.getParent() != null) {
271+
snapshotInfo = snapshotInfo.getParent();
272+
}
273+
return snapshotInfo.getSnapshotId();
274+
}
275+
254276
@Override
255277
public boolean deleteSnapshot(Long snapshotId, Long zoneId) {
256278
SnapshotVO snapshotVO = snapshotDao.findById(snapshotId);
@@ -392,7 +414,7 @@ protected Boolean deleteSnapshotInfo(SnapshotInfo snapshotInfo, SnapshotVO snaps
392414
snapshotObject.processEvent(Snapshot.Event.DestroyRequested);
393415
}
394416
verifyIfTheSnapshotIsBeingUsedByAnyVolume(snapshotObject);
395-
if (deleteSnapshotChain(snapshotInfo, storageToString)) {
417+
if (Transaction.execute((TransactionCallback<Boolean>) status -> deleteSnapshotChain(snapshotInfo, storageToString))) {
396418
logger.debug(String.format("%s was deleted on %s. We will mark the snapshot as destroyed.", snapshotVo, storageToString));
397419
} else {
398420
logger.debug(String.format("%s was not deleted on %s; however, we will mark the snapshot as hidden for future garbage collecting.", snapshotVo,

0 commit comments

Comments
 (0)