@@ -313,6 +313,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
313
313
314
314
public final static String HOST_CACHE_PATH_PARAMETER = "host.cache.location" ;
315
315
public final static String CONFIG_DIR = "config" ;
316
+ private boolean enableIoUring ;
317
+ private final static String ENABLE_IO_URING_PROPERTY = "enable.io.uring" ;
316
318
317
319
public static final String BASH_SCRIPT_PATH = "/bin/bash" ;
318
320
@@ -1132,6 +1134,12 @@ public boolean configure(final String name, final Map<String, Object> params) th
1132
1134
s_logger .trace ("Ignoring libvirt error." , e );
1133
1135
}
1134
1136
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
+
1135
1143
final String cpuArchOverride = (String )params .get ("guest.cpu.arch" );
1136
1144
if (!Strings .isNullOrEmpty (cpuArchOverride )) {
1137
1145
_guestCpuArch = cpuArchOverride ;
@@ -2949,20 +2957,68 @@ private KVMPhysicalDisk getPhysicalDiskPrimaryStore(PrimaryDataStoreTO primaryDa
2949
2957
return storagePool .getPhysicalDisk (data .getPath ());
2950
2958
}
2951
2959
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
+
2952
2987
/**
2953
2988
* Set Disk IO Driver, if supported by the Libvirt/Qemu version.
2954
2989
* IO Driver works for:
2955
2990
* (i) Qemu >= 5.0;
2956
2991
* (ii) Libvirt >= 6.3.0
2957
2992
*/
2958
2993
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 ) {
2962
2995
disk .setIoDriver (DiskDef .IoDriver .IOURING );
2963
2996
}
2964
2997
}
2965
2998
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
+
2966
3022
private KVMPhysicalDisk getPhysicalDiskFromNfsStore (String dataStoreUrl , DataTO data ) {
2967
3023
final String volPath = dataStoreUrl + File .separator + data .getPath ();
2968
3024
final int index = volPath .lastIndexOf ("/" );
@@ -3826,10 +3882,20 @@ public List<DiskDef> getDisks(final Connect conn, final String vmName) {
3826
3882
}
3827
3883
3828
3884
private String executeBashScript (final String script ) {
3885
+ return createScript (script ).execute ();
3886
+ }
3887
+
3888
+ private Script createScript (final String script ) {
3829
3889
final Script command = new Script ("/bin/bash" , _timeout , s_logger );
3830
3890
command .add ("-c" );
3831
3891
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 ();
3833
3899
}
3834
3900
3835
3901
public List <VmNetworkStatsEntry > getVmNetworkStat (Connect conn , String vmName ) throws LibvirtException {
0 commit comments