Repository navigation
server: Avoid device id conflicts between data volumes, the CD-ROM and the config drive ISO - #14073
weizhouapache wants to merge 4 commits into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## 4.22 #14073 +/- ##
============================================
+ Coverage 18.03% 18.04% +0.01%
- Complexity 16286 16321 +35
============================================
Files 5937 5937
Lines 536771 536825 +54
Branches 65782 65791 +9
============================================
+ Hits 96787 96886 +99
+ Misses 428932 428882 -50
- Partials 11052 11057 +5
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🟡 Changes recommended
Reserving an additional device-id for ConfigDrive without expanding the computed max device-id range can reduce the maximum attachable data volumes and cause avoidable allocation failures.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR addresses KVM/libvirt disk target collisions when ConfigDrive is enabled by ensuring the device-id allocators avoid using the ConfigDrive ISO’s reserved disk sequence (4), preventing duplicate target devices on Q35/UEFI machine types.
Changes:
- Detect ConfigDrive presence via
VmDetailConstants.CONFIG_DRIVE_LOCATIONand skip device idCONFIGDRIVEDISKSEQduring device-id allocation. - Expose
CONFIGDRIVEDISKSEQpublicly so allocators can reference the reserved slot. - Update KVM import/restore volume attach path to use the updated allocator logic.
File summaries
| File | Description |
|---|---|
| server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java | Skip ConfigDrive’s reserved device id during device-id validation/allocation for volume attach. |
| server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java | Make ConfigDrive disk sequence constant publicly accessible. |
| server/src/main/java/com/cloud/hypervisor/KVMGuru.java | Skip ConfigDrive’s reserved device id when selecting the next available device id during VM restore/import flows. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| int maxDevices = getMaxDataVolumesSupported(vm) + 2; // add 2 to consider devices root volume and cdrom | ||
| int maxDeviceId = maxDevices - 1; | ||
| List<VolumeVO> vols = _volsDao.findByInstance(vm.getId()); | ||
| boolean vmHasConfigDrive = vmInstanceDetailsDao.findDetail(vm.getId(), VmDetailConstants.CONFIG_DRIVE_LOCATION) != null; |
There was a problem hiding this comment.
what happens for a vm deployed with startvm=false and then given three data disks? the config drive detail only shows up on first start, so the third disk still lands on 4
There was a problem hiding this comment.
good point. I did not consider this case.
maybe we need to determine if configdrive ISO is needed by the network/offering providers.
There was a problem hiding this comment.
makes sense, checking if the default network uses config drive for user data would work even before the first start
|
need re-work to consider
moving to draft |
| * {@link TemplateManager#CDROM_PRIMARY_DEVICE_SEQ}. | ||
| */ | ||
| protected int getVmCdromCount(VirtualMachine vm) { | ||
| return 1; |
There was a problem hiding this comment.
on main a second cd drive sits on 4 too, so should the config drive move past the last cd slot when this merges forward?
There was a problem hiding this comment.
@Damans227
yes, there will be another PR target to main, which calculate the count of CD-ROMs from vm
…olumes on KVM ConfigDriveNetworkElement hardcodes disk sequence 4 (CONFIGDRIVEDISKSEQ) for the config drive ISO, but the volume device-id allocators (VolumeApiServiceImpl.getDeviceId, KVMGuru.getNextAvailableDeviceId) only look at persisted VolumeVO rows and have no knowledge that slot 4 is reserved by the config drive. When a VM using ConfigDrive already has data disks on device ids 1 and 2, attaching a 3rd data disk gets assigned device id 4 as well, producing two disks with the same libvirt target device (e.g. "sde") once both end up on the same bus namespace, as happens with Q35/UEFI machine types. Both allocators now skip CONFIGDRIVEDISKSEQ when the VM has a config drive (detected via the existing CONFIG_DRIVE_LOCATION vm detail), the same way they already permanently reserve device id 3 for the CD-ROM slot.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Data volumes could be assigned the same device id as the CD-ROM or the config drive ISO, which end up with the same libvirt target name (e.g. sde) when they are on the same bus namespace (SATA with UEFI/Q35). Add VolumeApiService.getReservedDeviceIds(), which returns the device ids of the CD-ROM devices and of the config drive ISO when the Instance uses config drive. The config drive is detected from the network providers (Dhcp, Dns, UserData), so Instances which have never been started are covered as well as the ones with the config drive location detail. The reserved ids are skipped when allocating device ids in: - attach volume - restore of volumes and Instances from backup - import of Instances (unmanaged Instances and VMware to KVM) The max number of data volumes is preserved when device ids are reserved, and the error message of an invalid deviceId lists the reserved ids.
Move the calculation of the device ids reserved for the CD-ROM and the config drive ISO to TemplateManager, as getCdromDeviceIds(). An Instance has one CD-ROM, and the config drive ISO is one more CD-ROM (device id 4) when any network of the Instance uses config drive. VolumeApiService#getReservedDeviceIds() delegates to it, and a variant with the usage of config drive is added for the cases where the networks of the Instance are not known yet (VM import and backup restore).
4eab500 to
a28af1a
Compare
| * @param vm the Instance | ||
| * @return the device ids of the CD-ROM devices, including the one of the config drive ISO if the Instance uses config drive | ||
| */ | ||
| Set<Long> getCdromDeviceIds(VirtualMachine vm); |
|
I deployed two Ubuntu 24 VMs on kvm1.
With config drive, ids 3 and 4 are reserved for the CD-ROM and the config drive ISO. Without it, only id 3 is reserved, so id 4 is available to a data disk. |
Damans227
left a comment
There was a problem hiding this comment.
thanks @weizhouapache, fix looks right. LGTM





Description
This PR fixes #13484 (the fix for main, which also covers multiple ISOs per Instance (#14321), is in #14407).
On KVM, a data volume could get the same device id as the CD-ROM or the config drive ISO. When both devices end up with the same
sd*target name (SATA CD-ROMs on UEFI/q35 Instances plus SCSI or SATA data disks), libvirt rejects the domain XML withtarget 'sde' duplicated for disk sources .... The config drive ISO is attached with the device id 4, but the allocators of volume device ids only reserved the device id 3 (the CD-ROM), so the third data volume got the device id 4.The same conflict could happen when attaching a volume to a stopped Instance (it is accepted, and the Instance cannot start any more), when restoring volumes/Instances from backup, and when importing Instances (unmanaged Instances and VMware to KVM), which numbered the data disks 1, 2, 3, 4, ...
Device ids of an Instance
0341,2, then the next device ids which are not used by the CD-ROM and the config drive. The maximum number of data volumes is not reduced by the reserved device ids.Example (default maximum of 6 data volumes):
31,2,4,5,6,73,41,2,5,6,7,8An Instance uses config drive if the Dhcp, Dns or UserData service of any of its networks is provided by ConfigDrive (checked on the network providers, so it also works for Instances which have never been started), or if it has the config drive location detail.
Only one ISO can be attached to an Instance in this version, so there is a single CD-ROM (device id
3). The device ids of the CD-ROMs are obtained fromgetVmCdromCount(), which returns 1, so that the logic can be merged forward to main, where it is calculated from the Instance (#14407).Changes
VolumeApiService.getReservedDeviceIds(vm)returns the device ids reserved for the CD-ROM and the config drive ISO (if the Instance uses config drive). It is used when allocating device ids in:deviceidparameter, whose error message now lists the reserved ids). This also covers Instances which are stopped.KVMGuru). When a whole Instance is restored, its networks may not be available any more, so the device id of the config drive is always kept free.ConfigDriveNetworkElement.CONFIGDRIVEDISKSEQis public, so it can be used by the allocators.Notes
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
Screenshots (if appropriate):
How Has This Been Tested?
Unit tests (
VolumeApiServiceImplTest,KVMGuruTest,UnmanagedVMsManagerImplTest) cover the reserved device ids with and without config drive (including Instances which have never been started, detected from the network providers), the device id allocation for attach volume, restore and import, that the maximum number of data volumes can still be attached, and the error message of an invaliddeviceid.This branch has not been run on a 4.22 environment since the last change. The same logic was tested manually on main (see #14407), with Instances on BIOS and UEFI/q35, with and without config drive, attaching volumes to running and stopped Instances, and importing an unmanaged Instance.
How did you try to break this feature and the system with this change?