From d55ff29eea9bf959e67d5d99964f24dfa372207a Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Mon, 22 Aug 2022 14:42:09 -0400 Subject: [PATCH] io_uring: add IORING_OP_URING_CMD test support This commit adds a basic test for the io_uring command passthrough functionality. Signed-off-by: Paul Moore --- tests/io_uring/iouring.c | 77 ++++++++++++++++++++++++++++++++++++++-- tests/io_uring/test | 10 ++++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/tests/io_uring/iouring.c b/tests/io_uring/iouring.c index be22811..0ed8d76 100644 --- a/tests/io_uring/iouring.c +++ b/tests/io_uring/iouring.c @@ -68,6 +68,10 @@ #include +#ifndef IORING_OP_URING_CMD +#define IORING_OP_URING_CMD 46 +#endif + struct urt_config { struct io_uring ring; struct io_uring_params ring_params; @@ -451,6 +455,50 @@ int uring_op_a(struct io_uring *ring, int personality, const char *path) return 0; } +/** + * An io_uring test + * @param ring the io_uring pointer + * + * This function executes an io_uring test, see the function body for more + * details. Returns 0 on success, negative values on failure. + */ +int uring_op_b(struct io_uring *ring) +{ + int rc; + int fd; + struct io_uring_sqe *sqe; + struct io_uring_cqe *cqe; + + fd = open("/dev/null", O_RDWR); + if (fd < 0) + fatal("open(/dev/null) failed"); + + /* + * command + */ + + sqe = io_uring_get_sqe(ring); + if (!sqe) + fatal("io_uring_get_sqe(cmd)"); + sqe->opcode = IORING_OP_URING_CMD; + sqe->fd = fd; + + rc = io_uring_submit(ring); + if (rc < 0) + fatal("io_uring_submit(cmd)"); + + rc = io_uring_wait_cqe(ring, &cqe); + if (rc < 0) + fatal("io_uring_wait_cqe(cmd)"); + if (cqe->res) + fatal("IORING_OP_URING_CMD"); + io_uring_cqe_seen(ring, cqe); + + printf(">>> io_uring cmd(): OK\n"); + + return 0; +} + /** * The main entrypoint to the test program * @param argc number of command line options @@ -465,7 +513,8 @@ int main(int argc, char *argv[]) enum { TST_UNKNOWN, TST_SQPOLL, - TST_T1_PARENT, TST_T1_CHILD + TST_T1_PARENT, TST_T1_CHILD, + TST_T2, } tst_method; /* parse the command line and do some sanity checks */ @@ -478,6 +527,8 @@ int main(int argc, char *argv[]) tst_method = TST_T1_PARENT; else if (!strcmp(argv[1], "t1_child")) tst_method = TST_T1_CHILD; + else if (!strcmp(argv[1], "t2")) + tst_method = TST_T2; } if (tst_method == TST_UNKNOWN) { fprintf(stderr, "usage: %s ... \n", argv[0]); @@ -487,11 +538,29 @@ int main(int argc, char *argv[]) /* simple header */ printf(">>> running as PID = %d\n", getpid()); printf(">>> LSM/SELinux = %s\n", selinux_current()); + printf(">>> test method = "); + switch (tst_method) { + case TST_SQPOLL: + printf("SQPOLL\n"); + break; + case TST_T1_PARENT: + printf("T1_PARENT\n"); + break; + case TST_T1_CHILD: + printf("T1_CHILD\n"); + break; + case TST_T2: + printf("T2\n"); + break; + default: + printf("UNKNOWN\n"); + } /* * test setup (if necessary) */ - if (tst_method == TST_SQPOLL || tst_method == TST_T1_PARENT) { + if (tst_method == TST_SQPOLL || tst_method == TST_T1_PARENT || + tst_method == TST_T2) { /* create an io_uring and prepare it for optional sharing */ int flags; @@ -584,6 +653,10 @@ int main(int argc, char *argv[]) rc = uring_op_a(ring, cfg_p->ring_creds, "/tmp/iouring.4.txt"); if (rc < 0) fatal("uring_op_a(\"/tmp/iouring.4.txt\")"); + } else if (tst_method == TST_T2) { + rc = uring_op_b(ring); + if (rc < 0) + fatal("uring_op_b()"); } /* diff --git a/tests/io_uring/test b/tests/io_uring/test index df13af0..84c6ef4 100755 --- a/tests/io_uring/test +++ b/tests/io_uring/test @@ -3,7 +3,7 @@ use strict; use Test; -BEGIN { plan tests => 5 } +BEGIN { plan tests => 6 } use File::Temp qw/ tempfile /; @@ -51,8 +51,9 @@ system("auditctl -a exit,always -F arch=b$abi_bits -S io_uring_setup -k $key"); system("auditctl -a exit,always -F arch=b$abi_bits -S io_uring_enter -k $key"); system("auditctl -a io_uring,always -S openat -k $key"); -# run the "t1" test +# run the io_uring tests system("$basedir/iouring t1"); +system("$basedir/iouring t2"); for ( my $i = 0 ; $i < 10 ; $i++ ) { if ( system("ausearch -k $key >& /dev/null") eq 0 ) { last; @@ -69,6 +70,7 @@ my $found_sc_setup = 0; my $found_sc_enter = 0; my $found_uop_open = 0; my $found_uop_close = 0; +my $found_uop_cmd = 0; # find the io_uring syscalls and io_uring ops while ( $line = <$fh_out> ) { @@ -84,11 +86,15 @@ while ( $line = <$fh_out> ) { if ( $line =~ /uring_op=19/ || $line =~ /uring_op=close/ ) { $found_uop_close = 1; } + if ( $line =~ /uring_op=46/ || $line =~ /uring_op=uring_cmd/ ) { + $found_uop_cmd = 1; + } } ok($found_sc_setup); ok($found_sc_enter); ok($found_uop_open); ok($found_uop_close); +ok($found_uop_cmd); ### # cleanup