Skip to content

Allow full clone volumes with thin provisioning #11177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

JoaoJandre
Copy link
Contributor

@JoaoJandre JoaoJandre commented Jul 10, 2025

Description

This PR 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.

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • build/CI
  • test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

Without setting the property, I deployed a VM, which used linked-clone to create the volume.

Afterward, I added the create.full.clone property to agent.properties, restarted the agent service, and created another VM. This time, the volume was full-clone.

How did you try to break this feature and the system with this change?

Copy link

codecov bot commented Jul 10, 2025

Codecov Report

Attention: Patch coverage is 11.11111% with 8 lines in your changes missing coverage. Please review.

Project coverage is 16.57%. Comparing base (8e4fe1c) to head (b942c0d).
Report is 16 commits behind head on main.

Files with missing lines Patch % Lines
.../hypervisor/kvm/storage/LibvirtStorageAdaptor.java 0.00% 8 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #11177      +/-   ##
============================================
- Coverage     16.57%   16.57%   -0.01%     
  Complexity    13988    13988              
============================================
  Files          5745     5745              
  Lines        510847   510853       +6     
  Branches      62140    62142       +2     
============================================
- Hits          84696    84682      -14     
- Misses       416677   416705      +28     
+ Partials       9474     9466       -8     
Flag Coverage Δ
uitests 3.91% <ø> (ø)
unittests 17.47% <11.11%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sureshanaparti
Copy link
Contributor

@blueorangutan package

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a new create.full.clone configuration to allow creating THIN-provisioned QCOW2 volumes as full clones instead of linked clones.

  • Introduces a boolean agent property CREATE_FULL_CLONE (default false).
  • Updates createDiskFromTemplate to branch on the new property for THIN provisioning.
  • Adds default entry in agent.properties and Javadoc in AgentProperties.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java Conditional full-clone logic added for THIN volumes based on new property
agent/src/main/java/com/cloud/agent/properties/AgentProperties.java Defined CREATE_FULL_CLONE property with Javadoc and default value
agent/conf/agent.properties Added commented default for create.full.clone
Comments suppressed due to low confidence (1)

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java:1327

  • There are no unit or integration tests verifying the new full-clone path; adding tests to cover both true and false scenarios for CREATE_FULL_CLONE would ensure the behavior remains correct.
                        if (createFullClone) {

@@ -1315,14 +1317,22 @@ public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template,
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);
Copy link
Preview

Copilot AI Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading the agent properties on each disk creation may incur unnecessary overhead; consider caching the CREATE_FULL_CLONE value or loading it once at adaptor initialization.

Suggested change
Boolean createFullClone = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.CREATE_FULL_CLONE);

Copilot uses AI. Check for mistakes.

@@ -1315,14 +1317,22 @@ public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template,
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);
Copy link
Preview

Copilot AI Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Prefer using a primitive boolean instead of the Boolean wrapper to avoid potential null unboxing issues and reduce overhead.

Suggested change
Boolean createFullClone = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.CREATE_FULL_CLONE);
boolean createFullClone = Boolean.TRUE.equals(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.CREATE_FULL_CLONE));

Copilot uses AI. Check for mistakes.

Copy link
Contributor

@DaanHoogland DaanHoogland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

took me a while of looking at this to have the penny drop. Code looks good @JoaoJandre , but what is the use case for this? I’d say one would want thin to be thin and fat to be fat. It seems now thin still makes a full clone given this setting and effectively becomes fat.

@JoaoJandre
Copy link
Contributor Author

took me a while of looking at this to have the penny drop. Code looks good @JoaoJandre , but what is the use case for this? I’d say one would want thin to be thin and fat to be fat. It seems now thin still makes a full clone given this setting and effectively becomes fat.

@DaanHoogland THIN, FAT and SPARSE are translated to preallocation methods in qemu-img. THIN being OFF, SPARSE being METADATA and FAT being FULL.

When using preallocation=full, qemu-img will write the full disk size to storage (filling it with zeros). When using preallocation=off, only the actual necessary data is written.

So, if you convert an image with virtual size as 50 GB, but real size 5 GB, using FULL, you'll get an image with 50 GB of real size. Using OFF, you'll end up with an image of 5GB of real size.

This is the use case of THIN and full-clone. You copy the template but do not preallocate the full disk size.

@DaanHoogland
Copy link
Contributor

DaanHoogland commented Jul 14, 2025

This is the use case of THIN and full-clone. You copy the template but do not preallocate the full disk size.

ok, so this is not a thick provisioned copy but just a byte by byte copy.

@slavkap
Copy link
Contributor

slavkap commented Jul 15, 2025

For me, the code looks good, but my only concern here is that the configuration create.full.clone should come from the management service as an API parameter or a property of a volume/VM, or template (I'm not sure exactly where). This is in case the administrators want some volumes to be full cloned and others not. In that case, they should change the value of the configuration every time from the agent.properties file, and restart the agent service

@weizhouapache
Copy link
Member

For me, the code looks good, but my only concern here is that the configuration create.full.clone should come from the management service as an API parameter or a property of a volume/VM, or template (I'm not sure exactly where). This is in case the administrators want some volumes to be full cloned and others not. In that case, they should change the value of the configuration every time from the agent.properties file, and restart the agent service

makes sense

@rosi-shapeblue rosi-shapeblue self-assigned this Jul 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

6 participants