Repository navigation
server,kvm: Avoid device id conflicts between data volumes, CD-ROMs and the config drive ISO - #14407
weizhouapache wants to merge 6 commits into
Conversation
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
Data volumes could be assigned the same device id as one of the CD-ROM devices 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). With multiple CD-ROM support, the KVM agent defines all the CD-ROMs supported by the host at boot, so any slot after the primary one can conflict. 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 number of CD-ROM devices is returned by TemplateManager.getVmCdromCount(), based on the CD-ROM cap advertised by the host and the ISOs attached. 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.
The config drive ISO is attached as a CD-ROM, but its device id was hardcoded to 4, which is also the device id of the second ISO CD-ROM when multiple ISOs are supported. With vm.iso.max.count >= 2 the Instance could get two CD-ROMs on the same device id. The config drive ISO is now the CD-ROM following the ones of the ISOs, so its device id is the primary CD-ROM device id plus the number of the CD-ROMs of the ISOs (TemplateManager.getConfigDriveDeviceId). As the config drive ISO takes one of the CD-ROMs supported by the host, the maximum number of ISOs of an Instance using config drive is lowered by one. The number of CD-ROM devices of an Instance (TemplateManager.getVmCdromCount) includes the config drive ISO, so the device ids reserved for the volumes follow it, and the volume device id allocators do not need to know about the config drive any more. The KVM agent finds the config drive CD-ROM by the path of its ISO, and keeps its label and bus when refreshing it, instead of using the hardcoded id 4 and the label hdd (which does not match the SATA CD-ROMs of UEFI Instances).
9fa2580 to
3076489
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #14407 +/- ##
============================================
+ Coverage 20.39% 20.41% +0.01%
- Complexity 21283 21322 +39
============================================
Files 6481 6481
Lines 588040 588108 +68
Branches 72021 72034 +13
============================================
+ Hits 119957 120049 +92
+ Misses 455052 455029 -23
+ Partials 13031 13030 -1
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:
|
vm.iso.max.count is the maximum number of ISOs of an Instance, so it should not take the config drive ISO into account: the config drive ISO is attached as an additional CD-ROM, following the ones of the ISOs. As the IDE bus only has the slots of the first MAX_CDROMS_PER_VM CD-ROMs (hdc and hdd), the KVM agent attaches the CD-ROMs beyond these slots (e.g. the config drive ISO following the maximum number of ISOs) on the SATA bus.
| } | ||
| } | ||
|
|
||
| @Override |
There was a problem hiding this comment.
The changes in this file looks good but I am not sure if this is the place where these methods should exist.
vishesh92
left a comment
There was a problem hiding this comment.
just one minor comment. otherwise the changes looks good.
The config drive ISO keeps the device id 4, whatever the number of CD-ROMs of the Instance. The CD-ROMs of the ISOs are attached around it. This reverts the commits: - server,kvm: Do not count the config drive ISO in vm.iso.max.count - server,kvm: Calculate the device id of the config drive ISO
The config drive ISO keeps the device id 4, whatever the number of ISOs of the Instance. When an Instance uses config drive, the CD-ROMs of the ISOs which would use that device id or the next ones are moved to the next device ids, i.e. the CD-ROMs are, by device id: ISO 1 (3), config drive (4), ISO 2 (5), ISO 3 (6), ... The ISO slots stored for the Instance (user_vm.iso_id and vm_iso_map) are not changed. They are converted to device ids when the CD-ROMs are defined for the Instance, and when an ISO is attached or detached, so Instances which already have an ISO in the slot following the first one do not need to be updated. The number of CD-ROM devices of an Instance (TemplateManager.getVmCdromCount) includes the one of the config drive ISO, so the device ids reserved for the volumes cover all of them. When the networks of an Instance are not known yet (import, restore from backup), the config drive is always assumed. CloudStack supports 2 CD-ROMs per Instance on the IDE bus (hdc and hdd, the first two slots are kept for the disks). The KVM agent defines the CD-ROMs beyond these slots on the SATA bus.
TemplateManager exposed the number of CD-ROMs of an Instance, which the only caller (VolumeApiServiceImpl) converted back to the device ids starting from the primary CD-ROM device id. Return the device ids directly (TemplateManager.getCdromDeviceIds), so the callers do not have to assume that they are consecutive, and the number of CD-ROMs becomes an internal detail of TemplateManagerImpl.
|
overall the changes look good. nit: what happens if a running vm is added to a config drive network and then gets a second iso? looks like the iso goes to a drive that was never set up at start, so the attach fails until a restart. |
good point. if so, I would advise to reserve device id 3 as primary CD-ROM, and device id 4 as configdrive ISO. if the VM use IDE controller which support 2 CDROMs, the additional CD-ROMs (from 2nd CDROM) will use SATA controller or 2nd IDE controller, due to hardcoded |
@weizhouapache right, the limit of 2 is ours, not qemu's. with 4 always kept for the config drive, the ide bus is full after the first cd, so extra isos go on sata or a second ide controller. that also covers the running vm case, since the second iso no longer moves when a config drive shows up. |
Description
This PR fixes #13484 and #14321 (the fix for 4.22 is in #14073).
On KVM, a data volume could get the same device id as a CD-ROM or as 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 ...:Besides the attach volume API, the same conflicts could happen when attaching volumes to a stopped Instance (the conflict only shows up when it is started), 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
034, always4,5, ... without config drive;5,6, ... with config drive (the device id of the config drive is skipped)1,2, then the next device ids which are not used by a CD-ROM. The maximum number of data volumes is not reduced by the reserved device ids.vm.iso.max.countis the maximum number of ISOs, the config drive ISO is not counted. It is limited by the number of CD-ROMs supported by the host (host.cdrom.max.count: 2 for KVM, 1 if the host does not advertise it).user_vm.iso_idandvm_iso_map) are not changed: they are 3, 4, 5, ... They are converted to device ids when the CD-ROMs are defined for the Instance and when an ISO is attached or detached. So an Instance which already has an ISO stored in the second slot does not need to be updated, and the config drive keeps the device id 4.hdcandhdd, as the first two slots are kept for the disks). The CD-ROMs with a device id beyond them (e.g. ISO 2 after the config drive ISO) are put on the SATA bus by the KVM agent. UEFI Instances have all their CD-ROMs on the SATA bus.Examples (KVM host which supports 2 CD-ROMs, default maximum of 6 data volumes):
vm.iso.max.count3ISO 1,4(empty)3,41,2,5,6,7,83ISO 1,4ISO 23,41,2,5,6,7,83ISO 1,4config drive3,4,51,2,6,7,8,93ISO 1,4config drive,5ISO 23,4,51,2,6,7,8,9Libvirt targets of the last row: BIOS (IDE) Instance: ISO 1
hdc, config drivehdd, ISO 2sdf; UEFI Instance with SCSI disks: ISO 1sdd, config drivesde, ISO 2sdf, data volumessdb,sdc,sdg,sdh, ...For a host which does not advertise the number of CD-ROMs (older agents, other hypervisors): one ISO CD-ROM (
3), and the config drive ISO (4) if the Instance uses config drive.Changes
VolumeApiService.getReservedDeviceIds(vm)returns the device ids reserved for the CD-ROMs (including the config drive ISO). 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)getReservedDeviceIds(vm, true)).TemplateManager.getVmCdromCount(vm)returns the number of CD-ROM devices of an Instance (including the config drive ISO).TemplateManagerImplconverts the stored ISO slots to device ids (getIsoDeviceSeq) when defining the CD-ROMs at boot (prepareIsoForVmProfile) and when attaching or detaching an ISO.Notes
vm.iso.max.countwas at least 2 when it was started (the CD-ROM has to exist in the domain). Otherwise the Instance has to be restarted.listVirtualMachinesdoes not take the config drive ISO into account (it is not counted invm.iso.max.countanyway).kvm.guest.os.machine.type(withoutUEFI) still puts the CD-ROMs on the IDE bus, which q35 does not support.Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
Screenshots (if appropriate):
How Has This Been Tested?
Unit tests (
TemplateManagerImplTest,VolumeApiServiceImplTest,ConfigDriveNetworkElementTest,KVMGuruTest,UnmanagedVMsManagerImplTest,LibvirtComputingResourceTest,LibvirtVMDefTest) cover the reserved device ids, the number of CD-ROMs, the config drive detection (from the network providers and from the location detail), the conversion of ISO slots to device ids, the device id allocation for attach volume, restore and import, and the SATA bus for the CD-ROMs beyond the IDE slots.Manually tested on a KVM host (management server and agent built from this branch, Ubuntu 24.04 template, L2 networks with and without config drive,
vm.iso.max.count1 and 2):deviceid3/4 rejectedhdc, config drivehdd, ISO 2sdf, data volumes 1, 2, 6; detaching ISO 2 does not touch the config drive; the ISOs are kept after a stop/start; adding a NIC re-attaches the config driveHow did you try to break this feature and the system with this change?
vm.iso.max.countset to 2, including raising it while the Instance is running