Skip to content

Commit 9f219bb

Browse files
nvazquezrohityadavcloud
authored andcommitted
[KVM] Enable IOURING only when it is available on the host (apache#6399)
* [KVM] Disable IOURING by default on agents * Refactor * Remove agent property for iouring * Restore property * Refactor suse check and enable on ubuntu by default * Refactor irrespective of guest OS * Improvement * Logs and new path * Refactor condition to enable iouring * Improve condition * Refactor property check * Improvement * Doc comment * Extend comment * Move method * Add log (cherry picked from commit dc975df) Signed-off-by: Rohit Yadav <[email protected]>
1 parent 3e41aca commit 9f219bb

File tree

3 files changed

+71
-12
lines changed

3 files changed

+71
-12
lines changed

agent/conf/agent.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,5 +286,5 @@ iscsi.session.cleanup.enabled=false
286286
# Enable manually setting CPU's topology on KVM's VM.
287287
# enable.manually.setting.cpu.topology.on.kvm.vm=true
288288

289-
# Enable/disable IO driver for Qemu / It's enabled by default on KVM agents
289+
# Enable/disable IO driver for Qemu (in case it is not set CloudStack can also detect if its supported by qemu)
290290
# enable.io.uring=true

agent/src/main/java/com/cloud/agent/properties/AgentProperties.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,6 @@ public class AgentProperties{
5454
*/
5555
public static final Property<Boolean> ENABLE_MANUALLY_SETTING_CPU_TOPOLOGY_ON_KVM_VM = new Property<Boolean>("enable.manually.setting.cpu.topology.on.kvm.vm", true);
5656

57-
/**
58-
* Enable manually IO driver on KVM's VM. <br>
59-
* Data type: boolean.<br>
60-
* Default value: true.
61-
*/
62-
public static final Property<Boolean> ENABLE_IO_URING = new Property<Boolean>("enable.io.uring", true);
63-
6457
public static class Property <T>{
6558
private final String name;
6659
private final T defaultValue;

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

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
313313

314314
public final static String HOST_CACHE_PATH_PARAMETER = "host.cache.location";
315315
public final static String CONFIG_DIR = "config";
316+
private boolean enableIoUring;
317+
private final static String ENABLE_IO_URING_PROPERTY = "enable.io.uring";
316318

317319
public static final String BASH_SCRIPT_PATH = "/bin/bash";
318320

@@ -1132,6 +1134,12 @@ public boolean configure(final String name, final Map<String, Object> params) th
11321134
s_logger.trace("Ignoring libvirt error.", e);
11331135
}
11341136

1137+
// Enable/disable IO driver for Qemu (in case it is not set CloudStack can also detect if its supported by qemu)
1138+
// Do not remove - switching it to AgentProperties.Property may require accepting null values for the properties default value
1139+
String enableIoUringConfig = (String) params.get(ENABLE_IO_URING_PROPERTY);
1140+
enableIoUring = isIoUringEnabled(enableIoUringConfig);
1141+
s_logger.info("IO uring driver for Qemu: " + (enableIoUring ? "enabled" : "disabled"));
1142+
11351143
final String cpuArchOverride = (String)params.get("guest.cpu.arch");
11361144
if (!Strings.isNullOrEmpty(cpuArchOverride)) {
11371145
_guestCpuArch = cpuArchOverride;
@@ -2949,20 +2957,68 @@ private KVMPhysicalDisk getPhysicalDiskPrimaryStore(PrimaryDataStoreTO primaryDa
29492957
return storagePool.getPhysicalDisk(data.getPath());
29502958
}
29512959

2960+
/**
2961+
* Check if IO_URING is supported by qemu
2962+
*/
2963+
protected boolean isIoUringSupportedByQemu() {
2964+
s_logger.debug("Checking if iouring is supported");
2965+
String command = getIoUringCheckCommand();
2966+
if (org.apache.commons.lang3.StringUtils.isBlank(command)) {
2967+
s_logger.debug("Could not check iouring support, disabling it");
2968+
return false;
2969+
}
2970+
int exitValue = executeBashScriptAndRetrieveExitValue(command);
2971+
return exitValue == 0;
2972+
}
2973+
2974+
protected String getIoUringCheckCommand() {
2975+
String[] qemuPaths = { "/usr/bin/qemu-system-x86_64", "/usr/libexec/qemu-kvm", "/usr/bin/qemu-kvm" };
2976+
for (String qemuPath : qemuPaths) {
2977+
File file = new File(qemuPath);
2978+
if (file.exists()) {
2979+
String cmd = String.format("ldd %s | grep -Eqe '[[:space:]]liburing\\.so'", qemuPath);
2980+
s_logger.debug("Using the check command: " + cmd);
2981+
return cmd;
2982+
}
2983+
}
2984+
return null;
2985+
}
2986+
29522987
/**
29532988
* Set Disk IO Driver, if supported by the Libvirt/Qemu version.
29542989
* IO Driver works for:
29552990
* (i) Qemu >= 5.0;
29562991
* (ii) Libvirt >= 6.3.0
29572992
*/
29582993
protected void setDiskIoDriver(DiskDef disk) {
2959-
if (getHypervisorLibvirtVersion() >= HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IO_URING
2960-
&& getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_SUPPORTS_IO_URING
2961-
&& AgentPropertiesFileHandler.getPropertyValue(AgentProperties.ENABLE_IO_URING)) {
2994+
if (enableIoUring) {
29622995
disk.setIoDriver(DiskDef.IoDriver.IOURING);
29632996
}
29642997
}
29652998

2999+
/**
3000+
* IO_URING supported if the property 'enable.io.uring' is set to true OR it is supported by qemu
3001+
*/
3002+
private boolean isIoUringEnabled(String enableIoUringConfig) {
3003+
boolean meetRequirements = getHypervisorLibvirtVersion() >= HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IO_URING
3004+
&& getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_SUPPORTS_IO_URING;
3005+
if (!meetRequirements) {
3006+
return false;
3007+
}
3008+
return enableIoUringConfig != null ?
3009+
Boolean.parseBoolean(enableIoUringConfig):
3010+
(isBaseOsUbuntu() || isIoUringSupportedByQemu());
3011+
}
3012+
3013+
private boolean isBaseOsUbuntu() {
3014+
Map<String, String> versionString = getVersionStrings();
3015+
String hostKey = "Host.OS";
3016+
if (MapUtils.isEmpty(versionString) || !versionString.containsKey(hostKey) || versionString.get(hostKey) == null) {
3017+
return false;
3018+
}
3019+
return versionString.get(hostKey).equalsIgnoreCase("ubuntu");
3020+
}
3021+
29663022
private KVMPhysicalDisk getPhysicalDiskFromNfsStore(String dataStoreUrl, DataTO data) {
29673023
final String volPath = dataStoreUrl + File.separator + data.getPath();
29683024
final int index = volPath.lastIndexOf("/");
@@ -3826,10 +3882,20 @@ public List<DiskDef> getDisks(final Connect conn, final String vmName) {
38263882
}
38273883

38283884
private String executeBashScript(final String script) {
3885+
return createScript(script).execute();
3886+
}
3887+
3888+
private Script createScript(final String script) {
38293889
final Script command = new Script("/bin/bash", _timeout, s_logger);
38303890
command.add("-c");
38313891
command.add(script);
3832-
return command.execute();
3892+
return command;
3893+
}
3894+
3895+
private int executeBashScriptAndRetrieveExitValue(final String script) {
3896+
Script command = createScript(script);
3897+
command.execute();
3898+
return command.getExitValue();
38333899
}
38343900

38353901
public List<VmNetworkStatsEntry> getVmNetworkStat(Connect conn, String vmName) throws LibvirtException {

0 commit comments

Comments
 (0)