@@ -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