You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by nv...@apache.org on 2022/04/14 04:17:04 UTC

[cloudstack] branch main updated: Allow creating snapshot from VM snapshot (#4739)

This is an automated email from the ASF dual-hosted git repository.

nvazquez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new c7941278f7 Allow creating snapshot from VM snapshot (#4739)
c7941278f7 is described below

commit c7941278f7f670a2f1429c4055467a7f3b901dd6
Author: Rakesh <ra...@gmail.com>
AuthorDate: Thu Apr 14 06:16:59 2022 +0200

    Allow creating snapshot from VM snapshot (#4739)
    
    If `kvm.snapshot.enabled` is set to false then we cant create snapshot from
    VM snapshot. With this change, its possible to create snapshot from VM
    snapshot even when the global setting is set to false.
    Note that you still cant directly create a snapshot from volume though
---
 .../com/cloud/storage/snapshot/SnapshotApiService.java    |  4 ++++
 .../main/java/com/cloud/storage/VolumeApiServiceImpl.java |  4 ++--
 .../com/cloud/storage/snapshot/SnapshotManagerImpl.java   | 15 ++++++++++-----
 3 files changed, 16 insertions(+), 7 deletions(-)

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 cb67ba75ca..38e5e105a4 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 c31daf3693..1028898347 100644
--- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
@@ -3302,7 +3302,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             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
@@ -3358,7 +3358,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             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 d98125e389..207cf5d762 100755
--- a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -1126,7 +1126,7 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
         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;
         }
@@ -1138,7 +1138,7 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
             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;
                 }
@@ -1159,7 +1159,7 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
         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();
@@ -1183,7 +1183,7 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
             }
             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.");
                 }
@@ -1460,9 +1460,14 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
 
     @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);