[PATCH] test_aio: Skip io_uring tests when kernel disables it

Started by Henson Choiabout 1 month ago2 messages
#1Henson Choi
assam258@gmail.com
1 attachment(s)

Hi hackers,

I encountered test_aio failures on RHEL 9 / Rocky Linux 9 systems where
io_uring is disabled by default (io_uring_disabled=2). This is increasingly
common in enterprise environments.

Background:
Red Hat disabled io_uring in 2021 and maintains this policy in RHEL 9
for security reasons. Many critical CVEs have been found (CVE-2021-41073,
CVE-2022-2602, CVE-2024-0582, etc.), and Google reported that 60% of their
2022 kernel exploit submissions targeted io_uring, leading them to disable
it across Android, ChromeOS, and production servers.

Current behavior:
The test_aio module only checks if PostgreSQL was compiled with io_uring
support (have_io_uring) but doesn't check if the kernel allows it.
This causes test failures on RHEL 9 and similar distributions.

Proposed solution:
Add io_uring_enabled() to check /proc/sys/kernel/io_uring_disabled.
Only run io_uring tests when the value is 0 (fully enabled).

Why skip io_uring_disabled=1 (CAP_SYS_ADMIN required) as well:
- Checking for CAP_SYS_ADMIN capability adds complexity
- Most test users don't have CAP_SYS_ADMIN
- High probability of failure, safer to skip
- Prioritize test simplicity and stability over coverage

Testing:
- ✓ RHEL 9 (io_uring_disabled=2): Tests skip correctly
- ✓ Ubuntu 24 (io_uring_disabled=0): Tests run normally

The patch is minimal (adds one function, modifies one condition) and
follows the existing pattern used for injection points testing.

Thoughts?

Best regards,
Henson Choi

Attachments:

0001-test_aio-Skip-io_uring-tests-when-kernel-disables-it.patchapplication/octet-stream; name=0001-test_aio-Skip-io_uring-tests-when-kernel-disables-it.patchDownload
From 77c0e188720213f1a99eb6dc4502a152f72500d8 Mon Sep 17 00:00:00 2001
From: HyunSu Choi <assam258@gmail.com>
Date: Mon, 8 Dec 2025 09:58:49 +0900
Subject: [PATCH] test_aio: Skip io_uring tests when kernel disables it

The test_aio module fails on systems where io_uring is disabled at
the kernel level, despite PostgreSQL being compiled with io_uring
support.  The existing have_io_uring() function only checks whether
PostgreSQL was compiled with io_uring support, but does not verify
that the kernel actually permits io_uring operations at runtime.

Many enterprise Linux distributions (e.g., RHEL 9) set
io_uring_disabled=2 by default due to security concerns.  When
io_uring is kernel-disabled, initdb fails with EPERM, causing test
bailouts.

Add io_uring_enabled() to check /proc/sys/kernel/io_uring_disabled.
Tests only run when the value is 0 (fully enabled).  We skip tests
for value 1 (requires CAP_SYS_ADMIN) as well, since checking for
that capability adds complexity and most test users lack it.  When
the sysctl file doesn't exist (kernels < 5.1), we treat it as
disabled via "|| echo 2", which is the safest approach.

The implementation follows the existing pattern for have_io_uring(),
using a simple conditional to skip the entire test block when the
feature is unavailable.  Diagnostic output is provided via note()
when tests are skipped.

This is a test-only change with no impact on server functionality.
---
 src/test/modules/test_aio/t/001_aio.pl | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/test/modules/test_aio/t/001_aio.pl b/src/test/modules/test_aio/t/001_aio.pl
index 3f0453619e8..9a4ff86e78f 100644
--- a/src/test/modules/test_aio/t/001_aio.pl
+++ b/src/test/modules/test_aio/t/001_aio.pl
@@ -29,7 +29,7 @@ $node_worker->stop();
 # Test io_method=io_uring
 ###
 
-if (have_io_uring())
+if (have_io_uring() and io_uring_enabled())
 {
 	my $node_uring = create_node('io_uring');
 	$node_uring->start();
@@ -128,6 +128,27 @@ sub have_io_uring
 	return ($methods =~ m/io_uring/) ? 1 : 0;
 }
 
+sub io_uring_enabled
+{
+	# Check if io_uring is disabled by the kernel
+	# 0 = enabled for all users
+	# 1 = disabled for unprivileged users (requires CAP_SYS_ADMIN)
+	# 2 = disabled for all users
+	# file not exists = very old kernel (< 5.1), treat as disabled
+
+	my $io_uring_disabled = `cat /proc/sys/kernel/io_uring_disabled 2>/dev/null || echo 2`;
+	chomp($io_uring_disabled);
+
+	# Only allow when fully enabled (value is 0)
+	if ($io_uring_disabled ne '0')
+	{
+		note "io_uring is restricted or disabled (io_uring_disabled=$io_uring_disabled)";
+		return 0;
+	}
+
+	return 1;
+}
+
 sub psql_like
 {
 	local $Test::Builder::Level = $Test::Builder::Level + 1;
-- 
2.34.1

#2Nazir Bilal Yavuz
byavuz81@gmail.com
In reply to: Henson Choi (#1)
Re: [PATCH] test_aio: Skip io_uring tests when kernel disables it

Hi,

On Mon, 8 Dec 2025 at 05:12, Henson Choi <assam258@gmail.com> wrote:

Hi hackers,

I encountered test_aio failures on RHEL 9 / Rocky Linux 9 systems where
io_uring is disabled by default (io_uring_disabled=2). This is increasingly
common in enterprise environments.

Background:
Red Hat disabled io_uring in 2021 and maintains this policy in RHEL 9
for security reasons. Many critical CVEs have been found (CVE-2021-41073,
CVE-2022-2602, CVE-2024-0582, etc.), and Google reported that 60% of their
2022 kernel exploit submissions targeted io_uring, leading them to disable
it across Android, ChromeOS, and production servers.

Current behavior:
The test_aio module only checks if PostgreSQL was compiled with io_uring
support (have_io_uring) but doesn't check if the kernel allows it.
This causes test failures on RHEL 9 and similar distributions.

Proposed solution:
Add io_uring_enabled() to check /proc/sys/kernel/io_uring_disabled.
Only run io_uring tests when the value is 0 (fully enabled).

Why skip io_uring_disabled=1 (CAP_SYS_ADMIN required) as well:
- Checking for CAP_SYS_ADMIN capability adds complexity
- Most test users don't have CAP_SYS_ADMIN
- High probability of failure, safer to skip
- Prioritize test simplicity and stability over coverage

Testing:
- ✓ RHEL 9 (io_uring_disabled=2): Tests skip correctly
- ✓ Ubuntu 24 (io_uring_disabled=0): Tests run normally

The patch is minimal (adds one function, modifies one condition) and
follows the existing pattern used for injection points testing.

Thoughts?

Thank you for the report! I am able to reproduce the problem you
mentioned by disabling io_uring with 'sysctl -w
kernel.io_uring_disabled=2' command.

method_io_uring.c has a hint about this problem:

/* add hints for some failures that errno explains sufficiently */
if (-ret == EPERM)
{
err = ERRCODE_INSUFFICIENT_PRIVILEGE;
hint = _("Check if io_uring is disabled via
/proc/sys/kernel/io_uring_disabled.");
}

and this hint is shown when you try to set the io_method to io_uring
also this hint is written to the 'regress_log_001_aio' if aio tests
fail because of that. I think it is correct to fail the test and show
the hint when you have an io_uring support but you can not use it
because of some kernel parameters.

--
Regards,
Nazir Bilal Yavuz
Microsoft