Skip to content

Commit 92bfb4d

Browse files
Marcus SorensenMarcus Sorensen
andauthored
Support KVM storage implementations controlling logical/physical block io size (#8724)
* Support KVM storage implementations controlling logical/physical block io size * Support custom block size during disk attach --------- Co-authored-by: Marcus Sorensen <[email protected]>
1 parent db564b1 commit 92bfb4d

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3058,6 +3058,13 @@ public int compare(final DiskTO arg0, final DiskTO arg1) {
30583058
disk.setBusType(DiskDef.DiskBus.SCSI);
30593059
}
30603060
} else {
3061+
if (pool == null) {
3062+
throw new CloudRuntimeException(String.format("Found null pool for volume %s", volume));
3063+
}
3064+
3065+
disk.setLogicalBlockIOSize(pool.getSupportedLogicalBlockSize());
3066+
disk.setPhysicalBlockIOSize(pool.getSupportedPhysicalBlockSize());
3067+
30613068
if (diskBusType == DiskDef.DiskBus.SCSI ) {
30623069
disk.setQemuDriver(true);
30633070
disk.setDiscard(DiscardType.UNMAP);
@@ -3486,6 +3493,9 @@ public synchronized String attachOrDetachDisk(final Connect conn,
34863493
if (cacheMode != null) {
34873494
diskdef.setCacheMode(DiskDef.DiskCacheMode.valueOf(cacheMode.toUpperCase()));
34883495
}
3496+
3497+
diskdef.setPhysicalBlockIOSize(attachingPool.getSupportedPhysicalBlockSize());
3498+
diskdef.setLogicalBlockIOSize(attachingPool.getSupportedLogicalBlockSize());
34893499
}
34903500

34913501
final String xml = diskdef.toString();

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,18 @@ public String toString() {
700700

701701
}
702702

703+
public enum BlockIOSize {
704+
SIZE_512("512"), SIZE_4K("4096");
705+
final String blockSize;
706+
707+
BlockIOSize(String size) { this.blockSize = size; }
708+
709+
@Override
710+
public String toString() {
711+
return blockSize;
712+
}
713+
}
714+
703715
private DeviceType _deviceType; /* floppy, disk, cdrom */
704716
private DiskType _diskType;
705717
private DiskProtocol _diskProtocol;
@@ -733,6 +745,8 @@ public String toString() {
733745
private IoDriverPolicy ioDriver;
734746
private LibvirtDiskEncryptDetails encryptDetails;
735747
private boolean isIothreadsEnabled;
748+
private BlockIOSize logicalBlockIOSize = null;
749+
private BlockIOSize physicalBlockIOSize = null;
736750

737751
public DiscardType getDiscard() {
738752
return _discard;
@@ -758,6 +772,10 @@ public void isIothreadsEnabled(boolean isIothreadsEnabled) {
758772
this.isIothreadsEnabled = isIothreadsEnabled;
759773
}
760774

775+
public void setPhysicalBlockIOSize(BlockIOSize size) { this.physicalBlockIOSize = size; }
776+
777+
public void setLogicalBlockIOSize(BlockIOSize size) { this.logicalBlockIOSize = size; }
778+
761779
public void defFileBasedDisk(String filePath, String diskLabel, DiskBus bus, DiskFmtType diskFmtType) {
762780
_diskType = DiskType.FILE;
763781
_deviceType = DeviceType.DISK;
@@ -1156,6 +1174,17 @@ public String toString() {
11561174
}
11571175
diskBuilder.append("/>\n");
11581176

1177+
if (logicalBlockIOSize != null || physicalBlockIOSize != null) {
1178+
diskBuilder.append("<blockio ");
1179+
if (logicalBlockIOSize != null) {
1180+
diskBuilder.append(String.format("logical_block_size='%s' ", logicalBlockIOSize));
1181+
}
1182+
if (physicalBlockIOSize != null) {
1183+
diskBuilder.append(String.format("physical_block_size='%s' ", physicalBlockIOSize));
1184+
}
1185+
diskBuilder.append("/>\n");
1186+
}
1187+
11591188
if (_serial != null && !_serial.isEmpty() && _deviceType != DeviceType.LUN) {
11601189
diskBuilder.append("<serial>" + _serial + "</serial>\n");
11611190
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import com.cloud.agent.properties.AgentProperties;
2323
import com.cloud.agent.properties.AgentPropertiesFileHandler;
24+
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef;
2425
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
2526
import org.joda.time.Duration;
2627

@@ -99,4 +100,12 @@ public interface KVMStoragePool {
99100
public Boolean checkingHeartBeat(HAStoragePool pool, HostTO host);
100101

101102
public Boolean vmActivityCheck(HAStoragePool pool, HostTO host, Duration activityScriptTimeout, String volumeUUIDListString, String vmActivityCheckPath, long duration);
103+
104+
default LibvirtVMDef.DiskDef.BlockIOSize getSupportedLogicalBlockSize() {
105+
return null;
106+
}
107+
108+
default LibvirtVMDef.DiskDef.BlockIOSize getSupportedPhysicalBlockSize() {
109+
return null;
110+
}
102111
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,8 @@ protected synchronized void attachOrDetachDisk(final Connect conn, final boolean
14821482
if (ioDriver != null) {
14831483
resource.setDiskIoDriver(diskdef, resource.getIoDriverForTheStorage(ioDriver.toUpperCase()));
14841484
}
1485+
diskdef.setPhysicalBlockIOSize(attachingPool.getSupportedPhysicalBlockSize());
1486+
diskdef.setLogicalBlockIOSize(attachingPool.getSupportedLogicalBlockSize());
14851487
}
14861488

14871489
attachOrDetachDevice(conn, attach, vmName, diskdef, waitDetachDevice);

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,43 @@ public void testDiskDefWithEncryption() {
280280
assertEquals(expectedXML, disk.toString());
281281
}
282282

283+
@Test
284+
public void testDiskDefWithBlockIO() {
285+
String filePath = "/var/lib/libvirt/images/disk.qcow2";
286+
String diskLabel = "vda";
287+
288+
DiskDef disk = new DiskDef();
289+
DiskDef.DiskBus bus = DiskDef.DiskBus.VIRTIO;
290+
DiskDef.DiskFmtType type = DiskDef.DiskFmtType.QCOW2;
291+
DiskDef.DiskCacheMode cacheMode = DiskDef.DiskCacheMode.WRITEBACK;
292+
293+
disk.defFileBasedDisk(filePath, diskLabel, bus, type);
294+
disk.setCacheMode(cacheMode);
295+
disk.setLogicalBlockIOSize(DiskDef.BlockIOSize.SIZE_4K);
296+
297+
assertEquals(filePath, disk.getDiskPath());
298+
assertEquals(diskLabel, disk.getDiskLabel());
299+
assertEquals(bus, disk.getBusType());
300+
assertEquals(DiskDef.DeviceType.DISK, disk.getDeviceType());
301+
302+
String expectedXmlLogical = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" +
303+
"<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n<blockio logical_block_size='4096' />\n</disk>\n";
304+
305+
assertEquals(expectedXmlLogical, disk.toString());
306+
307+
String expectedXmlPhysical = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" +
308+
"<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n<blockio physical_block_size='4096' />\n</disk>\n";
309+
310+
disk.setLogicalBlockIOSize(null);
311+
disk.setPhysicalBlockIOSize(DiskDef.BlockIOSize.SIZE_4K);
312+
assertEquals(expectedXmlPhysical, disk.toString());
313+
314+
disk.setLogicalBlockIOSize(DiskDef.BlockIOSize.SIZE_512);
315+
String expectedXml = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" +
316+
"<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n<blockio logical_block_size='512' physical_block_size='4096' />\n</disk>\n";
317+
assertEquals(expectedXml, disk.toString());
318+
}
319+
283320
@Test
284321
public void testDiskDefWithMultipleHosts() {
285322
String path = "/mnt/primary1";

0 commit comments

Comments
 (0)