diff --git a/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java b/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java index cb67ba75caa7..38e5e105a483 100644 --- a/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java +++ b/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java @@ -88,6 +88,10 @@ public interface SnapshotApiService { Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException; + Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType, Boolean isFromVmSnapshot) + throws ResourceAllocationException; + + /** * Create a snapshot of a volume * diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index b573af7dba1b..a31304aa5ae9 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -3289,7 +3289,7 @@ public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it"); } - return snapshotMgr.allocSnapshot(volumeId, policyId, snapshotName, locationType); + return snapshotMgr.allocSnapshot(volumeId, policyId, snapshotName, locationType, false); } @Override @@ -3345,7 +3345,7 @@ public Snapshot allocSnapshotForVm(Long vmId, Long volumeId, String snapshotName throw new InvalidParameterValueException("Cannot perform this operation, unsupported on storage pool type " + storagePool.getPoolType()); } - return snapshotMgr.allocSnapshot(volumeId, Snapshot.MANUAL_POLICY_ID, snapshotName, null); + return snapshotMgr.allocSnapshot(volumeId, Snapshot.MANUAL_POLICY_ID, snapshotName, null, true); } @Override diff --git a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 049754a04d83..112cf3799b54 100755 --- a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -1124,7 +1124,7 @@ private Type getSnapshotType(IntervalType intvType) { return null; } - private boolean hostSupportSnapsthotForVolume(HostVO host, VolumeInfo volume) { + private boolean hostSupportsSnapsthotForVolume(HostVO host, VolumeInfo volume, boolean isFromVmSnapshot) { if (host.getHypervisorType() != HypervisorType.KVM) { return true; } @@ -1136,7 +1136,7 @@ private boolean hostSupportSnapsthotForVolume(HostVO host, VolumeInfo volume) { VMInstanceVO vm = _vmDao.findById(vmId); if (vm.getState() != VirtualMachine.State.Stopped && vm.getState() != VirtualMachine.State.Destroyed) { boolean snapshotEnabled = Boolean.parseBoolean(_configDao.getValue("kvm.snapshot.enabled")); - if (!snapshotEnabled) { + if (!snapshotEnabled && !isFromVmSnapshot) { s_logger.debug("Snapshot is not supported on host " + host + " for the volume " + volume + " attached to the vm " + vm); return false; } @@ -1157,7 +1157,7 @@ private boolean hostSupportSnapsthotForVolume(HostVO host, VolumeInfo volume) { return false; } - private boolean supportedByHypervisor(VolumeInfo volume) { + private boolean supportedByHypervisor(VolumeInfo volume, boolean isFromVmSnapshot) { HypervisorType hypervisorType; StoragePoolVO storagePool = _storagePoolDao.findById(volume.getDataStore().getId()); ScopeType scope = storagePool.getScope(); @@ -1181,7 +1181,7 @@ private boolean supportedByHypervisor(VolumeInfo volume) { } if (hosts != null && !hosts.isEmpty()) { HostVO host = hosts.get(0); - if (!hostSupportSnapsthotForVolume(host, volume)) { + if (!hostSupportsSnapsthotForVolume(host, volume, isFromVmSnapshot)) { throw new CloudRuntimeException( "KVM Snapshot is not supported for Running VMs. It is disabled by default due to a possible volume corruption in certain cases. To enable it set global settings kvm.snapshot.enabled to True. See the documentation for more details."); } @@ -1489,9 +1489,14 @@ public void cleanupSnapshotsByVolume(Long volumeId) { @Override public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException { + return allocSnapshot(volumeId, policyId, snapshotName, locationType, false); + } + + @Override + public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType, Boolean isFromVmSnapshot) throws ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); VolumeInfo volume = volFactory.getVolume(volumeId); - supportedByHypervisor(volume); + supportedByHypervisor(volume, isFromVmSnapshot); // Verify permissions _accountMgr.checkAccess(caller, null, true, volume);