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

Pearl1594 pushed a commit to branch clvm-ng-bitmap-incsnaps
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit d8a5adbcc666ea05dec24766e67942ad76c328e8
Author: Pearl1594 <[email protected]>
AuthorDate: Thu Oct 22 15:39:22 2026 -0400

    Add support for clvm incremental volume snaps
---
 .../hypervisor/kvm/storage/KVMStorageProcessor.java    | 18 ++++++++++--------
 .../cloud/storage/snapshot/SnapshotManagerImpl.java    |  7 ++++---
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index 0cb32da318e..c14b875a0f2 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -2095,7 +2095,15 @@ public class KVMStorageProcessor implements 
StorageProcessor {
             String diskPath = disk.getPath();
             String snapshotPath = diskPath + File.separator + snapshotName;
             SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-            if (DomainInfo.DomainState.VIR_DOMAIN_RUNNING.equals(state) && 
!primaryPool.isExternalSnapshot()) {
+            boolean isClvmNgIncremental = primaryPool.getType() == 
StoragePoolType.CLVM_NG && snapshotTO.isKvmIncrementalSnapshot();
+            if (isClvmNgIncremental && secondaryPool == null) {
+                String errorMsg = String.format("Incremental snapshots for 
CLVM_NG require secondary storage. " +
+                        "Please configure secondary storage or disable 
incremental snapshots for volume [%s].", volume.getName());
+                logger.error(errorMsg);
+                return new CreateObjectAnswer(errorMsg);
+            }
+            boolean isLiveClvmNgIncremental = isClvmNgIncremental && 
(DomainInfo.DomainState.VIR_DOMAIN_RUNNING.equals(state) || 
DomainInfo.DomainState.VIR_DOMAIN_PAUSED.equals(state));
+            if ((DomainInfo.DomainState.VIR_DOMAIN_RUNNING.equals(state) && 
!primaryPool.isExternalSnapshot()) || isLiveClvmNgIncremental) {
                 if (snapshotTO.isKvmIncrementalSnapshot()) {
                     newSnapshot = 
takeIncrementalVolumeSnapshotOfRunningVm(snapshotTO, primaryPool, 
secondaryPool, imageStoreTo != null ? imageStoreTo.getUrl() : null, 
snapshotName, volume, vm, conn, cmd.getWait());
                 } else {
@@ -2109,13 +2117,7 @@ public class KVMStorageProcessor implements 
StorageProcessor {
                         newSnapshot.setPhysicalSize(snapshotSize);
                     }
                 } else if (primaryPool.getType() == StoragePoolType.CLVM || 
primaryPool.getType() == StoragePoolType.CLVM_NG) {
-                    if (primaryPool.getType() == StoragePoolType.CLVM_NG && 
snapshotTO.isKvmIncrementalSnapshot()) {
-                        if (secondaryPool == null) {
-                            String errorMsg = String.format("Incremental 
snapshots for CLVM_NG require secondary storage. " +
-                                    "Please configure secondary storage or 
disable incremental snapshots for volume [%s].", volume.getName());
-                            logger.error(errorMsg);
-                            return new CreateObjectAnswer(errorMsg);
-                        }
+                    if (isClvmNgIncremental) {
                         logger.info("Taking incremental snapshot of CLVM_NG 
volume [{}] using QCOW2 backup to secondary storage.", volume.getName());
                         newSnapshot = 
takeIncrementalVolumeSnapshotOfStoppedVm(snapshotTO, primaryPool, secondaryPool,
                                 imageStoreTo.getUrl(), snapshotName, volume, 
conn, cmd.getWait());
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 2d23e22a015..1ee1a1fde64 100755
--- a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -1638,8 +1638,9 @@ public class SnapshotManagerImpl extends 
MutualExclusiveIdsManagerBase implement
         boolean backupSnapToSecondary = 
isBackupSnapshotToSecondaryForZone(volume.getDataCenterId());
 
         StoragePoolType poolType = volume.getStoragePoolType();
+        boolean isClvmNgIncrementalCandidate = StoragePoolType.CLVM_NG == 
poolType && kvmIncrementalSnapshot.valueIn(clusterId);
 
-        if (isKvmAndFileBasedStorage && backupSnapToSecondary) {
+        if ((isKvmAndFileBasedStorage || isClvmNgIncrementalCandidate) && 
backupSnapToSecondary) {
             DataStore imageStore = 
snapshotSrv.findSnapshotImageStore(snapshot);
             if (imageStore == null) {
                 throw new CloudRuntimeException(String.format("Could not find 
any secondary storage to allocate snapshot [%s].", snapshot));
@@ -1663,7 +1664,7 @@ public class SnapshotManagerImpl extends 
MutualExclusiveIdsManagerBase implement
             SnapshotInfo snapshotOnPrimary = 
snapshotStrategy.takeSnapshot(snapshot);
 
             if (backupSnapToSecondary) {
-                if (!isKvmAndFileBasedStorage) {
+                if (!isKvmAndFileBasedStorage && 
!isClvmNgIncrementalCandidate) {
                     backupSnapshotToSecondary(payload.getAsyncBackup(), 
snapshotStrategy, snapshotOnPrimary, payload.getZoneIds(), 
payload.getStoragePoolIds());
                     if (!payload.getAsyncBackup() && 
ClvmPoolManager.isClvmPoolType(storagePool.getPoolType())) {
                         _snapshotStoreDao.removeBySnapshotStore(snapshotId, 
snapshotOnPrimary.getDataStore().getId(), 
snapshotOnPrimary.getDataStore().getRole());
@@ -1877,7 +1878,7 @@ public class SnapshotManagerImpl extends 
MutualExclusiveIdsManagerBase implement
             payload.setLocationType(null);
         }
 
-        if (isKvmAndFileBasedStorage && 
kvmIncrementalSnapshot.valueIn(clusterId)) {
+        if ((isKvmAndFileBasedStorage || StoragePoolType.CLVM_NG == poolType) 
&& kvmIncrementalSnapshot.valueIn(clusterId)) {
             payload.setKvmIncrementalSnapshot(true);
         }
     }

Reply via email to