diff --git a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java index beb8b044d1a..f3195668f4b 100755 --- a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java +++ b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java @@ -884,8 +884,8 @@ private void stepDelete(Completion completion) { return; } - VolumeTree.VolumeSnapshotLeaf onlineChild = children.stream() - .filter(child -> volumeTree.isOnline(current, currentRoot.getUuid(), child.getUuid(), vmState)) + VolumeTree.VolumeSnapshotLeaf aliveChild = children.stream() + .filter(child -> volumeTree.isOnAliveChain(child.getUuid())) .findFirst().orElse(null); Completion comp = new Completion(completion) { @@ -910,7 +910,7 @@ public void fail(ErrorCode errorCode) { pull(child, volumeTree, online, comp); } } else { - if (onlineChild != null && Objects.equals(child.getUuid(), onlineChild.getUuid())) { + if (aliveChild != null && Objects.equals(child.getUuid(), aliveChild.getUuid())) { child = children.get(1); } boolean online = volumeTree.isOnline(current, currentRoot.getUuid(), child.getUuid(), vmState); diff --git a/storage/src/main/java/org/zstack/storage/snapshot/VolumeTree.java b/storage/src/main/java/org/zstack/storage/snapshot/VolumeTree.java index ea669fd6202..f7b9bcc0ba3 100644 --- a/storage/src/main/java/org/zstack/storage/snapshot/VolumeTree.java +++ b/storage/src/main/java/org/zstack/storage/snapshot/VolumeTree.java @@ -361,12 +361,19 @@ public List getAliveChainSnapshotUuids() { return aliveChain.stream().map(VolumeSnapshotInventory::getUuid).collect(Collectors.toList()); } + public boolean isOnAliveChain(String snapshotUuid) { + return current && getAliveChainSnapshotUuids().contains(snapshotUuid); + } + + public static boolean isHypervisorOperation(VmInstanceState vmState) { + return vmState == VmInstanceState.Running || vmState == VmInstanceState.Paused; + } + public DeleteVolumeSnapshotDirection resolveDirection(String targetSnapshotUuid, String childSnapshotUuid, String initialDirection, boolean targetSnapshotIsLatest, VmInstanceState vmState) { - boolean online = (vmState == VmInstanceState.Running || vmState == VmInstanceState.Paused) - && getAliveChainSnapshotUuids().contains(targetSnapshotUuid) && getAliveChainSnapshotUuids().contains(childSnapshotUuid); - - boolean shouldUseCommitStrategy = current && !targetSnapshotIsLatest && online; + boolean targetOnAliveChain = isOnAliveChain(targetSnapshotUuid); + boolean childOnAliveChain = isOnAliveChain(childSnapshotUuid); + boolean shouldUseCommitStrategy = current && !targetSnapshotIsLatest && targetOnAliveChain && childOnAliveChain; if (Objects.equals(initialDirection, DeleteVolumeSnapshotDirection.Pull.toString()) && shouldUseCommitStrategy) { throw new IllegalArgumentException("the snapshot will be deleted by block 'commit', but the direction is 'pull', " + @@ -387,8 +394,10 @@ public DeleteVolumeSnapshotDirection resolveDirection(String targetSnapshotUuid, } public boolean isOnline(boolean treeIsCurrent, String targetSnapshotUuid, String childSnapshotUuid, VmInstanceState vmState) { - return treeIsCurrent && (vmState == VmInstanceState.Running || vmState == VmInstanceState.Paused) - && getAliveChainSnapshotUuids().contains(targetSnapshotUuid) && getAliveChainSnapshotUuids().contains(childSnapshotUuid); + return treeIsCurrent + && isHypervisorOperation(vmState) + && getAliveChainSnapshotUuids().contains(targetSnapshotUuid) + && getAliveChainSnapshotUuids().contains(childSnapshotUuid); } // TODO(clone) : When both chain cloning and single-node snapshot deletion are enabled,