fstests: skip AIO-related tests when CONFIG_AIO=n
When running xfstests on a kernel configured with CONFIG_AIO=n, all
AIO-related tests fail, often due to an error similar to the
following:
error Function not implemented during io_setup
This affected at least the following tests: generic/036,
generic/112, generic/113, generic/198, generic/207, generic/208,
generic/210, generic/211, generic/239, generic/323, generic/427,
xfs/240, xfs/241.
Fix this by enhancing the 'feature' program to allow testing for
asynchronous I/O support, then skipping all AIO-related tests when
AIO is unsupported.
This change is useful because CONFIG_AIO is sometimes disabled to
reduce the kernel's attack surface (e.g. see
https://android-review.googlesource.com/#/c/292158/).
Signed-off-by: Eric Biggers <ebiggers@google.com>
Reviewed-by: Eryu Guan <eguan@redhat.com>
Signed-off-by: Eryu Guan <eguan@redhat.com>
diff --git a/common/rc b/common/rc
index a7af1f2..ba21596 100644
--- a/common/rc
+++ b/common/rc
@@ -1868,7 +1868,24 @@
_notrun "External device testing in progress, skipped this test"
}
+# this test requires that the kernel supports asynchronous I/O
+_require_aio()
+{
+ $here/src/feature -A
+ case $? in
+ 0)
+ ;;
+ 1)
+ _notrun "kernel does not support asynchronous I/O"
+ ;;
+ *)
+ _fail "unexpected error testing for asynchronous I/O support"
+ ;;
+ esac
+}
+
# this test requires that a (specified) aio-dio executable exists
+# and that the kernel supports asynchronous I/O.
# $1 - command (optional)
#
_require_aiodio()
@@ -1881,6 +1898,7 @@
AIO_TEST=src/aio-dio-regress/$1
[ -x $AIO_TEST ] || _notrun "$AIO_TEST not built"
fi
+ _require_aio
_require_odirect
}
diff --git a/src/Makefile b/src/Makefile
index b505b42..4724662 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -60,6 +60,7 @@
ifeq ($(HAVE_AIO), true)
SUBDIRS += aio-dio-regress
+LLDLIBS += -laio
endif
ifeq ($(HAVE_SSL), true)
diff --git a/src/feature.c b/src/feature.c
index 334063b..b735468 100644
--- a/src/feature.c
+++ b/src/feature.c
@@ -30,6 +30,7 @@
* Return code: 0 is true, anything else is error/not supported
*
* Test for machine features
+ * -A test whether AIO syscalls are available
* -o report a number of online cpus
* -s report pagesize
* -w report bits per long
@@ -46,6 +47,10 @@
#include <xfs/xqm.h>
#endif
+#ifdef HAVE_LIBAIO_H
+#include <libaio.h>
+#endif
+
#ifndef USRQUOTA
#define USRQUOTA 0
#endif
@@ -66,7 +71,7 @@
fprintf(stderr, "Usage: feature [-v] -<q|u|g|p|U|G|P> <filesystem>\n");
fprintf(stderr, " feature [-v] -c <file>\n");
fprintf(stderr, " feature [-v] -t <file>\n");
- fprintf(stderr, " feature -o | -s | -w\n");
+ fprintf(stderr, " feature -A | -o | -s | -w\n");
exit(1);
}
@@ -199,10 +204,35 @@
return (1);
}
+static int
+check_aio_support(void)
+{
+#ifdef HAVE_LIBAIO_H
+ struct io_context *ctx = NULL;
+ int err;
+
+ err = io_setup(1, &ctx);
+ if (err == 0)
+ return 0;
+
+ if (err == -ENOSYS) /* CONFIG_AIO=n */
+ return 1;
+
+ fprintf(stderr, "unexpected error from io_setup(): %s\n",
+ strerror(-err));
+ return 2;
+#else
+ /* libaio was unavailable at build time; assume AIO is unsupported */
+ return 1;
+#endif
+}
+
+
int
main(int argc, char **argv)
{
int c;
+ int Aflag = 0;
int cflag = 0;
int tflag = 0;
int gflag = 0;
@@ -217,8 +247,11 @@
int oflag = 0;
char *fs = NULL;
- while ((c = getopt(argc, argv, "ctgGopPqsuUvw")) != EOF) {
+ while ((c = getopt(argc, argv, "ActgGopPqsuUvw")) != EOF) {
switch (c) {
+ case 'A':
+ Aflag++;
+ break;
case 'c':
cflag++;
break;
@@ -268,7 +301,7 @@
if (optind != argc-1) /* need a device */
usage();
fs = argv[argc-1];
- } else if (wflag || sflag || oflag) {
+ } else if (Aflag || wflag || sflag || oflag) {
if (optind != argc)
usage();
} else
@@ -293,6 +326,9 @@
if (Uflag)
return(hasxfsquota(USRQUOTA, XFS_QUOTA_UDQ_ACCT, fs));
+ if (Aflag)
+ return(check_aio_support());
+
if (sflag) {
printf("%d\n", getpagesize());
exit(0);
diff --git a/tests/generic/112 b/tests/generic/112
index 55be394..0ab1c8c 100755
--- a/tests/generic/112
+++ b/tests/generic/112
@@ -122,6 +122,7 @@
_supported_fs generic
_supported_os Linux
_require_test
+_require_aio
[ -x $here/ltp/aio-stress ] || \
_notrun "fsx not built with AIO for this platform"
diff --git a/tests/generic/113 b/tests/generic/113
index 54d6191..7e20d68 100755
--- a/tests/generic/113
+++ b/tests/generic/113
@@ -77,6 +77,7 @@
_supported_fs generic
_supported_os Linux
_require_test
+_require_aio
_require_odirect
[ -x $here/ltp/aio-stress ] || _notrun "aio-stress not built for this platform"
diff --git a/tests/xfs/240 b/tests/xfs/240
index 62a7735..fa0edc7 100755
--- a/tests/xfs/240
+++ b/tests/xfs/240
@@ -49,9 +49,8 @@
_require_cp_reflink
_require_dm_target error
_require_xfs_io_command "cowextsize"
-_require_test_program "aio-dio-regress/aiocp"
+_require_aiodio "aiocp"
AIO_TEST="src/aio-dio-regress/aiocp"
-_require_odirect
rm -f $seqres.full
diff --git a/tests/xfs/241 b/tests/xfs/241
index 5b29f4d..b309673 100755
--- a/tests/xfs/241
+++ b/tests/xfs/241
@@ -46,9 +46,8 @@
_require_scratch_reflink
_require_cp_reflink
_require_xfs_io_command "cowextsize"
-_require_test_program "aio-dio-regress/aiocp"
+_require_aiodio "aiocp"
AIO_TEST="src/aio-dio-regress/aiocp"
-_require_odirect
rm -f $seqres.full