Skip to content

Commit 3d7ab65

Browse files
committed
kvm: bind virtio-blk disks to an iothread, and let running SCSI disks win on attach
A disk with iothreads enabled got its iothread= binding only when its bus was VIRTIO, although a virtio-blk disk is rendered with the same libvirt bus. A virtio-blk VM with the iothreads detail therefore ran every disk with io='threads' but no iothread, and data disks following a virtio-blk root now lost it as well. Treat VIRTIOBLK like VIRTIO there. When a data disk is attached without a controller of its own, the virtio-blk root fallback ran before the scan of the running domain. The root detail can be changed on a running VM, so a VM started on SCSI whose detail was later set to virtio-blk would get a virtio disk hot-plugged next to its sd* ones. Scan the running disks first and use the fallback only when no SCSI disk is there.
1 parent 430ecf0 commit 3d7ab65

4 files changed

Lines changed: 31 additions & 10 deletions

File tree

‎plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,7 @@ public String toString() {
12031203
diskBuilder.append(String.format("io='%s' ", ioDriver));
12041204
}
12051205

1206-
if (isIothreadsEnabled && _bus == DiskBus.VIRTIO) {
1206+
if (isIothreadsEnabled && (_bus == DiskBus.VIRTIO || _bus == DiskBus.VIRTIOBLK)) {
12071207
diskBuilder.append(String.format("iothread='%s' ", NUMBER_OF_IOTHREADS));
12081208
}
12091209
diskBuilder.append("/>\n");

‎plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java‎

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,15 +1538,6 @@ protected DiskDef.DiskBus getAttachDiskBusType(int deviceId, List<DiskDef> disks
15381538
diskController, controllerKey, deviceId);
15391539
return busType;
15401540
}
1541-
if (deviceId != 0 && DiskDef.DiskBus.VIRTIOBLK == DiskDef.DiskBus.fromValue(
1542-
MapUtils.getString(controllerInfo, VmDetailConstants.ROOT_DISK_CONTROLLER))) {
1543-
// A data disk with no controller of its own follows the root, as it already does when the
1544-
// VM starts. The scan below cannot help here: a virtio-blk disk is rendered with libvirt's
1545-
// 'virtio' bus, so it is indistinguishable from a plain virtio disk in the domain XML, and
1546-
// the disk would silently lose discard until the next stop/start.
1547-
logger.debug("Attaching disk (deviceId={}) with the root controller virtio-blk", deviceId);
1548-
return DiskDef.DiskBus.VIRTIOBLK;
1549-
}
15501541
for (final DiskDef disk : disks) {
15511542
if (disk.getDeviceType() != DeviceType.DISK) {
15521543
continue;
@@ -1557,6 +1548,17 @@ protected DiskDef.DiskBus getAttachDiskBusType(int deviceId, List<DiskDef> disks
15571548
return DiskDef.DiskBus.VIRTIOBLK;
15581549
}
15591550
}
1551+
if (deviceId != 0 && DiskDef.DiskBus.VIRTIOBLK == DiskDef.DiskBus.fromValue(
1552+
MapUtils.getString(controllerInfo, VmDetailConstants.ROOT_DISK_CONTROLLER))) {
1553+
// A data disk with no controller of its own follows the root, as it already does when the
1554+
// VM starts. The scan above cannot see this case: a virtio-blk disk is rendered with
1555+
// libvirt's 'virtio' bus, so it is indistinguishable from a plain virtio disk in the domain
1556+
// XML, and the disk would silently lose discard until the next stop/start. The scan still
1557+
// wins when the running VM is on SCSI, so a detail changed after the VM started cannot
1558+
// put a virtio disk next to its SCSI ones.
1559+
logger.debug("Attaching disk (deviceId={}) with the root controller virtio-blk", deviceId);
1560+
return DiskDef.DiskBus.VIRTIOBLK;
1561+
}
15601562
return DiskDef.DiskBus.VIRTIO;
15611563
}
15621564

‎plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,4 +642,14 @@ public void testDiskDefScsiIsUnchanged() {
642642
String xmlDef = disk.toString();
643643
assertTrue(xmlDef, xmlDef.contains("<target dev='sda' bus='scsi'/>"));
644644
}
645+
646+
@Test
647+
public void testDiskDefVirtioBlkGetsAnIothreadLikeVirtio() {
648+
DiskDef disk = new DiskDef();
649+
disk.defFileBasedDisk("/var/lib/libvirt/images/disk.qcow2", 0, DiskDef.DiskBus.VIRTIOBLK, DiskDef.DiskFmtType.QCOW2);
650+
disk.isIothreadsEnabled(true);
651+
652+
String xmlDef = disk.toString();
653+
assertTrue(xmlDef, xmlDef.contains("iothread="));
654+
}
645655
}

‎plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessorTest.java‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,4 +523,13 @@ public void getAttachDiskBusTypeStillDetectsScsiFromTheRunningDisks() {
523523
Assert.assertEquals(LibvirtVMDef.DiskDef.DiskBus.SCSI,
524524
storageProcessor.getAttachDiskBusType(1, List.of(diskWithBus(LibvirtVMDef.DiskDef.DiskBus.SCSI)), Map.of()));
525525
}
526+
527+
@Test
528+
public void getAttachDiskBusTypePrefersTheRunningScsiDisksOverAVirtioBlkRootDetail() {
529+
// the detail can be changed on a running VM; the disks it actually runs on win, so a SCSI VM
530+
// does not get a virtio disk hot-plugged next to its sd* ones
531+
Map<String, String> controllerInfo = Map.of(VmDetailConstants.ROOT_DISK_CONTROLLER, "virtio-blk");
532+
Assert.assertEquals(LibvirtVMDef.DiskDef.DiskBus.SCSI,
533+
storageProcessor.getAttachDiskBusType(1, List.of(diskWithBus(LibvirtVMDef.DiskDef.DiskBus.SCSI)), controllerInfo));
534+
}
526535
}

0 commit comments

Comments
 (0)