Skip to content

[VMware] Disk controller mappings#10454

Open
winterhazel wants to merge 20 commits intoapache:mainfrom
scclouds:disk-controller-mappings
Open

[VMware] Disk controller mappings#10454
winterhazel wants to merge 20 commits intoapache:mainfrom
scclouds:disk-controller-mappings

Conversation

@winterhazel
Copy link
Copy Markdown
Member

Description

This is a refactor of the disk controller related logic for VMware that also adds support for SATA and NVME controllers.

A detailed description of these changes is available at https://cwiki.apache.org/confluence/display/CLOUDSTACK/Disk+Controller+Mappings.

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

How Has This Been Tested?

The tests below were performed for VMs with the following rootDiskController and dataDiskController configurations:

  • osdefault/osdefault (converted to lsilogic/lsilogic)
  • ide/ide
  • pvscsi/pvscsi
  • sata/sata
  • nvme/nvme
  • sata/lsilogic
  • ide/osdefault
  • osdefault/ide
  1. VM deployment: I deployed one VM with each of the configurations. I verified in vCenter that they had the correct amount of disk controllers, and that each volume was associated to the expected controller. The sata/lsilogic VM was the only one that had a data disk; the others only had a root disk.

  2. VM start: I stopped the VMs deployed in (1) and started them again. I verified in vCenter that they had the correct amount of disk controllers, and that each volume was associated to the expected controller.

  3. Disk attachment: while the VMs were running, I tried to attach a data disk. All the data disks were attached successfully (expect for the VMs using IDE as the data disk controller, which does not allow hot plugging disks; for these, I attached the disks after stopping the VM). I verified that all the disks were using the expected controller. Then, I stopped and started the VM, and verified that they were still using the expected controllers. Finally, I stoped the VMs and detached the volumes. I verified that they were detached successfully.

  4. VM import: I unmanaged the VMs and imported them back. I verified that their settings were infered successfully according to the existing disk controllers. Then, I started the VMs, and verified that the controllers and the volumes were configured correctly.

The next tests were performed using the following imported VMs:

  • osdefault/osdefault
  • ide/ide
  • nvme/nvme
  • sata/lsilogic
  1. Volume migration: I migrated the volumes from NFS to local storage, and verified that the migration finished successfully. Then, I started the VMs and verified that both the controllers and the disks were configured correctly.

  2. Volume resize: I expanded all of the disks, and verified in vCenter that their size was changed. Then, I started the VMs and verified that both the controllers and the disks were configured correctly.

  3. VM snapshot: I took some VM snapshots, started the VMs and verified that everything was ok. I changed the configurations of the VM using osdefault/osdefault to sata/sata and started the VM to begin the reconfiguration process. I verified that the disk controllers in use were not removed, and that the disks were still associated with the previous controllers; however, the SATA controllers were also created. The VM was working as expected. Finally, I deleted the VM snapshots.

  4. Template creation from volume: I created templates from the root disks. Then, I deployed VMs from the templates. I verified that all the VMs had the same disk controllers as the original VM, and that the only existing disk was correctly associated with the configured root disk controller.

  5. Template creation from volume snapshot: I took snapshots from the root disks, and created templates from the snapshots. Then, I deployed VMs from the templates. I verified that all the VMs had the same disk controllers as the original VM, and that the only existing disk was correctly associated with the configured root disk controller.

  6. VM scale: with the VMs stopped, I scaled the VM from Small Instance to Medium Instance. I verified that the offering was changed. I started the VMs, and verified that the VMs were correctly reconfigured in vCenter.

Other tests:

  • System VM creation: after applying the patches, I recreated the SSVM and the CPVM. I verified that they were using a single LSI Logic controller. I also verified the controllers of a new VR and of an existing VR.

  • I attached 3 disks to the ide/ide controller. When trying to attach a 4th disk, I got an expected exception, as the IDE bus reached the maximum amount of devices (the 4th one was the CD/DVD drive).

  • I removed all the disks from the sata/lsilogic VM. I tried to attach the root disk again, and verified that it was attached successfully. I started the VM, and verified that it was configured correctly.

  • I attached 8 disks to the pvscsi/pvscsi VM, and verified that the 8th disk was successfully attached to device number 8 (device number 7 is reserved for the controller).

@winterhazel
Copy link
Copy Markdown
Member Author

@blueorangutan package

@winterhazel winterhazel changed the title Disk controller mappings [VMware] Disk controller mappings Feb 24, 2025
@blueorangutan
Copy link
Copy Markdown

@winterhazel a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 24, 2025

Codecov Report

❌ Patch coverage is 62.92776% with 195 lines in your changes missing coverage. Please review.
✅ Project coverage is 18.09%. Comparing base (1bff543) to head (f013bab).

Files with missing lines Patch % Lines
...he/cloudstack/storage/DiskControllerMappingVO.java 31.86% 61 Missing and 1 partial ⚠️
...oud/hypervisor/vmware/resource/VmwareResource.java 74.65% 31 Missing and 6 partials ⚠️
...m/cloud/hypervisor/vmware/mo/VirtualMachineMO.java 78.46% 23 Missing and 5 partials ⚠️
...tack/storage/dao/DiskControllerMappingDaoImpl.java 0.00% 20 Missing ⚠️
...com/cloud/hypervisor/vmware/util/VmwareHelper.java 86.86% 13 Missing ⚠️
.../com/cloud/agent/api/SecStorageVMSetupCommand.java 0.00% 6 Missing ⚠️
...esource/VmwareSecondaryStorageResourceHandler.java 0.00% 6 Missing ⚠️
...ain/java/com/cloud/api/query/QueryManagerImpl.java 0.00% 6 Missing ⚠️
...cloud/storage/resource/VmwareStorageProcessor.java 0.00% 5 Missing ⚠️
.../secondarystorage/SecondaryStorageManagerImpl.java 0.00% 4 Missing ⚠️
... and 4 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #10454      +/-   ##
============================================
+ Coverage     18.02%   18.09%   +0.06%     
- Complexity    16460    16553      +93     
============================================
  Files          5968     5970       +2     
  Lines        537213   537122      -91     
  Branches      65975    65884      -91     
============================================
+ Hits          96825    97179     +354     
+ Misses       429469   429012     -457     
- Partials      10919    10931      +12     
Flag Coverage Δ
uitests 3.53% <ø> (ø)
unittests 19.26% <62.92%> (+0.07%) ⬆️

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.

@blueorangutan
Copy link
Copy Markdown

Packaging result [SF]: ✖️ el8 ✖️ el9 ✖️ debian ✖️ suse15. SL-JID 12549

@winterhazel
Copy link
Copy Markdown
Member Author

@DaanHoogland it seems there were some merge issues in main. org.apache.cloudstack.backup.VeeamBackupProvider is missing some methods and imports.

@DaanHoogland
Copy link
Copy Markdown
Contributor

@DaanHoogland it seems there were some merge issues in main. org.apache.cloudstack.backup.VeeamBackupProvider is missing some methods and imports.

I'll check and update

@DaanHoogland
Copy link
Copy Markdown
Contributor

@winterhazel , please see #10457 . I have had no time (or infra) to test yet.

@winterhazel
Copy link
Copy Markdown
Member Author

@blueorangutan package

@blueorangutan
Copy link
Copy Markdown

@winterhazel a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ debian ✔️ suse15. SL-JID 12586

@github-actions
Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@JoaoJandre
Copy link
Copy Markdown
Contributor

@winterhazel could you fix the conflicts?

@winterhazel
Copy link
Copy Markdown
Member Author

@blueorangutan package

@blueorangutan
Copy link
Copy Markdown

@winterhazel a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ debian ✔️ suse15. SL-JID 13603

@sureshanaparti sureshanaparti requested a review from nvazquez June 5, 2025 09:30
@winterhazel
Copy link
Copy Markdown
Member Author

@blueorangutan package

@blueorangutan
Copy link
Copy Markdown

@winterhazel a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@winterhazel winterhazel marked this pull request as ready for review December 13, 2025 23:33
@blueorangutan
Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 16038

@github-actions
Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 5, 2026

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@winterhazel
Copy link
Copy Markdown
Member Author

@blueorangutan package

@blueorangutan
Copy link
Copy Markdown

@winterhazel a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 16624

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 9, 2026

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@winterhazel
Copy link
Copy Markdown
Member Author

@blueorangutan package

@blueorangutan
Copy link
Copy Markdown

@winterhazel a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan
Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 17276

@DaanHoogland DaanHoogland requested a review from Copilot March 30, 2026 10:09
@DaanHoogland
Copy link
Copy Markdown
Contributor

@blueorangutan test matrix

@blueorangutan
Copy link
Copy Markdown

@DaanHoogland a [SL] Trillian-Jenkins matrix job (EL8 mgmt + EL8 KVM, Ubuntu22 mgmt + Ubuntu22 KVM, EL8 mgmt + VMware 7.0u3, EL9 mgmt + XCP-ng 8.2 ) has been kicked to run smoke tests

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 29 out of 29 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return controllerReference.equals(that.getControllerReference());
}

@Override
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

equals() is overridden but hashCode() is not. This breaks the general contract for hash-based collections (e.g., HashSet/HashMap) and can cause duplicate mappings or failed lookups when mappings are compared/collected. Add a hashCode() implementation consistent with equals() (or switch to Objects.hash(controllerReference)).

Suggested change
@Override
@Override
public int hashCode() {
return controllerReference != null ? controllerReference.hashCode() : 0;
}
@Override

Copilot uses AI. Check for mistakes.
Comment on lines 1226 to +1230
String recommendedDiskControllerClassName = vmMo != null ? vmMo.getRecommendedDiskController(null) : host.getRecommendedDiskController(guestOsIdentifier);
String recommendedDiskController = DiskControllerType.getType(recommendedDiskControllerClassName).toString();
DiskControllerMappingVO recommendedDiskController = getAllSupportedDiskControllerMappingsExceptOsDefault().stream()
.filter(c -> c.getControllerReference().contains(recommendedDiskControllerClassName))
.findFirst()
.orElseThrow(() -> new CloudRuntimeException("Recommended disk controller is not mapped."));
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

Selecting the recommended controller mapping via controllerReference.contains(recommendedDiskControllerClassName) + findFirst() is ambiguous when multiple mappings share the same controller reference (e.g., the default DB mappings include both scsi and lsilogic for VirtualLsiLogicController). This can make the chosen mapping depend on DB/list ordering. Prefer an unambiguous match (e.g., exact class name match) and/or a deterministic tie-breaker (e.g., prefer lsilogic over the legacy alias) to keep behavior stable.

Copilot uses AI. Check for mistakes.
continue;
}
for (int bus = 0; bus < diskController.getMaxControllerCount(); bus++) {
VirtualController controller = (VirtualController) controllerClass.newInstance();
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

Class#newInstance() is deprecated and can fail in surprising ways (e.g., with non-public constructors). Use getDeclaredConstructor().newInstance() instead, and consider surfacing a clearer exception if instantiation fails for a configured mapping.

Suggested change
VirtualController controller = (VirtualController) controllerClass.newInstance();
VirtualController controller = (VirtualController) controllerClass.getDeclaredConstructor().newInstance();

Copilot uses AI. Check for mistakes.
Comment on lines +1265 to +1275
public static void configureDiskControllerMappingsInVmwareBaseModule(List<DiskControllerMappingVO> mappings) {
List<DiskControllerMappingVO> validMappings = new ArrayList<>();

for (DiskControllerMappingVO mapping : mappings) {
try {
if (!DiskControllerType.osdefault.toString().equals(mapping.getName())) {
Class.forName(mapping.getControllerReference());
}
LOGGER.debug("Adding disk controller mapping with name [{}] and controller reference [{}] to the list of available disk controllers.",
mapping.getName(), mapping.getControllerReference());
validMappings.add(mapping);
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

configureDiskControllerMappingsInVmwareBaseModule only validates that the controller class exists, but later logic assumes non-osdefault mappings have non-null busName, maxDeviceCount, maxControllerCount, and vmdkAdapterType. Since the DB schema allows these columns to be NULL, a partially configured mapping can later trigger NPEs or incorrect behavior. Consider validating required fields here (and skipping invalid rows) so the runtime surface area is safer.

Copilot uses AI. Check for mistakes.
if (!unsupportedDiskControllers.isEmpty()) {
String names = unsupportedDiskControllers.stream().map(DiskControllerMappingVO::getName).collect(Collectors.joining(", "));
String requiredVersions = unsupportedDiskControllers.stream().map(DiskControllerMappingVO::getMinHardwareVersion).collect(Collectors.joining(", "));
logger.debug("Virtual machine [{}] does not support disk controllers [{}], as its virtual hardware version is [{}] but the controllers require, respectfully, versions [{}].",
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

Typo in log message: "respectfully" should be "respectively" (the sentence is describing required versions, not expressing respect).

Suggested change
logger.debug("Virtual machine [{}] does not support disk controllers [{}], as its virtual hardware version is [{}] but the controllers require, respectfully, versions [{}].",
logger.debug("Virtual machine [{}] does not support disk controllers [{}], as its virtual hardware version is [{}] but the controllers require, respectively, versions [{}].",

Copilot uses AI. Check for mistakes.
String diskController = VmwareHelper.getControllerBasedOnDiskType(chosenDiskControllers, disk);
// Let's first find which disk controller should be used for the volume being attached.
//
// `controllerInfo` can not be null here. It is always defined when creating the `AttachComand` in
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

Typo in comment: AttachComand should be AttachCommand.

Suggested change
// `controllerInfo` can not be null here. It is always defined when creating the `AttachComand` in
// `controllerInfo` can not be null here. It is always defined when creating the `AttachCommand` in

Copilot uses AI. Check for mistakes.
Comment on lines +332 to +342
public void addDiskControllersToVmConfigSpecTestMaximumAmmountOfControllersIsAdded() throws Exception {
DiskControllerMappingVO nvmeMapping = VmwareHelper.getDiskControllerMapping("nvme", null);
DiskControllerMappingVO sataMapping = VmwareHelper.getDiskControllerMapping("sata", null);
Set<DiskControllerMappingVO> requiredControllers = new HashSet<>();
requiredControllers.add(nvmeMapping);
requiredControllers.add(sataMapping);

VmwareHelper.addDiskControllersToVmConfigSpec(virtualMachineConfigSpecMock, requiredControllers, false);

int expectedControllerAmmount = nvmeMapping.getMaxControllerCount() + sataMapping.getMaxControllerCount();
Assert.assertEquals(expectedControllerAmmount, virtualMachineConfigSpecMock.getDeviceChange().size());
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

Typo in test/variable naming: "Ammount" should be "Amount" (e.g., expectedControllerAmount, ...MaximumAmount...). Renaming improves readability and avoids propagating the typo to future tests.

Copilot uses AI. Check for mistakes.
@blueorangutan
Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-15764)

@blueorangutan
Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-15762)

@blueorangutan
Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-15763)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants