diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index 2fc576b8b8f..c8a0bc8a794 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -107,6 +107,7 @@ public class SnapshotObject implements SnapshotInfo { .create(SnapshotDataStoreVO.class); sc.addAnd(sc.getEntity().getDataStoreId(), Op.EQ, this.store.getId()); sc.addAnd(sc.getEntity().getRole(), Op.EQ, this.store.getRole()); + sc.addAnd(sc.getEntity().getState(), Op.NIN, State.Destroying, State.Destroyed, State.Error); sc.addAnd(sc.getEntity().getParentSnapshotId(), Op.EQ, this.getId()); SnapshotDataStoreVO vo = sc.find(); if (vo == null) { diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index ebbce5b16a4..c470bfe0593 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -140,7 +140,20 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { } s_logger.debug("Snapshot: " + snapshot.getId() + " doesn't have children, so it's ok to delete it and its parents"); SnapshotInfo parent = snapshot.getParent(); - result = this.snapshotSvr.deleteSnapshot(snapshot); + boolean deleted = false; + if (parent != null) { + if (parent.getPath() != null && parent.getPath().equalsIgnoreCase(snapshot.getPath())) { + //NOTE: if both snapshots share the same path, it's for xenserver's empty delta snapshot. We can't delete the snapshot on the backend, as parent snapshot still reference to it + //Instead, mark it as destroyed in the db. + s_logger.debug("for empty delta snapshot, only mark it as destroyed in db"); + snapshot.processEvent(Event.DestroyRequested); + snapshot.processEvent(Event.OperationSuccessed); + deleted = true; + } + } + if (!deleted) { + result = this.snapshotSvr.deleteSnapshot(snapshot); + } snapshot = parent; } return result;