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

sureshanaparti 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 5ea1ada59a4 Allow full clone volumes with thin provisioning in KVM 
(#11177)
5ea1ada59a4 is described below

commit 5ea1ada59a43bccc699f09efb3a7a89df1562017
Author: João Jandre <48719461+joaojan...@users.noreply.github.com>
AuthorDate: Thu Jul 31 07:42:17 2025 -0300

    Allow full clone volumes with thin provisioning in KVM (#11177)
    
    It adds a configuration called create.full.clone to the agent.properties 
file. When set to true, all QCOW2 volumes created will be full-clone. If false 
(default), the current behavior remains, where only FAT and SPARSE volumes are 
full-clone and THIN volumes are linked-clone.
---
 agent/conf/agent.properties                              |  3 +++
 .../java/com/cloud/agent/properties/AgentProperties.java |  8 ++++++++
 .../hypervisor/kvm/storage/LibvirtStorageAdaptor.java    | 16 +++++++++++++---
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties
index e70acee229d..cd31b0db56d 100644
--- a/agent/conf/agent.properties
+++ b/agent/conf/agent.properties
@@ -447,3 +447,6 @@ iscsi.session.cleanup.enabled=false
 
 # Timeout (in seconds) to wait for the incremental snapshot to complete.
 # incremental.snapshot.timeout=10800
+
+# If set to true, creates VMs as full clones of their templates on KVM 
hypervisor. Creates as linked clones otherwise.
+# create.full.clone=false
diff --git 
a/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java 
b/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
index 47255762a05..847d1bb2396 100644
--- a/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
+++ b/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
@@ -863,6 +863,14 @@ public class AgentProperties{
      * */
     public static final Property<Integer> REVERT_SNAPSHOT_TIMEOUT = new 
Property<>("revert.snapshot.timeout", 10800);
 
+    /**
+     *  If set to true, creates VMs as full clones of their templates on KVM 
hypervisor. Creates as linked clones otherwise. <br>
+     * Data type: Boolean. <br>
+     * Default value: <code>false</code>
+     */
+    public static final Property<Boolean> CREATE_FULL_CLONE = new 
Property<>("create.full.clone", false);
+
+
     public static class Property <T>{
         private String name;
         private T defaultValue;
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
index 7c66a91876f..bf851831cd0 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
@@ -32,6 +32,8 @@ import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
+import com.cloud.agent.properties.AgentProperties;
+import com.cloud.agent.properties.AgentPropertiesFileHandler;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.utils.cryptsetup.KeyFile;
 import org.apache.cloudstack.utils.qemu.QemuImageOptions;
@@ -1315,14 +1317,22 @@ public class LibvirtStorageAdaptor implements 
StorageAdaptor {
                         
passphraseObjects.add(QemuObject.prepareSecretForQemuImg(format, 
QemuObject.EncryptFormat.LUKS, keyFile.toString(), "sec0", options));
                         
disk.setQemuEncryptFormat(QemuObject.EncryptFormat.LUKS);
                     }
+
+                    QemuImgFile srcFile = new QemuImgFile(template.getPath(), 
template.getFormat());
+                    Boolean createFullClone = 
AgentPropertiesFileHandler.getPropertyValue(AgentProperties.CREATE_FULL_CLONE);
                     switch(provisioningType){
                     case THIN:
-                        QemuImgFile backingFile = new 
QemuImgFile(template.getPath(), template.getFormat());
-                        qemu.create(destFile, backingFile, options, 
passphraseObjects);
+                        logger.info("Creating volume [{}] {} backing file [{}] 
as the property [{}] is [{}].", destFile.getFileName(), createFullClone ? 
"without" : "with",
+                                template.getPath(), 
AgentProperties.CREATE_FULL_CLONE.getName(), createFullClone);
+                        if (createFullClone) {
+                            qemu.convert(srcFile, destFile, options, 
passphraseObjects, null, false);
+                        } else {
+                            qemu.create(destFile, srcFile, options, 
passphraseObjects);
+                        }
                         break;
                     case SPARSE:
                     case FAT:
-                        QemuImgFile srcFile = new 
QemuImgFile(template.getPath(), template.getFormat());
+                        srcFile = new QemuImgFile(template.getPath(), 
template.getFormat());
                         qemu.convert(srcFile, destFile, options, 
passphraseObjects, null, false);
                         break;
                     }

Reply via email to