From 924f33c192a99d7e9cae7e30778f3fbeb481c774 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Wed, 28 Feb 2024 16:57:49 -0700 Subject: [PATCH 1/2] Support KVM storage implementations controlling logical/physical block io size --- .../resource/LibvirtComputingResource.java | 10 +++++ .../hypervisor/kvm/resource/LibvirtVMDef.java | 29 +++++++++++++++ .../kvm/storage/KVMStoragePool.java | 9 +++++ .../kvm/resource/LibvirtVMDefTest.java | 37 +++++++++++++++++++ 4 files changed, 85 insertions(+) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 0a253878dafa..7ba75d654662 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -3058,6 +3058,13 @@ public int compare(final DiskTO arg0, final DiskTO arg1) { disk.setBusType(DiskDef.DiskBus.SCSI); } } else { + if (pool == null) { + throw new CloudRuntimeException(String.format("Found null pool for volume %s", volume)); + } + + disk.setLogicalBlockIOSize(pool.getSupportedLogicalBlockSize()); + disk.setPhysicalBlockIOSize(pool.getSupportedPhysicalBlockSize()); + if (diskBusType == DiskDef.DiskBus.SCSI ) { disk.setQemuDriver(true); disk.setDiscard(DiscardType.UNMAP); @@ -3486,6 +3493,9 @@ public synchronized String attachOrDetachDisk(final Connect conn, if (cacheMode != null) { diskdef.setCacheMode(DiskDef.DiskCacheMode.valueOf(cacheMode.toUpperCase())); } + + diskdef.setPhysicalBlockIOSize(attachingPool.getSupportedPhysicalBlockSize()); + diskdef.setLogicalBlockIOSize(attachingPool.getSupportedLogicalBlockSize()); } final String xml = diskdef.toString(); diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 09071ed6cdbe..5e0c90442282 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -700,6 +700,18 @@ public String toString() { } + public enum BlockIOSize { + SIZE_512("512"), SIZE_4K("4096"); + final String blockSize; + + BlockIOSize(String size) { this.blockSize = size; } + + @Override + public String toString() { + return blockSize; + } + } + private DeviceType _deviceType; /* floppy, disk, cdrom */ private DiskType _diskType; private DiskProtocol _diskProtocol; @@ -733,6 +745,8 @@ public String toString() { private IoDriverPolicy ioDriver; private LibvirtDiskEncryptDetails encryptDetails; private boolean isIothreadsEnabled; + private BlockIOSize logicalBlockIOSize = null; + private BlockIOSize physicalBlockIOSize = null; public DiscardType getDiscard() { return _discard; @@ -758,6 +772,10 @@ public void isIothreadsEnabled(boolean isIothreadsEnabled) { this.isIothreadsEnabled = isIothreadsEnabled; } + public void setPhysicalBlockIOSize(BlockIOSize size) { this.physicalBlockIOSize = size; } + + public void setLogicalBlockIOSize(BlockIOSize size) { this.logicalBlockIOSize = size; } + public void defFileBasedDisk(String filePath, String diskLabel, DiskBus bus, DiskFmtType diskFmtType) { _diskType = DiskType.FILE; _deviceType = DeviceType.DISK; @@ -1156,6 +1174,17 @@ public String toString() { } diskBuilder.append("/>\n"); + if (logicalBlockIOSize != null || physicalBlockIOSize != null) { + diskBuilder.append("\n"); + } + if (_serial != null && !_serial.isEmpty() && _deviceType != DeviceType.LUN) { diskBuilder.append("" + _serial + "\n"); } diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java index 43a09ccf2bf9..43547e7c7d1b 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java @@ -21,6 +21,7 @@ import com.cloud.agent.properties.AgentProperties; import com.cloud.agent.properties.AgentPropertiesFileHandler; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.joda.time.Duration; @@ -99,4 +100,12 @@ public interface KVMStoragePool { public Boolean checkingHeartBeat(HAStoragePool pool, HostTO host); public Boolean vmActivityCheck(HAStoragePool pool, HostTO host, Duration activityScriptTimeout, String volumeUUIDListString, String vmActivityCheckPath, long duration); + + default LibvirtVMDef.DiskDef.BlockIOSize getSupportedLogicalBlockSize() { + return null; + } + + default LibvirtVMDef.DiskDef.BlockIOSize getSupportedPhysicalBlockSize() { + return null; + } } diff --git a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java index 5bc251673552..3e1df81713cc 100644 --- a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java +++ b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java @@ -280,6 +280,43 @@ public void testDiskDefWithEncryption() { assertEquals(expectedXML, disk.toString()); } + @Test + public void testDiskDefWithBlockIO() { + String filePath = "/var/lib/libvirt/images/disk.qcow2"; + String diskLabel = "vda"; + + DiskDef disk = new DiskDef(); + DiskDef.DiskBus bus = DiskDef.DiskBus.VIRTIO; + DiskDef.DiskFmtType type = DiskDef.DiskFmtType.QCOW2; + DiskDef.DiskCacheMode cacheMode = DiskDef.DiskCacheMode.WRITEBACK; + + disk.defFileBasedDisk(filePath, diskLabel, bus, type); + disk.setCacheMode(cacheMode); + disk.setLogicalBlockIOSize(DiskDef.BlockIOSize.SIZE_4K); + + assertEquals(filePath, disk.getDiskPath()); + assertEquals(diskLabel, disk.getDiskLabel()); + assertEquals(bus, disk.getBusType()); + assertEquals(DiskDef.DeviceType.DISK, disk.getDeviceType()); + + String expectedXmlLogical = "\n\n" + + "\n\n\n\n"; + + assertEquals(expectedXmlLogical, disk.toString()); + + String expectedXmlPhysical = "\n\n" + + "\n\n\n\n"; + + disk.setLogicalBlockIOSize(null); + disk.setPhysicalBlockIOSize(DiskDef.BlockIOSize.SIZE_4K); + assertEquals(expectedXmlPhysical, disk.toString()); + + disk.setLogicalBlockIOSize(DiskDef.BlockIOSize.SIZE_512); + String expectedXml = "\n\n" + + "\n\n\n\n"; + assertEquals(expectedXml, disk.toString()); + } + @Test public void testDiskDefWithMultipleHosts() { String path = "/mnt/primary1"; From 229bb47e8c0bae56d26880bedd584d37f0101aa4 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Wed, 28 Feb 2024 21:33:03 -0700 Subject: [PATCH 2/2] Support custom block size during disk attach --- .../com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index c7261f30e8ae..ce52c47119d4 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -1482,6 +1482,8 @@ protected synchronized void attachOrDetachDisk(final Connect conn, final boolean if (ioDriver != null) { resource.setDiskIoDriver(diskdef, resource.getIoDriverForTheStorage(ioDriver.toUpperCase())); } + diskdef.setPhysicalBlockIOSize(attachingPool.getSupportedPhysicalBlockSize()); + diskdef.setLogicalBlockIOSize(attachingPool.getSupportedLogicalBlockSize()); } attachOrDetachDevice(conn, attach, vmName, diskdef, waitDetachDevice);