mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
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 <mls@apple.com>
This commit is contained in:
parent
db564b12b6
commit
92bfb4dcaa
@ -3058,6 +3058,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
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 class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
if (cacheMode != null) {
|
||||
diskdef.setCacheMode(DiskDef.DiskCacheMode.valueOf(cacheMode.toUpperCase()));
|
||||
}
|
||||
|
||||
diskdef.setPhysicalBlockIOSize(attachingPool.getSupportedPhysicalBlockSize());
|
||||
diskdef.setLogicalBlockIOSize(attachingPool.getSupportedLogicalBlockSize());
|
||||
}
|
||||
|
||||
final String xml = diskdef.toString();
|
||||
|
||||
@ -700,6 +700,18 @@ public class LibvirtVMDef {
|
||||
|
||||
}
|
||||
|
||||
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 class LibvirtVMDef {
|
||||
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 class LibvirtVMDef {
|
||||
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 class LibvirtVMDef {
|
||||
}
|
||||
diskBuilder.append("/>\n");
|
||||
|
||||
if (logicalBlockIOSize != null || physicalBlockIOSize != null) {
|
||||
diskBuilder.append("<blockio ");
|
||||
if (logicalBlockIOSize != null) {
|
||||
diskBuilder.append(String.format("logical_block_size='%s' ", logicalBlockIOSize));
|
||||
}
|
||||
if (physicalBlockIOSize != null) {
|
||||
diskBuilder.append(String.format("physical_block_size='%s' ", physicalBlockIOSize));
|
||||
}
|
||||
diskBuilder.append("/>\n");
|
||||
}
|
||||
|
||||
if (_serial != null && !_serial.isEmpty() && _deviceType != DeviceType.LUN) {
|
||||
diskBuilder.append("<serial>" + _serial + "</serial>\n");
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import java.util.Map;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1482,6 +1482,8 @@ public class KVMStorageProcessor implements StorageProcessor {
|
||||
if (ioDriver != null) {
|
||||
resource.setDiskIoDriver(diskdef, resource.getIoDriverForTheStorage(ioDriver.toUpperCase()));
|
||||
}
|
||||
diskdef.setPhysicalBlockIOSize(attachingPool.getSupportedPhysicalBlockSize());
|
||||
diskdef.setLogicalBlockIOSize(attachingPool.getSupportedLogicalBlockSize());
|
||||
}
|
||||
|
||||
attachOrDetachDevice(conn, attach, vmName, diskdef, waitDetachDevice);
|
||||
|
||||
@ -280,6 +280,43 @@ public class LibvirtVMDefTest extends TestCase {
|
||||
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 = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" +
|
||||
"<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n<blockio logical_block_size='4096' />\n</disk>\n";
|
||||
|
||||
assertEquals(expectedXmlLogical, disk.toString());
|
||||
|
||||
String expectedXmlPhysical = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" +
|
||||
"<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n<blockio physical_block_size='4096' />\n</disk>\n";
|
||||
|
||||
disk.setLogicalBlockIOSize(null);
|
||||
disk.setPhysicalBlockIOSize(DiskDef.BlockIOSize.SIZE_4K);
|
||||
assertEquals(expectedXmlPhysical, disk.toString());
|
||||
|
||||
disk.setLogicalBlockIOSize(DiskDef.BlockIOSize.SIZE_512);
|
||||
String expectedXml = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" +
|
||||
"<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n<blockio logical_block_size='512' physical_block_size='4096' />\n</disk>\n";
|
||||
assertEquals(expectedXml, disk.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiskDefWithMultipleHosts() {
|
||||
String path = "/mnt/primary1";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user