aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/liburing/test
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2023-07-26 17:26:21 +0300
committerthegeorg <thegeorg@yandex-team.com>2023-07-26 17:26:21 +0300
commit3785d5f97965bccf048718d8717904cf50f9f8f9 (patch)
treeb7ce8ae67d7eb7fcf7767c54379f0564c281147f /contrib/libs/liburing/test
parent1f6b57071583f89299bb5abd3863d594f23c5be5 (diff)
downloadydb-3785d5f97965bccf048718d8717904cf50f9f8f9.tar.gz
Update contrib/libs/liburing to 2.4
Diffstat (limited to 'contrib/libs/liburing/test')
-rw-r--r--contrib/libs/liburing/test/232c93d07b74.c6
-rw-r--r--contrib/libs/liburing/test/35fa71a030ca.c6
-rw-r--r--contrib/libs/liburing/test/500f9fbadef8.c2
-rw-r--r--contrib/libs/liburing/test/917257daa0fe.c2
-rw-r--r--contrib/libs/liburing/test/a0908ae19763.c4
-rw-r--r--contrib/libs/liburing/test/a4c0b3decb33.c4
-rw-r--r--contrib/libs/liburing/test/accept-link.c8
-rw-r--r--contrib/libs/liburing/test/accept-reuse.c12
-rw-r--r--contrib/libs/liburing/test/accept.c65
-rw-r--r--contrib/libs/liburing/test/b19062a56726.c2
-rw-r--r--contrib/libs/liburing/test/buf-ring.c158
-rw-r--r--contrib/libs/liburing/test/ce593a6c480a.c4
-rw-r--r--contrib/libs/liburing/test/close-opath.c3
-rw-r--r--contrib/libs/liburing/test/connect-rep.c205
-rw-r--r--contrib/libs/liburing/test/connect-rep.t/ya.make (renamed from contrib/libs/liburing/test/timeout-overflow.t/ya.make)2
-rw-r--r--contrib/libs/liburing/test/connect.c8
-rw-r--r--contrib/libs/liburing/test/cq-overflow.c22
-rw-r--r--contrib/libs/liburing/test/d4ae271dfaae.c2
-rw-r--r--contrib/libs/liburing/test/defer-taskrun.c73
-rw-r--r--contrib/libs/liburing/test/defer.c2
-rw-r--r--contrib/libs/liburing/test/double-poll-crash.c6
-rw-r--r--contrib/libs/liburing/test/eeed8b54e0df.c11
-rw-r--r--contrib/libs/liburing/test/eploop.c75
-rw-r--r--contrib/libs/liburing/test/eploop.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/eventfd-ring.c2
-rw-r--r--contrib/libs/liburing/test/eventfd.c2
-rw-r--r--contrib/libs/liburing/test/evloop.c74
-rw-r--r--contrib/libs/liburing/test/evloop.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/exit-no-cleanup.c2
-rw-r--r--contrib/libs/liburing/test/fadvise.c2
-rw-r--r--contrib/libs/liburing/test/fallocate.c9
-rw-r--r--contrib/libs/liburing/test/fc2a85cb02ef.c6
-rw-r--r--contrib/libs/liburing/test/fd-pass.c84
-rw-r--r--contrib/libs/liburing/test/file-register.c61
-rw-r--r--contrib/libs/liburing/test/file-verify.c37
-rw-r--r--contrib/libs/liburing/test/files-exit-hang-timeout.c4
-rw-r--r--contrib/libs/liburing/test/fixed-link.c2
-rw-r--r--contrib/libs/liburing/test/hardlink.c2
-rw-r--r--contrib/libs/liburing/test/helpers.c56
-rw-r--r--contrib/libs/liburing/test/helpers.h4
-rw-r--r--contrib/libs/liburing/test/io-cancel.c4
-rw-r--r--contrib/libs/liburing/test/io_uring_passthrough.c47
-rw-r--r--contrib/libs/liburing/test/io_uring_register.c2
-rw-r--r--contrib/libs/liburing/test/io_uring_setup.c83
-rw-r--r--contrib/libs/liburing/test/iopoll-overflow.c119
-rw-r--r--contrib/libs/liburing/test/iopoll-overflow.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/iopoll.c94
-rw-r--r--contrib/libs/liburing/test/lfs-openat-write.c16
-rw-r--r--contrib/libs/liburing/test/lfs-openat.c14
-rw-r--r--contrib/libs/liburing/test/link_drain.c36
-rw-r--r--contrib/libs/liburing/test/madvise.c2
-rw-r--r--contrib/libs/liburing/test/msg-ring-flags.c193
-rw-r--r--contrib/libs/liburing/test/msg-ring-flags.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/msg-ring-overflow.c160
-rw-r--r--contrib/libs/liburing/test/msg-ring-overflow.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/msg-ring.c186
-rw-r--r--contrib/libs/liburing/test/multicqes_drain.c41
-rw-r--r--contrib/libs/liburing/test/nvme.h7
-rw-r--r--contrib/libs/liburing/test/pipe-bug.c96
-rw-r--r--contrib/libs/liburing/test/pipe-bug.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/poll-link.c6
-rw-r--r--contrib/libs/liburing/test/poll-many.c60
-rw-r--r--contrib/libs/liburing/test/poll-mshot-overflow.c107
-rw-r--r--contrib/libs/liburing/test/poll-race-mshot.c277
-rw-r--r--contrib/libs/liburing/test/poll-race-mshot.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/poll-race.c106
-rw-r--r--contrib/libs/liburing/test/poll-race.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/poll.c270
-rw-r--r--contrib/libs/liburing/test/pollfree.c10
-rw-r--r--contrib/libs/liburing/test/read-before-exit.c23
-rw-r--r--contrib/libs/liburing/test/read-write.c55
-rw-r--r--contrib/libs/liburing/test/recv-msgall.c44
-rw-r--r--contrib/libs/liburing/test/recv-multishot.c99
-rw-r--r--contrib/libs/liburing/test/reg-hint.c57
-rw-r--r--contrib/libs/liburing/test/reg-hint.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/reg-reg-ring.c91
-rw-r--r--contrib/libs/liburing/test/reg-reg-ring.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/regbuf-merge.c92
-rw-r--r--contrib/libs/liburing/test/regbuf-merge.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/rename.c2
-rw-r--r--contrib/libs/liburing/test/ring-leak.c1
-rw-r--r--contrib/libs/liburing/test/ring-leak2.c2
-rw-r--r--contrib/libs/liburing/test/ringbuf-read.c24
-rw-r--r--contrib/libs/liburing/test/send-zerocopy.c376
-rw-r--r--contrib/libs/liburing/test/send_recv.c11
-rw-r--r--contrib/libs/liburing/test/send_recvmsg.c21
-rw-r--r--contrib/libs/liburing/test/sendmsg_fs_cve.c4
-rw-r--r--contrib/libs/liburing/test/sendmsg_fs_cve.t/ya.make7
-rw-r--r--contrib/libs/liburing/test/single-issuer.c16
-rw-r--r--contrib/libs/liburing/test/skip-cqe.c7
-rw-r--r--contrib/libs/liburing/test/socket.c1
-rw-r--r--contrib/libs/liburing/test/sq-poll-dup.c13
-rw-r--r--contrib/libs/liburing/test/sq-poll-kthread.c2
-rw-r--r--contrib/libs/liburing/test/sq-poll-share.c5
-rw-r--r--contrib/libs/liburing/test/sqpoll-cancel-hang.c23
-rw-r--r--contrib/libs/liburing/test/sqpoll-disable-exit.c8
-rw-r--r--contrib/libs/liburing/test/symlink.c3
-rw-r--r--contrib/libs/liburing/test/test.h3
-rw-r--r--contrib/libs/liburing/test/timeout-new.c18
-rw-r--r--contrib/libs/liburing/test/timeout-overflow.c205
-rw-r--r--contrib/libs/liburing/test/timeout.c279
-rw-r--r--contrib/libs/liburing/test/unlink.c2
-rw-r--r--contrib/libs/liburing/test/version.c26
-rw-r--r--contrib/libs/liburing/test/version.t/ya.make31
-rw-r--r--contrib/libs/liburing/test/wakeup-hang.c2
-rw-r--r--contrib/libs/liburing/test/xattr.c12
106 files changed, 4047 insertions, 824 deletions
diff --git a/contrib/libs/liburing/test/232c93d07b74.c b/contrib/libs/liburing/test/232c93d07b74.c
index ab28adab17..a89e7aebbf 100644
--- a/contrib/libs/liburing/test/232c93d07b74.c
+++ b/contrib/libs/liburing/test/232c93d07b74.c
@@ -34,9 +34,9 @@ struct params {
__be16 bind_port;
};
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-int rcv_ready = 0;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static int rcv_ready = 0;
static void set_rcv_ready(void)
{
diff --git a/contrib/libs/liburing/test/35fa71a030ca.c b/contrib/libs/liburing/test/35fa71a030ca.c
index cf8e3ff605..b21f95a54e 100644
--- a/contrib/libs/liburing/test/35fa71a030ca.c
+++ b/contrib/libs/liburing/test/35fa71a030ca.c
@@ -177,7 +177,7 @@ static void kill_and_wait(int pid, int* status)
}
#define SYZ_HAVE_SETUP_TEST 1
-static void setup_test()
+static void setup_test(void)
{
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
setpgrp();
@@ -263,7 +263,7 @@ static void loop(void)
}
}
-uint64_t r[1] = {0xffffffffffffffff};
+static uint64_t r[1] = {0xffffffffffffffff};
void execute_call(int call)
{
@@ -321,7 +321,7 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
signal(SIGINT, sig_int);
- mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0);
+ mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0);
signal(SIGALRM, sig_int);
alarm(5);
diff --git a/contrib/libs/liburing/test/500f9fbadef8.c b/contrib/libs/liburing/test/500f9fbadef8.c
index c9e4397820..5306d09431 100644
--- a/contrib/libs/liburing/test/500f9fbadef8.c
+++ b/contrib/libs/liburing/test/500f9fbadef8.c
@@ -43,6 +43,8 @@ int main(int argc, char *argv[])
sprintf(buf, "./XXXXXX");
fd = mkostemp(buf, O_WRONLY | O_DIRECT | O_CREAT);
if (fd < 0) {
+ if (errno == EINVAL)
+ return T_EXIT_SKIP;
perror("mkostemp");
return T_EXIT_FAIL;
}
diff --git a/contrib/libs/liburing/test/917257daa0fe.c b/contrib/libs/liburing/test/917257daa0fe.c
index b24d140d83..0fc8e57178 100644
--- a/contrib/libs/liburing/test/917257daa0fe.c
+++ b/contrib/libs/liburing/test/917257daa0fe.c
@@ -20,7 +20,7 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
- mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0);
+ mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0);
*(uint32_t*)0x20000000 = 0;
*(uint32_t*)0x20000004 = 0;
diff --git a/contrib/libs/liburing/test/a0908ae19763.c b/contrib/libs/liburing/test/a0908ae19763.c
index dbe9c5100a..0b0f6a0eac 100644
--- a/contrib/libs/liburing/test/a0908ae19763.c
+++ b/contrib/libs/liburing/test/a0908ae19763.c
@@ -15,13 +15,13 @@
#include "helpers.h"
#include "../src/syscall.h"
-uint64_t r[1] = {0xffffffffffffffff};
+static uint64_t r[1] = {0xffffffffffffffff};
int main(int argc, char *argv[])
{
if (argc > 1)
return T_EXIT_SKIP;
- mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0);
+ mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0);
intptr_t res = 0;
*(uint32_t*)0x20000080 = 0;
*(uint32_t*)0x20000084 = 0;
diff --git a/contrib/libs/liburing/test/a4c0b3decb33.c b/contrib/libs/liburing/test/a4c0b3decb33.c
index 376ecb3d87..89a750a471 100644
--- a/contrib/libs/liburing/test/a4c0b3decb33.c
+++ b/contrib/libs/liburing/test/a4c0b3decb33.c
@@ -96,7 +96,7 @@ static void kill_and_wait(int pid, int* status)
}
}
-static void setup_test()
+static void setup_test(void)
{
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
setpgrp();
@@ -176,7 +176,7 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
signal(SIGINT, sig_int);
- mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0);
+ mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0);
loop();
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/accept-link.c b/contrib/libs/liburing/test/accept-link.c
index af47e0f4f0..36b8e3dd6e 100644
--- a/contrib/libs/liburing/test/accept-link.c
+++ b/contrib/libs/liburing/test/accept-link.c
@@ -17,8 +17,8 @@
#include "liburing.h"
#include "helpers.h"
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static int recv_thread_ready = 0;
static int recv_thread_done = 0;
@@ -78,7 +78,7 @@ static void *send_thread(void *arg)
return NULL;
}
-void *recv_thread(void *arg)
+static void *recv_thread(void *arg)
{
struct data *data = arg;
struct io_uring ring;
@@ -196,7 +196,7 @@ static int test_accept_timeout(int do_connect, unsigned long timeout)
if (ret) {
fprintf(stderr, "queue_init: %d\n", ret);
return 1;
- };
+ }
fast_poll = (p.features & IORING_FEAT_FAST_POLL) != 0;
io_uring_queue_exit(&ring);
diff --git a/contrib/libs/liburing/test/accept-reuse.c b/contrib/libs/liburing/test/accept-reuse.c
index fb15ade840..47c1b1361f 100644
--- a/contrib/libs/liburing/test/accept-reuse.c
+++ b/contrib/libs/liburing/test/accept-reuse.c
@@ -1,6 +1,5 @@
#include "../config-host.h"
/* SPDX-License-Identifier: MIT */
-#include <liburing.h>
#include <netdb.h>
#include <string.h>
#include <sys/socket.h>
@@ -12,17 +11,16 @@
#include "helpers.h"
#include "../src/syscall.h"
-struct io_uring io_uring;
+static struct io_uring io_uring;
-int sys_io_uring_enter(const int fd,
- const unsigned to_submit,
- const unsigned min_complete,
- const unsigned flags, sigset_t * const sig)
+static int sys_io_uring_enter(const int fd, const unsigned to_submit,
+ const unsigned min_complete,
+ const unsigned flags, sigset_t * const sig)
{
return __sys_io_uring_enter(fd, to_submit, min_complete, flags, sig);
}
-int submit_sqe(void)
+static int submit_sqe(void)
{
struct io_uring_sq *sq = &io_uring.sq;
const unsigned tail = *sq->ktail;
diff --git a/contrib/libs/liburing/test/accept.c b/contrib/libs/liburing/test/accept.c
index cde1542a20..df23eab53f 100644
--- a/contrib/libs/liburing/test/accept.c
+++ b/contrib/libs/liburing/test/accept.c
@@ -273,6 +273,7 @@ static int test_loop(struct io_uring *ring,
uint32_t multishot_mask = 0;
int nr_fds = multishot ? MAX_FDS : 1;
int multishot_idx = multishot ? INITIAL_USER_DATA : 0;
+ int err_ret = T_EXIT_FAIL;
if (args.overflow)
cause_overflow(ring);
@@ -299,6 +300,7 @@ static int test_loop(struct io_uring *ring,
no_accept_multi = 1;
else
no_accept = 1;
+ ret = T_EXIT_SKIP;
goto out;
} else if (s_fd[i] < 0) {
if (args.accept_should_error &&
@@ -361,10 +363,10 @@ static int test_loop(struct io_uring *ring,
out:
close_sock_fds(s_fd, c_fd, nr_fds, fixed);
- return 0;
+ return T_EXIT_PASS;
err:
close_sock_fds(s_fd, c_fd, nr_fds, fixed);
- return 1;
+ return err_ret;
}
static int test(struct io_uring *ring, struct accept_test_args args)
@@ -373,7 +375,7 @@ static int test(struct io_uring *ring, struct accept_test_args args)
int ret = 0;
int loop;
int32_t recv_s0 = start_accept_listen(&addr, 0,
- args.nonblock ? O_NONBLOCK : 0);
+ args.nonblock ? SOCK_NONBLOCK : 0);
if (args.queue_accept_before_connect)
queue_accept_conn(ring, recv_s0, args);
for (loop = 0; loop < 1 + args.extra_loops; loop++) {
@@ -459,7 +461,7 @@ static int test_accept_many(struct test_accept_many_args args)
for (i = 0; i < nr_socks; i++)
fds[i] = start_accept_listen(NULL, i,
- args.nonblock ? O_NONBLOCK : 0);
+ args.nonblock ? SOCK_NONBLOCK : 0);
for (i = 0; i < nr; i++) {
int sock_idx = args.single_sock ? 0 : i;
@@ -612,7 +614,7 @@ static int test_multishot_accept(int count, bool before, bool overflow)
return ret;
}
-static int test_accept_multishot_wrong_arg()
+static int test_accept_multishot_wrong_arg(void)
{
struct io_uring m_io_uring;
struct io_uring_cqe *cqe;
@@ -734,8 +736,9 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
+
ret = test_accept(1, false);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept failed\n");
return ret;
}
@@ -743,141 +746,141 @@ int main(int argc, char *argv[])
return T_EXIT_SKIP;
ret = test_accept(2, false);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept(2) failed\n");
return ret;
}
ret = test_accept(2, true);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept(2, true) failed\n");
return ret;
}
ret = test_accept_nonblock(false, 1);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_nonblock failed\n");
return ret;
}
ret = test_accept_nonblock(true, 1);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_nonblock(before, 1) failed\n");
return ret;
}
ret = test_accept_nonblock(true, 3);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_nonblock(before,3) failed\n");
return ret;
}
ret = test_accept_fixed();
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_fixed failed\n");
return ret;
}
ret = test_multishot_fixed_accept();
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_multishot_fixed_accept failed\n");
return ret;
}
ret = test_accept_multishot_wrong_arg();
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_multishot_wrong_arg failed\n");
return ret;
}
ret = test_accept_sqpoll();
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_sqpoll failed\n");
return ret;
}
ret = test_accept_cancel(0, 1, false);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_cancel nodelay failed\n");
return ret;
}
ret = test_accept_cancel(10000, 1, false);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_cancel delay failed\n");
return ret;
}
ret = test_accept_cancel(0, 4, false);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_cancel nodelay failed\n");
return ret;
}
ret = test_accept_cancel(10000, 4, false);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_cancel delay failed\n");
return ret;
}
ret = test_accept_cancel(0, 1, true);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
return ret;
}
ret = test_accept_cancel(10000, 1, true);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_cancel multishot delay failed\n");
return ret;
}
ret = test_accept_cancel(0, 4, true);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
return ret;
}
ret = test_accept_cancel(10000, 4, true);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_cancel multishot delay failed\n");
return ret;
}
ret = test_multishot_accept(1, true, true);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_multishot_accept(1, false, true) failed\n");
return ret;
}
ret = test_multishot_accept(1, false, false);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_multishot_accept(1, false, false) failed\n");
return ret;
}
ret = test_multishot_accept(1, true, false);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_multishot_accept(1, true, false) failed\n");
return ret;
}
ret = test_accept_many((struct test_accept_many_args) {});
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_many failed\n");
return ret;
}
ret = test_accept_many((struct test_accept_many_args) {
.usecs = 100000 });
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_many(sleep) failed\n");
return ret;
}
ret = test_accept_many((struct test_accept_many_args) {
.nonblock = true });
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_many(nonblock) failed\n");
return ret;
}
@@ -886,13 +889,13 @@ int main(int argc, char *argv[])
.nonblock = true,
.single_sock = true,
.close_fds = true });
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_many(nonblock,close) failed\n");
return ret;
}
ret = test_accept_pending_on_exit();
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_accept_pending_on_exit failed\n");
return ret;
}
diff --git a/contrib/libs/liburing/test/b19062a56726.c b/contrib/libs/liburing/test/b19062a56726.c
index e065e30f6e..9356769818 100644
--- a/contrib/libs/liburing/test/b19062a56726.c
+++ b/contrib/libs/liburing/test/b19062a56726.c
@@ -20,7 +20,7 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
- mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0);
+ mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0);
*(uint32_t*)0x20000200 = 0;
*(uint32_t*)0x20000204 = 0;
diff --git a/contrib/libs/liburing/test/buf-ring.c b/contrib/libs/liburing/test/buf-ring.c
index 569639a347..08f03f99ec 100644
--- a/contrib/libs/liburing/test/buf-ring.c
+++ b/contrib/libs/liburing/test/buf-ring.c
@@ -10,20 +10,22 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
+#include <sys/mman.h>
#include "liburing.h"
#include "helpers.h"
static int no_buf_ring;
+static int pagesize;
/* test trying to register classic group when ring group exists */
static int test_mixed_reg2(int bgid)
{
- struct io_uring_buf_reg reg = { };
+ struct io_uring_buf_ring *br;
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
struct io_uring ring;
- void *ptr, *bufs;
+ void *bufs;
int ret;
ret = t_create_ring(1, &ring, 0);
@@ -32,15 +34,8 @@ static int test_mixed_reg2(int bgid)
else if (ret != T_SETUP_OK)
return 1;
- if (posix_memalign(&ptr, 4096, 4096))
- return 1;
-
- reg.ring_addr = (unsigned long) ptr;
- reg.ring_entries = 32;
- reg.bgid = bgid;
-
- ret = io_uring_register_buf_ring(&ring, &reg, 0);
- if (ret) {
+ br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret);
+ if (!br) {
fprintf(stderr, "Buffer ring register failed %d\n", ret);
return 1;
}
@@ -61,6 +56,7 @@ static int test_mixed_reg2(int bgid)
}
io_uring_cqe_seen(&ring, cqe);
+ io_uring_free_buf_ring(&ring, br, 32, bgid);
io_uring_queue_exit(&ring);
return 0;
}
@@ -68,11 +64,11 @@ static int test_mixed_reg2(int bgid)
/* test trying to register ring group when classic group exists */
static int test_mixed_reg(int bgid)
{
- struct io_uring_buf_reg reg = { };
+ struct io_uring_buf_ring *br;
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
struct io_uring ring;
- void *ptr, *bufs;
+ void *bufs;
int ret;
ret = t_create_ring(1, &ring, 0);
@@ -97,16 +93,9 @@ static int test_mixed_reg(int bgid)
}
io_uring_cqe_seen(&ring, cqe);
- if (posix_memalign(&ptr, 4096, 4096))
- return 1;
-
- reg.ring_addr = (unsigned long) ptr;
- reg.ring_entries = 32;
- reg.bgid = bgid;
-
- ret = io_uring_register_buf_ring(&ring, &reg, 0);
- if (ret != -EEXIST) {
- fprintf(stderr, "Buffer ring register failed %d\n", ret);
+ br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret);
+ if (br) {
+ fprintf(stderr, "Buffer ring setup succeeded unexpectedly %d\n", ret);
return 1;
}
@@ -117,8 +106,8 @@ static int test_mixed_reg(int bgid)
static int test_double_reg_unreg(int bgid)
{
struct io_uring_buf_reg reg = { };
+ struct io_uring_buf_ring *br;
struct io_uring ring;
- void *ptr;
int ret;
ret = t_create_ring(1, &ring, 0);
@@ -127,21 +116,14 @@ static int test_double_reg_unreg(int bgid)
else if (ret != T_SETUP_OK)
return 1;
- if (posix_memalign(&ptr, 4096, 4096))
- return 1;
-
- reg.ring_addr = (unsigned long) ptr;
- reg.ring_entries = 32;
- reg.bgid = bgid;
-
- ret = io_uring_register_buf_ring(&ring, &reg, 0);
- if (ret) {
+ br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret);
+ if (!br) {
fprintf(stderr, "Buffer ring register failed %d\n", ret);
return 1;
}
/* check that 2nd register with same bgid fails */
- reg.ring_addr = (unsigned long) ptr;
+ reg.ring_addr = (unsigned long) br;
reg.ring_entries = 32;
reg.bgid = bgid;
@@ -151,7 +133,7 @@ static int test_double_reg_unreg(int bgid)
return 1;
}
- ret = io_uring_unregister_buf_ring(&ring, bgid);
+ ret = io_uring_free_buf_ring(&ring, br, 32, bgid);
if (ret) {
fprintf(stderr, "Buffer ring register failed %d\n", ret);
return 1;
@@ -169,9 +151,8 @@ static int test_double_reg_unreg(int bgid)
static int test_reg_unreg(int bgid)
{
- struct io_uring_buf_reg reg = { };
+ struct io_uring_buf_ring *br;
struct io_uring ring;
- void *ptr;
int ret;
ret = t_create_ring(1, &ring, 0);
@@ -180,15 +161,8 @@ static int test_reg_unreg(int bgid)
else if (ret != T_SETUP_OK)
return 1;
- if (posix_memalign(&ptr, 4096, 4096))
- return 1;
-
- reg.ring_addr = (unsigned long) ptr;
- reg.ring_entries = 32;
- reg.bgid = bgid;
-
- ret = io_uring_register_buf_ring(&ring, &reg, 0);
- if (ret) {
+ br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret);
+ if (!br) {
if (ret == -EINVAL) {
no_buf_ring = 1;
return 0;
@@ -197,9 +171,9 @@ static int test_reg_unreg(int bgid)
return 1;
}
- ret = io_uring_unregister_buf_ring(&ring, bgid);
+ ret = io_uring_free_buf_ring(&ring, br, 32, bgid);
if (ret) {
- fprintf(stderr, "Buffer ring register failed %d\n", ret);
+ fprintf(stderr, "Buffer ring unregister failed %d\n", ret);
return 1;
}
@@ -231,6 +205,54 @@ static int test_bad_reg(int bgid)
return !ret;
}
+static int test_full_page_reg(int bgid)
+{
+#if defined(__hppa__)
+ return T_EXIT_SKIP;
+#else
+ struct io_uring ring;
+ int ret;
+ void *ptr;
+ struct io_uring_buf_reg reg = { };
+ int entries = pagesize / sizeof(struct io_uring_buf);
+
+ ret = io_uring_queue_init(1, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "queue init failed %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = posix_memalign(&ptr, pagesize, pagesize * 2);
+ if (ret) {
+ fprintf(stderr, "posix_memalign failed %d\n", ret);
+ goto err;
+ }
+
+ ret = mprotect(ptr + pagesize, pagesize, PROT_NONE);
+ if (ret) {
+ fprintf(stderr, "mprotect failed %d\n", errno);
+ goto err1;
+ }
+
+ reg.ring_addr = (unsigned long) ptr;
+ reg.ring_entries = entries;
+ reg.bgid = bgid;
+
+ ret = io_uring_register_buf_ring(&ring, &reg, 0);
+ if (ret)
+ fprintf(stderr, "register buf ring failed %d\n", ret);
+
+ if (mprotect(ptr + pagesize, pagesize, PROT_READ | PROT_WRITE))
+ fprintf(stderr, "reverting mprotect failed %d\n", errno);
+
+err1:
+ free(ptr);
+err:
+ io_uring_queue_exit(&ring);
+ return ret ? T_EXIT_FAIL : T_EXIT_PASS;
+#endif
+}
+
static int test_one_read(int fd, int bgid, struct io_uring *ring)
{
int ret;
@@ -273,18 +295,12 @@ static int test_one_read(int fd, int bgid, struct io_uring *ring)
static int test_running(int bgid, int entries, int loops)
{
- struct io_uring_buf_reg reg = { };
+ int ring_mask = io_uring_buf_ring_mask(entries);
+ struct io_uring_buf_ring *br;
+ int ret, loop, idx, read_fd;
struct io_uring ring;
- void *ptr;
char buffer[8];
- int ret;
- int ring_size = (entries * sizeof(struct io_uring_buf) + 4095) & (~4095);
- int ring_mask = io_uring_buf_ring_mask(entries);
-
- int loop, idx;
bool *buffers;
- struct io_uring_buf_ring *br;
- int read_fd;
ret = t_create_ring(1, &ring, 0);
if (ret == T_SETUP_SKIP)
@@ -292,11 +308,12 @@ static int test_running(int bgid, int entries, int loops)
else if (ret != T_SETUP_OK)
return 1;
- if (posix_memalign(&ptr, 4096, ring_size))
+ br = io_uring_setup_buf_ring(&ring, entries, bgid, 0, &ret);
+ if (!br) {
+ /* by now should have checked if this is supported or not */
+ fprintf(stderr, "Buffer ring register failed %d\n", ret);
return 1;
-
- br = (struct io_uring_buf_ring *)ptr;
- io_uring_buf_ring_init(br);
+ }
buffers = malloc(sizeof(bool) * entries);
if (!buffers)
@@ -306,17 +323,6 @@ static int test_running(int bgid, int entries, int loops)
if (read_fd < 0)
return 1;
- reg.ring_addr = (unsigned long) ptr;
- reg.ring_entries = entries;
- reg.bgid = bgid;
-
- ret = io_uring_register_buf_ring(&ring, &reg, 0);
- if (ret) {
- /* by now should have checked if this is supported or not */
- fprintf(stderr, "Buffer ring register failed %d\n", ret);
- return 1;
- }
-
for (loop = 0; loop < loops; loop++) {
memset(buffers, 0, sizeof(bool) * entries);
for (idx = 0; idx < entries; idx++)
@@ -375,6 +381,8 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
+ pagesize = getpagesize();
+
for (i = 0; bgids[i] != -1; i++) {
ret = test_reg_unreg(bgids[i]);
if (ret) {
@@ -407,6 +415,12 @@ int main(int argc, char *argv[])
fprintf(stderr, "test_mixed_reg2 failed\n");
return T_EXIT_FAIL;
}
+
+ ret = test_full_page_reg(bgids[i]);
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test_full_page_reg failed\n");
+ return T_EXIT_FAIL;
+ }
}
for (i = 0; !no_buf_ring && entries[i] != -1; i++) {
diff --git a/contrib/libs/liburing/test/ce593a6c480a.c b/contrib/libs/liburing/test/ce593a6c480a.c
index 7b6fc438ae..4677a095d4 100644
--- a/contrib/libs/liburing/test/ce593a6c480a.c
+++ b/contrib/libs/liburing/test/ce593a6c480a.c
@@ -16,7 +16,7 @@
static int use_sqpoll = 0;
-void notify_fd(int fd)
+static void notify_fd(int fd)
{
char buf[8] = {0, 0, 0, 0, 0, 0, 1};
int ret;
@@ -26,7 +26,7 @@ void notify_fd(int fd)
perror("write");
}
-void *delay_set_fd_from_thread(void *data)
+static void *delay_set_fd_from_thread(void *data)
{
int fd = (intptr_t) data;
diff --git a/contrib/libs/liburing/test/close-opath.c b/contrib/libs/liburing/test/close-opath.c
index 85fe30d9df..818493261d 100644
--- a/contrib/libs/liburing/test/close-opath.c
+++ b/contrib/libs/liburing/test/close-opath.c
@@ -16,12 +16,13 @@
#include <errno.h>
#include <fcntl.h>
-#include <liburing.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include "liburing.h"
+
typedef struct
{
const char *const flnames;
diff --git a/contrib/libs/liburing/test/connect-rep.c b/contrib/libs/liburing/test/connect-rep.c
new file mode 100644
index 0000000000..ca300e7ac3
--- /dev/null
+++ b/contrib/libs/liburing/test/connect-rep.c
@@ -0,0 +1,205 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Check that repeated IORING_OP_CONNECT to a socket without a listener keeps
+ * yielding -ECONNREFUSED rather than -ECONNABORTED. Based on a reproducer
+ * from:
+ *
+ * https://github.com/axboe/liburing/issues/828
+ *
+ * and adopted to our usual test cases. Other changes made like looping,
+ * using different ring types, adding a memset() for reuse, etc.
+ *
+ */
+#include <stdio.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+static unsigned long ud;
+
+static int init_test_server(struct sockaddr_in *serv_addr)
+{
+ socklen_t servaddr_len = sizeof(struct sockaddr_in);
+ int fd;
+
+ /* Init server socket. Bind but don't listen */
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ perror("socket");
+ return -1;
+ }
+
+ serv_addr->sin_family = AF_INET;
+ serv_addr->sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ if (bind(fd, (struct sockaddr *) serv_addr, servaddr_len) < 0) {
+ perror("bind");
+ return -1;
+ }
+
+ /*
+ * Get the addresses the socket is bound to because the port is chosen
+ * by the network stack.
+ */
+ if (getsockname(fd, (struct sockaddr *)serv_addr, &servaddr_len) < 0) {
+ perror("getsockname");
+ return -1;
+ }
+
+ return fd;
+}
+
+static int init_test_client(void)
+{
+ socklen_t addr_len = sizeof(struct sockaddr_in);
+ struct sockaddr_in client_addr = {};
+ int clientfd;
+
+ clientfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (clientfd < 0) {
+ perror("socket");
+ return -1;
+ }
+
+ client_addr.sin_family = AF_INET;
+ client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ if (bind(clientfd, (struct sockaddr *)&client_addr, addr_len) < 0) {
+ perror("bind");
+ close(clientfd);
+ return -1;
+ }
+
+ /*
+ * Get the addresses the socket is bound to because the port is chosen
+ * by the network stack.
+ */
+ if (getsockname(clientfd, (struct sockaddr *)&client_addr, &addr_len) < 0) {
+ perror("getsockname");
+ close(clientfd);
+ return -1;
+ }
+
+ return clientfd;
+}
+
+static int get_completion_and_print(struct io_uring *ring)
+{
+ struct io_uring_cqe *cqe;
+ int ret, res;
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait_cqe=%d\n", ret);
+ return -1;
+ }
+
+ /* Mark this completion as seen */
+ res = cqe->res;
+ io_uring_cqe_seen(ring, cqe);
+ return res;
+}
+
+static int test_connect(struct io_uring *ring,
+ int clientfd, struct sockaddr_in *serv_addr)
+{
+ struct sockaddr_in local_sa;
+ struct io_uring_sqe *sqe;
+ int ret;
+
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_connect(sqe, clientfd, (const struct sockaddr *)serv_addr,
+ sizeof(struct sockaddr_in));
+ sqe->user_data = ++ud;
+
+ memcpy(&local_sa, serv_addr, sizeof(local_sa));
+
+ ret = io_uring_submit_and_wait(ring, 1);
+ if (ret != 1) {
+ fprintf(stderr, "submit=%d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ /* check for reuse at the same time */
+ memset(&local_sa, 0xff, sizeof(local_sa));
+
+ ret = get_completion_and_print(ring);
+ if (ret != -ECONNREFUSED) {
+ fprintf(stderr, "Connect got %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ return T_EXIT_PASS;
+}
+
+static int test(int flags)
+{
+ struct io_uring_params params = { .flags = flags, };
+ struct sockaddr_in serv_addr = {};
+ struct io_uring ring;
+ int ret, clientfd, s_fd, i;
+
+ if (flags & IORING_SETUP_SQPOLL)
+ params.sq_thread_idle = 50;
+
+ ret = io_uring_queue_init_params(8, &ring, &params);
+ if (ret < 0) {
+ fprintf(stderr, "Queue init: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ s_fd = init_test_server(&serv_addr);
+ if (s_fd < 0)
+ return T_EXIT_FAIL;
+
+ clientfd = init_test_client();
+ if (clientfd < 0) {
+ close(s_fd);
+ return T_EXIT_FAIL;
+ }
+
+ /* make sure SQPOLL thread is sleeping */
+ if (flags & IORING_SETUP_SQPOLL)
+ usleep(100000);
+
+ for (i = 0; i < 32; i++) {
+ ret = test_connect(&ring, clientfd, &serv_addr);
+ if (ret == T_EXIT_SKIP)
+ return T_EXIT_SKIP;
+ else if (ret == T_EXIT_PASS)
+ continue;
+
+ return T_EXIT_FAIL;
+ }
+
+ close(s_fd);
+ close(clientfd);
+ return T_EXIT_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = test(0);
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test(0) failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(IORING_SETUP_SQPOLL);
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test(SQPOLL) failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ return 0;
+}
diff --git a/contrib/libs/liburing/test/timeout-overflow.t/ya.make b/contrib/libs/liburing/test/connect-rep.t/ya.make
index de0ef396f3..556843fd8b 100644
--- a/contrib/libs/liburing/test/timeout-overflow.t/ya.make
+++ b/contrib/libs/liburing/test/connect-rep.t/ya.make
@@ -24,8 +24,8 @@ CFLAGS(
SRCDIR(contrib/libs/liburing/test)
SRCS(
+ connect-rep.c
helpers.c
- timeout-overflow.c
)
END()
diff --git a/contrib/libs/liburing/test/connect.c b/contrib/libs/liburing/test/connect.c
index 30f3ac1c3f..f1b7d941f4 100644
--- a/contrib/libs/liburing/test/connect.c
+++ b/contrib/libs/liburing/test/connect.c
@@ -16,6 +16,7 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
+#include <sys/stat.h>
#include "liburing.h"
#include "helpers.h"
@@ -257,6 +258,13 @@ static int test_connect_timeout(struct io_uring *ring)
struct sockaddr_in addr;
struct io_uring_sqe *sqe;
struct __kernel_timespec ts = {.tv_sec = 0, .tv_nsec = 100000};
+ struct stat sb;
+
+ /*
+ * Test reliably fails if syncookies isn't enabled
+ */
+ if (stat("/proc/sys/net/ipv4/tcp_syncookies", &sb) < 0)
+ return T_EXIT_SKIP;
connect_fd[0] = create_socket();
if (connect_fd[0] == -1)
diff --git a/contrib/libs/liburing/test/cq-overflow.c b/contrib/libs/liburing/test/cq-overflow.c
index f43e19c013..569c733752 100644
--- a/contrib/libs/liburing/test/cq-overflow.c
+++ b/contrib/libs/liburing/test/cq-overflow.c
@@ -49,7 +49,8 @@ static struct iovec *vecs;
* bash -c "echo 1 > /proc/self/make-it-fail && exec ./cq-overflow.t"
*/
-static int test_io(const char *file, unsigned long usecs, unsigned *drops, int fault)
+static int test_io(const char *file, unsigned long usecs, unsigned *drops,
+ int fault)
{
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
@@ -61,8 +62,10 @@ static int test_io(const char *file, unsigned long usecs, unsigned *drops, int f
fd = open(file, O_RDONLY | O_DIRECT);
if (fd < 0) {
+ if (errno == EINVAL)
+ return T_EXIT_SKIP;
perror("file open");
- return 1;
+ return T_EXIT_FAIL;
}
memset(&p, 0, sizeof(p));
@@ -70,7 +73,7 @@ static int test_io(const char *file, unsigned long usecs, unsigned *drops, int f
if (ret) {
close(fd);
fprintf(stderr, "ring create failed: %d\n", ret);
- return 1;
+ return T_EXIT_FAIL;
}
nodrop = 0;
if (p.features & IORING_FEAT_NODROP)
@@ -174,12 +177,12 @@ reap_it:
io_uring_queue_exit(&ring);
close(fd);
- return 0;
+ return T_EXIT_PASS;
err:
if (fd != -1)
close(fd);
io_uring_queue_exit(&ring);
- return 1;
+ return T_EXIT_SKIP;
}
static int reap_events(struct io_uring *ring, unsigned nr_events, int do_wait)
@@ -497,7 +500,10 @@ int main(int argc, char *argv[])
do {
drops = 0;
- if (test_io(fname, usecs, &drops, 0)) {
+ ret = test_io(fname, usecs, &drops, 0);
+ if (ret == T_EXIT_SKIP)
+ break;
+ else if (ret != T_EXIT_PASS) {
fprintf(stderr, "test_io nofault failed\n");
goto err;
}
@@ -507,12 +513,12 @@ int main(int argc, char *argv[])
iters++;
} while (iters < 40);
- if (test_io(fname, usecs, &drops, 0)) {
+ if (test_io(fname, usecs, &drops, 0) == T_EXIT_FAIL) {
fprintf(stderr, "test_io nofault failed\n");
goto err;
}
- if (test_io(fname, usecs, &drops, 1)) {
+ if (test_io(fname, usecs, &drops, 1) == T_EXIT_FAIL) {
fprintf(stderr, "test_io fault failed\n");
goto err;
}
diff --git a/contrib/libs/liburing/test/d4ae271dfaae.c b/contrib/libs/liburing/test/d4ae271dfaae.c
index 1a7886ed6b..af47047be8 100644
--- a/contrib/libs/liburing/test/d4ae271dfaae.c
+++ b/contrib/libs/liburing/test/d4ae271dfaae.c
@@ -30,7 +30,7 @@ int main(int argc, char *argv[])
memset(&p, 0, sizeof(p));
p.flags = IORING_SETUP_SQPOLL;
- ret = t_create_ring_params(4, &ring, &p);
+ ret = t_create_ring_params(16, &ring, &p);
if (ret == T_SETUP_SKIP)
return T_EXIT_SKIP;
else if (ret < 0)
diff --git a/contrib/libs/liburing/test/defer-taskrun.c b/contrib/libs/liburing/test/defer-taskrun.c
index b07ac2f778..c2543f4b26 100644
--- a/contrib/libs/liburing/test/defer-taskrun.c
+++ b/contrib/libs/liburing/test/defer-taskrun.c
@@ -5,7 +5,6 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
-#include <error.h>
#include <sys/eventfd.h>
#include <signal.h>
#include <poll.h>
@@ -58,9 +57,14 @@ static void eventfd_trigger(int fd)
assert(ret == sizeof(val));
}
-#define CHECK(x) if (!(x)) { \
- fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \
- return -1; }
+#define CHECK(x) \
+do { \
+ if (!(x)) { \
+ fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \
+ return -1; \
+ } \
+} while (0)
+
static int test_eventfd(void)
{
@@ -120,7 +124,7 @@ struct thread_data {
char buff[8];
};
-void *thread(void *t)
+static void *thread(void *t)
{
struct thread_data *td = t;
@@ -179,11 +183,11 @@ static int test_exec(const char *filename)
int wstatus;
CHECK(waitpid(fork_pid, &wstatus, 0) != (pid_t)-1);
- if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != T_EXIT_SKIP) {
+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) == T_EXIT_FAIL) {
fprintf(stderr, "child failed %i\n", WEXITSTATUS(wstatus));
return -1;
}
- return 0;
+ return T_EXIT_PASS;
}
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
@@ -193,9 +197,15 @@ static int test_exec(const char *filename)
if (filename) {
fd = open(filename, O_RDONLY | O_DIRECT);
+ if (fd < 0 && errno == EINVAL)
+ return T_EXIT_SKIP;
} else {
t_create_file(EXEC_FILENAME, EXEC_FILESIZE);
fd = open(EXEC_FILENAME, O_RDONLY | O_DIRECT);
+ if (fd < 0 && errno == EINVAL) {
+ unlink(EXEC_FILENAME);
+ return T_EXIT_SKIP;
+ }
unlink(EXEC_FILENAME);
}
buff = (char*)malloc(EXEC_FILESIZE);
@@ -208,7 +218,7 @@ static int test_exec(const char *filename)
ret = execve("/proc/self/exe", new_argv, new_env);
/* if we get here it failed anyway */
fprintf(stderr, "execve failed %d\n", ret);
- return -1;
+ return T_EXIT_FAIL;
}
static int test_flag(void)
@@ -284,6 +294,45 @@ static int test_ring_shutdown(void)
return 0;
}
+static int test_drain(void)
+{
+ struct io_uring ring;
+ int ret, i, fd[2];
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct iovec iovecs[128];
+ char buff[ARRAY_SIZE(iovecs)];
+
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN |
+ IORING_SETUP_TASKRUN_FLAG);
+ CHECK(!ret);
+
+ for (i = 0; i < ARRAY_SIZE(iovecs); i++) {
+ iovecs[i].iov_base = &buff[i];
+ iovecs[i].iov_len = 1;
+ }
+
+ ret = t_create_socket_pair(fd, true);
+ CHECK(!ret);
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_writev(sqe, fd[1], &iovecs[0], ARRAY_SIZE(iovecs), 0);
+ sqe->flags |= IOSQE_IO_DRAIN;
+ io_uring_submit(&ring);
+
+ for (i = 0; i < ARRAY_SIZE(iovecs); i++)
+ iovecs[i].iov_base = NULL;
+
+ CHECK(io_uring_wait_cqe(&ring, &cqe) == 0);
+ CHECK(cqe->res == 128);
+
+ close(fd[0]);
+ close(fd[1]);
+ io_uring_queue_exit(&ring);
+ return 0;
+}
+
int main(int argc, char *argv[])
{
int ret;
@@ -310,7 +359,7 @@ int main(int argc, char *argv[])
}
ret = test_exec(filename);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_exec failed\n");
return T_EXIT_FAIL;
}
@@ -333,5 +382,11 @@ int main(int argc, char *argv[])
return T_EXIT_FAIL;
}
+ ret = test_drain();
+ if (ret) {
+ fprintf(stderr, "test_drain failed\n");
+ return T_EXIT_FAIL;
+ }
+
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/defer.c b/contrib/libs/liburing/test/defer.c
index 4e7cd23135..c1e7478906 100644
--- a/contrib/libs/liburing/test/defer.c
+++ b/contrib/libs/liburing/test/defer.c
@@ -58,7 +58,7 @@ static int init_context(struct test_context *ctx, struct io_uring *ring, int nr,
case OP_REMOVE_BUFFERS:
io_uring_prep_remove_buffers(sqe, 10, 1);
break;
- };
+ }
sqe->user_data = i;
ctx->sqes[i] = sqe;
}
diff --git a/contrib/libs/liburing/test/double-poll-crash.c b/contrib/libs/liburing/test/double-poll-crash.c
index c24ad86661..67be0682c4 100644
--- a/contrib/libs/liburing/test/double-poll-crash.c
+++ b/contrib/libs/liburing/test/double-poll-crash.c
@@ -110,7 +110,7 @@ static long syz_open_dev(volatile long a0, volatile long a1, volatile long a2)
}
}
-uint64_t r[4] = {0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff};
+static uint64_t r[4] = {0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff};
int main(int argc, char *argv[])
{
@@ -122,10 +122,10 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
- mmap_ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
+ mmap_ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
if (mmap_ret == MAP_FAILED)
return T_EXIT_SKIP;
- mmap_ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
+ mmap_ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
if (mmap_ret == MAP_FAILED)
return T_EXIT_SKIP;
intptr_t res = 0;
diff --git a/contrib/libs/liburing/test/eeed8b54e0df.c b/contrib/libs/liburing/test/eeed8b54e0df.c
index c4118a2d51..6b73a35db6 100644
--- a/contrib/libs/liburing/test/eeed8b54e0df.c
+++ b/contrib/libs/liburing/test/eeed8b54e0df.c
@@ -103,13 +103,18 @@ int main(int argc, char *argv[])
goto err;
}
+ ret = T_EXIT_PASS;
if (cqe->res != -EAGAIN && cqe->res != 4096) {
- printf("cqe error: %d\n", cqe->res);
- goto err;
+ if (cqe->res == -EOPNOTSUPP) {
+ ret = T_EXIT_SKIP;
+ } else {
+ printf("cqe error: %d\n", cqe->res);
+ goto err;
+ }
}
close(fd);
- return T_EXIT_PASS;
+ return ret;
err:
close(fd);
return T_EXIT_FAIL;
diff --git a/contrib/libs/liburing/test/eploop.c b/contrib/libs/liburing/test/eploop.c
new file mode 100644
index 0000000000..f3fd3f582e
--- /dev/null
+++ b/contrib/libs/liburing/test/eploop.c
@@ -0,0 +1,75 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Test that we don't recursively generate completion events if an io_uring
+ * fd is added to an epoll context, and the ring itself polls for events on
+ * the epollfd. Older kernels will stop on overflow, newer kernels will
+ * detect this earlier and abort correctly.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/epoll.h>
+#include <sys/types.h>
+#include <poll.h>
+#include "liburing.h"
+#include "helpers.h"
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct epoll_event ev = { };
+ int epollfd, ret, i;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "Ring init failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ epollfd = epoll_create1(0);
+ if (epollfd < 0) {
+ perror("epoll_create");
+ return T_EXIT_FAIL;
+ }
+
+ ev.events = EPOLLIN;
+ ev.data.fd = ring.ring_fd;
+ ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, ring.ring_fd, &ev);
+ if (ret < 0) {
+ perror("epoll_ctl");
+ return T_EXIT_FAIL;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_poll_multishot(sqe, epollfd, POLLIN);
+ sqe->user_data = 1;
+ io_uring_submit(&ring);
+
+ sqe = io_uring_get_sqe(&ring);
+ sqe->user_data = 2;
+ io_uring_prep_nop(sqe);
+ io_uring_submit(&ring);
+
+ for (i = 0; i < 2; i++) {
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait_cqe ret = %d\n", ret);
+ break;
+ }
+ io_uring_cqe_seen(&ring, cqe);
+ }
+
+ ret = io_uring_peek_cqe(&ring, &cqe);
+ if (!ret) {
+ fprintf(stderr, "Generated too many events\n");
+ return T_EXIT_FAIL;
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/eploop.t/ya.make b/contrib/libs/liburing/test/eploop.t/ya.make
new file mode 100644
index 0000000000..29b1f9096a
--- /dev/null
+++ b/contrib/libs/liburing/test/eploop.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ eploop.c
+ helpers.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/eventfd-ring.c b/contrib/libs/liburing/test/eventfd-ring.c
index d4bed86526..e0a3eecaa5 100644
--- a/contrib/libs/liburing/test/eventfd-ring.c
+++ b/contrib/libs/liburing/test/eventfd-ring.c
@@ -1,7 +1,7 @@
#include "../config-host.h"
/* SPDX-License-Identifier: MIT */
/*
- * Description: run various nop tests
+ * Description: test use of eventfds with multiple rings
*
*/
#include <errno.h>
diff --git a/contrib/libs/liburing/test/eventfd.c b/contrib/libs/liburing/test/eventfd.c
index 317de29fb4..081987f520 100644
--- a/contrib/libs/liburing/test/eventfd.c
+++ b/contrib/libs/liburing/test/eventfd.c
@@ -1,7 +1,7 @@
#include "../config-host.h"
/* SPDX-License-Identifier: MIT */
/*
- * Description: run various nop tests
+ * Description: run various eventfd tests
*
*/
#include <errno.h>
diff --git a/contrib/libs/liburing/test/evloop.c b/contrib/libs/liburing/test/evloop.c
new file mode 100644
index 0000000000..a4339d9471
--- /dev/null
+++ b/contrib/libs/liburing/test/evloop.c
@@ -0,0 +1,74 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Test that we don't recursively generate completion events if an io_uring
+ * has an eventfd registered that triggers on completions, and we add a poll
+ * request with multishot on the eventfd. Older kernels will stop on overflow,
+ * newer kernels will detect this earlier and abort correctly.
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/eventfd.h>
+#include <sys/types.h>
+#include <poll.h>
+#include <assert.h>
+#include "liburing.h"
+#include "helpers.h"
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int ret, efd, i;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "Ring init failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ efd = eventfd(0, 0);
+ if (efd < 0) {
+ perror("eventfd");
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_register_eventfd(&ring, efd);
+ if (ret) {
+ fprintf(stderr, "Ring eventfd register failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_poll_multishot(sqe, efd, POLLIN);
+ sqe->user_data = 1;
+ io_uring_submit(&ring);
+
+ sqe = io_uring_get_sqe(&ring);
+ sqe->user_data = 2;
+ io_uring_prep_nop(sqe);
+ io_uring_submit(&ring);
+
+ for (i = 0; i < 2; i++) {
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait_cqe ret = %d\n", ret);
+ break;
+ }
+ io_uring_cqe_seen(&ring, cqe);
+ }
+
+ ret = io_uring_peek_cqe(&ring, &cqe);
+ if (!ret) {
+ fprintf(stderr, "Generated too many events\n");
+ return T_EXIT_FAIL;
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/evloop.t/ya.make b/contrib/libs/liburing/test/evloop.t/ya.make
new file mode 100644
index 0000000000..6040603610
--- /dev/null
+++ b/contrib/libs/liburing/test/evloop.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ evloop.c
+ helpers.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/exit-no-cleanup.c b/contrib/libs/liburing/test/exit-no-cleanup.c
index 2fe3dc7ddd..abf63ab2b0 100644
--- a/contrib/libs/liburing/test/exit-no-cleanup.c
+++ b/contrib/libs/liburing/test/exit-no-cleanup.c
@@ -27,7 +27,7 @@ static pthread_barrier_t init_barrier;
static int sleep_fd, notify_fd;
static sem_t sem;
-void *thread_func(void *arg)
+static void *thread_func(void *arg)
{
struct io_uring ring;
int res;
diff --git a/contrib/libs/liburing/test/fadvise.c b/contrib/libs/liburing/test/fadvise.c
index 86670b80f4..12b7ffd912 100644
--- a/contrib/libs/liburing/test/fadvise.c
+++ b/contrib/libs/liburing/test/fadvise.c
@@ -187,7 +187,7 @@ int main(int argc, char *argv[])
}
/* too hard to reliably test, just ignore */
- if (0 && bad > good) {
+ if ((0) && bad > good) {
fprintf(stderr, "Suspicious timings\n");
goto err;
}
diff --git a/contrib/libs/liburing/test/fallocate.c b/contrib/libs/liburing/test/fallocate.c
index a546922f96..cff01528fc 100644
--- a/contrib/libs/liburing/test/fallocate.c
+++ b/contrib/libs/liburing/test/fallocate.c
@@ -13,6 +13,7 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
+#include <signal.h>
#include "liburing.h"
#include "helpers.h"
@@ -217,14 +218,22 @@ err:
return 1;
}
+static void sig_xfsz(int sig)
+{
+}
+
int main(int argc, char *argv[])
{
+ struct sigaction act = { };
struct io_uring ring;
int ret;
if (argc > 1)
return T_EXIT_SKIP;
+ act.sa_handler = sig_xfsz;
+ sigaction(SIGXFSZ, &act, NULL);
+
ret = io_uring_queue_init(8, &ring, 0);
if (ret) {
fprintf(stderr, "ring setup failed\n");
diff --git a/contrib/libs/liburing/test/fc2a85cb02ef.c b/contrib/libs/liburing/test/fc2a85cb02ef.c
index 3c61374845..538e8d4312 100644
--- a/contrib/libs/liburing/test/fc2a85cb02ef.c
+++ b/contrib/libs/liburing/test/fc2a85cb02ef.c
@@ -55,7 +55,7 @@ static int inject_fault(int nth)
return fd;
}
-static int setup_fault()
+static int setup_fault(void)
{
static struct {
const char* file;
@@ -80,13 +80,13 @@ static int setup_fault()
return 0;
}
-uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+static uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
int main(int argc, char *argv[])
{
if (argc > 1)
return T_EXIT_SKIP;
- mmap((void *) 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+ mmap((void *) 0x20000000ul, 0x1000000ul, 3ul, MAP_ANON|MAP_PRIVATE, -1, 0);
if (setup_fault()) {
printf("Test needs failslab/fail_futex/fail_page_alloc enabled, skipped\n");
return T_EXIT_SKIP;
diff --git a/contrib/libs/liburing/test/fd-pass.c b/contrib/libs/liburing/test/fd-pass.c
index 9549d418e5..c5da83592b 100644
--- a/contrib/libs/liburing/test/fd-pass.c
+++ b/contrib/libs/liburing/test/fd-pass.c
@@ -14,8 +14,9 @@
#include "liburing.h"
#include "helpers.h"
-#define FSIZE 128
-#define PAT 0x9a
+#define FSIZE 128
+#define PAT 0x9a
+#define USER_DATA 0x89
static int no_fd_pass;
@@ -50,7 +51,7 @@ static int verify_fixed_read(struct io_uring *ring, int fixed_fd, int fail)
return 0;
}
-static int test(const char *filename)
+static int test(const char *filename, int source_fd, int target_fd)
{
struct io_uring sring, dring;
struct io_uring_sqe *sqe;
@@ -80,10 +81,18 @@ static int test(const char *filename)
fprintf(stderr, "register files failed %d\n", ret);
return T_EXIT_FAIL;
}
+ if (target_fd == IORING_FILE_INDEX_ALLOC) {
+ /* we want to test installing into a non-zero slot */
+ ret = io_uring_register_file_alloc_range(&dring, 1, 1);
+ if (ret) {
+ fprintf(stderr, "io_uring_register_file_alloc_range %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ }
/* open direct descriptor */
sqe = io_uring_get_sqe(&sring);
- io_uring_prep_openat_direct(sqe, AT_FDCWD, filename, 0, 0644, 0);
+ io_uring_prep_openat_direct(sqe, AT_FDCWD, filename, 0, 0644, source_fd);
io_uring_submit(&sring);
ret = io_uring_wait_cqe(&sring, &cqe);
if (ret) {
@@ -97,15 +106,19 @@ static int test(const char *filename)
io_uring_cqe_seen(&sring, cqe);
/* verify data is sane for source ring */
- if (verify_fixed_read(&sring, 0, 0))
+ if (verify_fixed_read(&sring, source_fd, 0))
return T_EXIT_FAIL;
/* send direct descriptor to destination ring */
sqe = io_uring_get_sqe(&sring);
- io_uring_prep_msg_ring(sqe, dring.ring_fd, 0, 0x89, 0);
- sqe->addr = 1;
- sqe->addr3 = 0;
- sqe->file_index = 1;
+ if (target_fd == IORING_FILE_INDEX_ALLOC) {
+ io_uring_prep_msg_ring_fd_alloc(sqe, dring.ring_fd, source_fd,
+ USER_DATA, 0);
+ } else {
+
+ io_uring_prep_msg_ring_fd(sqe, dring.ring_fd, source_fd,
+ target_fd, USER_DATA, 0);
+ }
io_uring_submit(&sring);
ret = io_uring_wait_cqe(&sring, &cqe);
@@ -113,7 +126,7 @@ static int test(const char *filename)
fprintf(stderr, "wait cqe failed %d\n", ret);
return T_EXIT_FAIL;
}
- if (cqe->res) {
+ if (cqe->res < 0) {
if (cqe->res == -EINVAL && !no_fd_pass) {
no_fd_pass = 1;
return T_EXIT_SKIP;
@@ -129,19 +142,30 @@ static int test(const char *filename)
fprintf(stderr, "wait cqe failed %d\n", ret);
return T_EXIT_FAIL;
}
- if (cqe->user_data != 0x89) {
+ if (cqe->user_data != USER_DATA) {
fprintf(stderr, "bad user_data %ld\n", (long) cqe->res);
return T_EXIT_FAIL;
}
+ if (cqe->res < 0) {
+ fprintf(stderr, "bad result %i\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
+ if (target_fd == IORING_FILE_INDEX_ALLOC) {
+ if (cqe->res != 1) {
+ fprintf(stderr, "invalid allocated index %i\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
+ target_fd = cqe->res;
+ }
io_uring_cqe_seen(&dring, cqe);
/* now verify we can read the sane data from the destination ring */
- if (verify_fixed_read(&dring, 0, 0))
+ if (verify_fixed_read(&dring, target_fd, 0))
return T_EXIT_FAIL;
/* close descriptor in source ring */
sqe = io_uring_get_sqe(&sring);
- io_uring_prep_close_direct(sqe, 0);
+ io_uring_prep_close_direct(sqe, source_fd);
io_uring_submit(&sring);
ret = io_uring_wait_cqe(&sring, &cqe);
@@ -156,13 +180,15 @@ static int test(const char *filename)
io_uring_cqe_seen(&sring, cqe);
/* check that source ring fails after close */
- if (verify_fixed_read(&sring, 0, 1))
+ if (verify_fixed_read(&sring, source_fd, 1))
return T_EXIT_FAIL;
/* check we can still read from destination ring */
- if (verify_fixed_read(&dring, 0, 0))
+ if (verify_fixed_read(&dring, target_fd, 0))
return T_EXIT_FAIL;
+ io_uring_queue_exit(&sring);
+ io_uring_queue_exit(&dring);
return T_EXIT_PASS;
}
@@ -177,9 +203,33 @@ int main(int argc, char *argv[])
sprintf(fname, ".fd-pass.%d", getpid());
t_create_file_pattern(fname, FSIZE, PAT);
- ret = test(fname);
+ ret = test(fname, 0, 1);
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test failed 0 1\n");
+ ret = T_EXIT_FAIL;
+ }
+
+ ret = test(fname, 0, 2);
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test failed 0 2\n");
+ ret = T_EXIT_FAIL;
+ }
+
+ ret = test(fname, 1, 1);
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test failed 1 1\n");
+ ret = T_EXIT_FAIL;
+ }
+
+ ret = test(fname, 1, 0);
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test failed 1 0\n");
+ ret = T_EXIT_FAIL;
+ }
+
+ ret = test(fname, 1, IORING_FILE_INDEX_ALLOC);
if (ret == T_EXIT_FAIL) {
- fprintf(stderr, "test failed\n");
+ fprintf(stderr, "test failed 1 ALLOC\n");
ret = T_EXIT_FAIL;
}
diff --git a/contrib/libs/liburing/test/file-register.c b/contrib/libs/liburing/test/file-register.c
index 707cd5422f..ee30b3e4f8 100644
--- a/contrib/libs/liburing/test/file-register.c
+++ b/contrib/libs/liburing/test/file-register.c
@@ -936,6 +936,59 @@ static int test_zero_range_alloc(struct io_uring *ring, int fds[2])
return 0;
}
+static int test_defer_taskrun(void)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring ring;
+ int ret, fds[2];
+ char buff = 'x';
+
+ ret = io_uring_queue_init(8, &ring,
+ IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER);
+ if (ret) {
+ fprintf(stderr, "ring init\n");
+ return 1;
+ }
+
+ ret = pipe(fds);
+ if (ret) {
+ fprintf(stderr, "bad pipes\n");
+ return 1;
+ }
+
+ ret = io_uring_register_files(&ring, &fds[0], 2);
+ if (ret) {
+ fprintf(stderr, "bad register %d\n", ret);
+ return 1;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_read(sqe, 0, &buff, 1, 0);
+ sqe->flags |= IOSQE_FIXED_FILE;
+ ret = io_uring_submit(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "bad submit\n");
+ return 1;
+ }
+
+ ret = write(fds[1], &buff, 1);
+ if (ret != 1) {
+ fprintf(stderr, "bad pipe write\n");
+ return 1;
+ }
+
+ ret = io_uring_unregister_files(&ring);
+ if (ret) {
+ fprintf(stderr, "bad unregister %d\n", ret);
+ return 1;
+ }
+
+ close(fds[0]);
+ close(fds[1]);
+ io_uring_queue_exit(&ring);
+ return 0;
+}
+
static int test_file_alloc_ranges(void)
{
struct io_uring ring;
@@ -1121,5 +1174,13 @@ int main(int argc, char *argv[])
return T_EXIT_FAIL;
}
+ if (t_probe_defer_taskrun()) {
+ ret = test_defer_taskrun();
+ if (ret) {
+ fprintf(stderr, "test_defer_taskrun failed\n");
+ return T_EXIT_FAIL;
+ }
+ }
+
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/file-verify.c b/contrib/libs/liburing/test/file-verify.c
index 7950b739cc..fd192ec272 100644
--- a/contrib/libs/liburing/test/file-verify.c
+++ b/contrib/libs/liburing/test/file-verify.c
@@ -11,7 +11,6 @@
#include <string.h>
#include <fcntl.h>
#include <assert.h>
-#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <linux/fs.h>
@@ -34,20 +33,38 @@
*/
#define READ_BATCH 16
+static void verify_buf_sync(void *buf, size_t size, bool registered)
+{
+#if defined(__hppa__)
+ if (registered) {
+ unsigned long off = (unsigned long) buf & 4095;
+ unsigned long p = (unsigned long) buf & ~4095;
+ int i;
+
+ size += off;
+ for (i = 0; i < size; i += 32)
+ asm volatile("fdc 0(%0)" : : "r" (p + i));
+ }
+#endif
+}
+
/*
* Each offset in the file has the offset / sizeof(int) stored for every
* sizeof(int) address.
*/
-static int verify_buf(void *buf, size_t size, off_t off)
+static int verify_buf(void *buf, size_t size, off_t off, bool registered)
{
int i, u_in_buf = size / sizeof(unsigned int);
unsigned int *ptr;
+ verify_buf_sync(buf, size, registered);
+
off /= sizeof(unsigned int);
ptr = buf;
for (i = 0; i < u_in_buf; i++) {
if (off != *ptr) {
- fprintf(stderr, "Found %u, wanted %lu\n", *ptr, off);
+ fprintf(stderr, "Found %u, wanted %llu\n", *ptr,
+ (unsigned long long) off);
return 1;
}
ptr++;
@@ -198,7 +215,7 @@ again:
goto err;
}
- if (verify_buf(buf, CHUNK_SIZE / 2, 0))
+ if (verify_buf(buf, CHUNK_SIZE / 2, 0, false))
goto err;
/*
@@ -365,9 +382,12 @@ static int test(struct io_uring *ring, const char *fname, int buffered,
v[i].iov_base = buf[i];
v[i].iov_len = CHUNK_SIZE;
}
- ret = io_uring_register_buffers(ring, v, READ_BATCH);
+ ret = t_register_buffers(ring, v, READ_BATCH);
if (ret) {
- fprintf(stderr, "Error buffer reg %d\n", ret);
+ if (ret == T_SETUP_SKIP) {
+ ret = 0;
+ goto free_bufs;
+ }
goto err;
}
}
@@ -446,12 +466,12 @@ static int test(struct io_uring *ring, const char *fname, int buffered,
void *buf = vecs[index][j].iov_base;
size_t len = vecs[index][j].iov_len;
- if (verify_buf(buf, len, voff))
+ if (verify_buf(buf, len, voff, registered))
goto err;
voff += len;
}
} else {
- if (verify_buf(buf[index], CHUNK_SIZE, voff))
+ if (verify_buf(buf[index], CHUNK_SIZE, voff, registered))
goto err;
}
}
@@ -461,6 +481,7 @@ static int test(struct io_uring *ring, const char *fname, int buffered,
done:
if (registered)
io_uring_unregister_buffers(ring);
+free_bufs:
if (vectored) {
for (j = 0; j < READ_BATCH; j++)
for (i = 0; i < nr_vecs; i++)
diff --git a/contrib/libs/liburing/test/files-exit-hang-timeout.c b/contrib/libs/liburing/test/files-exit-hang-timeout.c
index 708e42cded..a549e92cdb 100644
--- a/contrib/libs/liburing/test/files-exit-hang-timeout.c
+++ b/contrib/libs/liburing/test/files-exit-hang-timeout.c
@@ -22,9 +22,9 @@
#define PORT 9100
-struct io_uring ring;
+static struct io_uring ring;
-struct __kernel_timespec ts = {
+static struct __kernel_timespec ts = {
.tv_sec = 300,
.tv_nsec = 0,
};
diff --git a/contrib/libs/liburing/test/fixed-link.c b/contrib/libs/liburing/test/fixed-link.c
index 3e9eb8c4f1..d37788af03 100644
--- a/contrib/libs/liburing/test/fixed-link.c
+++ b/contrib/libs/liburing/test/fixed-link.c
@@ -37,7 +37,7 @@ int main(int argc, char *argv[])
for (i = 0; i < IOVECS_LEN; ++i) {
iovecs[i].iov_base = t_malloc(64);
iovecs[i].iov_len = 64;
- };
+ }
ret = io_uring_register_buffers(&ring, iovecs, IOVECS_LEN);
if (ret) {
diff --git a/contrib/libs/liburing/test/hardlink.c b/contrib/libs/liburing/test/hardlink.c
index 1d85fe0046..1bd7a1c882 100644
--- a/contrib/libs/liburing/test/hardlink.c
+++ b/contrib/libs/liburing/test/hardlink.c
@@ -45,7 +45,7 @@ err:
return 1;
}
-int files_linked_ok(const char* fn1, const char *fn2)
+static int files_linked_ok(const char* fn1, const char *fn2)
{
struct stat s1, s2;
diff --git a/contrib/libs/liburing/test/helpers.c b/contrib/libs/liburing/test/helpers.c
index a29c7b5966..7133b00b91 100644
--- a/contrib/libs/liburing/test/helpers.c
+++ b/contrib/libs/liburing/test/helpers.c
@@ -9,6 +9,7 @@
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
+#include <stdarg.h>
#include <sys/types.h>
#include <arpa/inet.h>
@@ -135,7 +136,8 @@ enum t_setup_ret t_create_ring_params(int depth, struct io_uring *ring,
return T_SETUP_SKIP;
}
- fprintf(stderr, "queue_init: %s\n", strerror(-ret));
+ if (ret != -EINVAL)
+ fprintf(stderr, "queue_init: %s\n", strerror(-ret));
return ret;
}
@@ -174,7 +176,7 @@ int t_create_socket_pair(int fd[2], bool stream)
int val;
struct sockaddr_in serv_addr;
struct sockaddr *paddr;
- size_t paddrlen;
+ socklen_t paddrlen;
type |= SOCK_CLOEXEC;
fd[0] = socket(AF_INET, type, 0);
@@ -267,3 +269,53 @@ bool t_probe_defer_taskrun(void)
io_uring_queue_exit(&ring);
return true;
}
+
+/*
+ * Sync internal state with kernel ring state on the SQ side. Returns the
+ * number of pending items in the SQ ring, for the shared ring.
+ */
+unsigned __io_uring_flush_sq(struct io_uring *ring)
+{
+ struct io_uring_sq *sq = &ring->sq;
+ unsigned tail = sq->sqe_tail;
+
+ if (sq->sqe_head != tail) {
+ sq->sqe_head = tail;
+ /*
+ * Ensure kernel sees the SQE updates before the tail update.
+ */
+ if (!(ring->flags & IORING_SETUP_SQPOLL))
+ IO_URING_WRITE_ONCE(*sq->ktail, tail);
+ else
+ io_uring_smp_store_release(sq->ktail, tail);
+ }
+ /*
+ * This _may_ look problematic, as we're not supposed to be reading
+ * SQ->head without acquire semantics. When we're in SQPOLL mode, the
+ * kernel submitter could be updating this right now. For non-SQPOLL,
+ * task itself does it, and there's no potential race. But even for
+ * SQPOLL, the load is going to be potentially out-of-date the very
+ * instant it's done, regardless or whether or not it's done
+ * atomically. Worst case, we're going to be over-estimating what
+ * we can submit. The point is, we need to be able to deal with this
+ * situation regardless of any perceived atomicity.
+ */
+ return tail - *sq->khead;
+}
+
+/*
+ * Implementation of error(3), prints an error message and exits.
+ */
+void t_error(int status, int errnum, const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+
+ vfprintf(stderr, format, args);
+ if (errnum)
+ fprintf(stderr, ": %s", strerror(errnum));
+
+ fprintf(stderr, "\n");
+ va_end(args);
+ exit(status);
+}
diff --git a/contrib/libs/liburing/test/helpers.h b/contrib/libs/liburing/test/helpers.h
index 4375a9e465..530732422c 100644
--- a/contrib/libs/liburing/test/helpers.h
+++ b/contrib/libs/liburing/test/helpers.h
@@ -85,8 +85,12 @@ enum t_setup_ret t_register_buffers(struct io_uring *ring,
bool t_probe_defer_taskrun(void);
+unsigned __io_uring_flush_sq(struct io_uring *ring);
+
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+void t_error(int status, int errnum, const char *format, ...);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/libs/liburing/test/io-cancel.c b/contrib/libs/liburing/test/io-cancel.c
index 59932ff9a4..8d769ea704 100644
--- a/contrib/libs/liburing/test/io-cancel.c
+++ b/contrib/libs/liburing/test/io-cancel.c
@@ -162,6 +162,8 @@ static int test_io_cancel(const char *file, int do_write, int do_partial,
fd = open(file, O_RDWR | O_DIRECT);
if (fd < 0) {
+ if (errno == EINVAL)
+ return T_EXIT_SKIP;
perror("file open");
goto err;
}
@@ -541,7 +543,7 @@ int main(int argc, char *argv[])
int async = (i & 4) != 0;
ret = test_io_cancel(fname, write, partial, async);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_io_cancel %d %d %d failed\n",
write, partial, async);
goto err;
diff --git a/contrib/libs/liburing/test/io_uring_passthrough.c b/contrib/libs/liburing/test/io_uring_passthrough.c
index 156347456e..ad6b6d3e5f 100644
--- a/contrib/libs/liburing/test/io_uring_passthrough.c
+++ b/contrib/libs/liburing/test/io_uring_passthrough.c
@@ -19,6 +19,7 @@
#define BUFFERS (FILE_SIZE / BS)
static struct iovec *vecs;
+static int no_pt;
/*
* Each offset in the file has the ((test_case / 2) * FILE_SIZE)
@@ -35,7 +36,8 @@ static int verify_buf(int tc, void *buf, off_t off)
ptr = buf;
for (i = 0; i < u_in_buf; i++) {
if (off != *ptr) {
- fprintf(stderr, "Found %u, wanted %lu\n", *ptr, off);
+ fprintf(stderr, "Found %u, wanted %llu\n", *ptr,
+ (unsigned long long) off);
return 1;
}
ptr++;
@@ -206,6 +208,10 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
goto err;
}
if (cqe->res != 0) {
+ if (!no_pt) {
+ no_pt = 1;
+ goto skip;
+ }
fprintf(stderr, "cqe res %d, wanted 0\n", cqe->res);
goto err;
}
@@ -235,6 +241,7 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
}
}
+skip:
close(fd);
return 0;
err:
@@ -259,6 +266,10 @@ static int test_io(const char *file, int tc, int read, int sqthread,
if (ret == T_SETUP_SKIP)
return 0;
if (ret != T_SETUP_OK) {
+ if (ret == -EINVAL) {
+ no_pt = 1;
+ return T_SETUP_SKIP;
+ }
fprintf(stderr, "ring create failed: %d\n", ret);
return 1;
}
@@ -269,8 +280,6 @@ static int test_io(const char *file, int tc, int read, int sqthread,
return ret;
}
-extern unsigned __io_uring_flush_sq(struct io_uring *ring);
-
/*
* Send a passthrough command that nvme will fail during submission.
* This comes handy for testing error handling.
@@ -283,8 +292,7 @@ static int test_invalid_passthru_submit(const char *file)
struct io_uring_sqe *sqe;
struct nvme_uring_cmd *cmd;
- ring_flags = IORING_SETUP_IOPOLL | IORING_SETUP_SQE128;
- ring_flags |= IORING_SETUP_CQE32;
+ ring_flags = IORING_SETUP_CQE32 | IORING_SETUP_SQE128;
ret = t_create_ring(1, &ring, ring_flags);
if (ret != T_SETUP_OK) {
@@ -347,6 +355,8 @@ static int test_io_uring_submit_enters(const char *file)
int fd, i, ret, ring_flags, open_flags;
unsigned head;
struct io_uring_cqe *cqe;
+ struct nvme_uring_cmd *cmd;
+ struct io_uring_sqe *sqe;
ring_flags = IORING_SETUP_IOPOLL;
ring_flags |= IORING_SETUP_SQE128;
@@ -366,12 +376,28 @@ static int test_io_uring_submit_enters(const char *file)
}
for (i = 0; i < BUFFERS; i++) {
- struct io_uring_sqe *sqe;
off_t offset = BS * (rand() % BUFFERS);
+ __u64 slba;
+ __u32 nlb;
sqe = io_uring_get_sqe(&ring);
- io_uring_prep_writev(sqe, fd, &vecs[i], 1, offset);
- sqe->user_data = 1;
+ io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
+ sqe->user_data = i;
+ sqe->opcode = IORING_OP_URING_CMD;
+ sqe->cmd_op = NVME_URING_CMD_IO;
+ cmd = (struct nvme_uring_cmd *)sqe->cmd;
+ memset(cmd, 0, sizeof(struct nvme_uring_cmd));
+
+ slba = offset >> lba_shift;
+ nlb = (BS >> lba_shift) - 1;
+
+ cmd->opcode = nvme_cmd_read;
+ cmd->cdw10 = slba & 0xffffffff;
+ cmd->cdw11 = slba >> 32;
+ cmd->cdw12 = nlb;
+ cmd->addr = (__u64)(uintptr_t)&vecs[i];
+ cmd->data_len = 1;
+ cmd->nsid = nsid;
}
/* submit manually to avoid adding IORING_ENTER_GETEVENTS */
@@ -427,6 +453,8 @@ int main(int argc, char *argv[])
int nonvec = (i & 8) != 0;
ret = test_io(fname, i, read, sqthread, fixed, nonvec);
+ if (no_pt)
+ break;
if (ret) {
fprintf(stderr, "test_io failed %d/%d/%d/%d\n",
read, sqthread, fixed, nonvec);
@@ -434,6 +462,9 @@ int main(int argc, char *argv[])
}
}
+ if (no_pt)
+ return T_EXIT_SKIP;
+
ret = test_io_uring_submit_enters(fname);
if (ret) {
fprintf(stderr, "test_io_uring_submit_enters failed\n");
diff --git a/contrib/libs/liburing/test/io_uring_register.c b/contrib/libs/liburing/test/io_uring_register.c
index b484ef4c4f..1201ffb2dc 100644
--- a/contrib/libs/liburing/test/io_uring_register.c
+++ b/contrib/libs/liburing/test/io_uring_register.c
@@ -411,7 +411,7 @@ static int ioring_poll(struct io_uring *ring, int fd, int fixed)
return 1;
}
ret = 0;
- if (cqe->res != POLLOUT) {
+ if (!(cqe->res & POLLOUT)) {
fprintf(stderr, "io_uring_wait_cqe: expected 0x%.8x, got 0x%.8x\n",
POLLOUT, cqe->res);
ret = 1;
diff --git a/contrib/libs/liburing/test/io_uring_setup.c b/contrib/libs/liburing/test/io_uring_setup.c
index 3d5a6c4bca..e0c6bcb519 100644
--- a/contrib/libs/liburing/test/io_uring_setup.c
+++ b/contrib/libs/liburing/test/io_uring_setup.c
@@ -20,86 +20,10 @@
#include "../syscall.h"
-char *features_string(struct io_uring_params *p)
-{
- static char flagstr[64];
-
- if (!p || !p->features)
- return "none";
-
- if (p->features & ~IORING_FEAT_SINGLE_MMAP) {
- snprintf(flagstr, 64, "0x%.8x", p->features);
- return flagstr;
- }
-
- if (p->features & IORING_FEAT_SINGLE_MMAP)
- strncat(flagstr, "IORING_FEAT_SINGLE_MMAP", 64 - strlen(flagstr));
-
- return flagstr;
-}
-
-/*
- * Attempt the call with the given args. Return 0 when expect matches
- * the return value of the system call, 1 otherwise.
- */
-char *
-flags_string(struct io_uring_params *p)
-{
- static char flagstr[64];
- int add_pipe = 0;
-
- memset(flagstr, 0, sizeof(flagstr));
-
- if (!p || p->flags == 0)
- return "none";
-
- /*
- * If unsupported flags are present, just print the bitmask.
- */
- if (p->flags & ~(IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL |
- IORING_SETUP_SQ_AFF)) {
- snprintf(flagstr, 64, "0x%.8x", p->flags);
- return flagstr;
- }
-
- if (p->flags & IORING_SETUP_IOPOLL) {
- strncat(flagstr, "IORING_SETUP_IOPOLL", 64 - strlen(flagstr));
- add_pipe = 1;
- }
- if (p->flags & IORING_SETUP_SQPOLL) {
- if (add_pipe)
- strncat(flagstr, "|", 64 - strlen(flagstr));
- else
- add_pipe = 1;
- strncat(flagstr, "IORING_SETUP_SQPOLL", 64 - strlen(flagstr));
- }
- if (p->flags & IORING_SETUP_SQ_AFF) {
- if (add_pipe)
- strncat(flagstr, "|", 64 - strlen(flagstr));
- strncat(flagstr, "IORING_SETUP_SQ_AFF", 64 - strlen(flagstr));
- }
-
- return flagstr;
-}
-
-char *
-dump_resv(struct io_uring_params *p)
-{
- static char resvstr[4096];
-
- if (!p)
- return "";
-
- sprintf(resvstr, "0x%.8x 0x%.8x 0x%.8x", p->resv[0],
- p->resv[1], p->resv[2]);
-
- return resvstr;
-}
-
/* bogus: setup returns a valid fd on success... expect can't predict the
fd we'll get, so this really only takes 1 parameter: error */
-int
-try_io_uring_setup(unsigned entries, struct io_uring_params *p, int expect)
+static int try_io_uring_setup(unsigned entries, struct io_uring_params *p,
+ int expect)
{
int ret;
@@ -124,8 +48,7 @@ try_io_uring_setup(unsigned entries, struct io_uring_params *p, int expect)
return 0;
}
-int
-main(int argc, char **argv)
+int main(int argc, char **argv)
{
int fd;
unsigned int status = 0;
diff --git a/contrib/libs/liburing/test/iopoll-overflow.c b/contrib/libs/liburing/test/iopoll-overflow.c
new file mode 100644
index 0000000000..96152fcfe4
--- /dev/null
+++ b/contrib/libs/liburing/test/iopoll-overflow.c
@@ -0,0 +1,119 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: IOPOLL with overflow test case
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <poll.h>
+#include <sys/eventfd.h>
+#include <sys/resource.h>
+#include "helpers.h"
+#include "liburing.h"
+#include "../src/syscall.h"
+
+#define FILE_SIZE (128 * 1024)
+#define BS 4096
+#define BUFFERS (FILE_SIZE / BS)
+
+static struct iovec *vecs;
+
+static int test(struct io_uring *ring, int fd)
+{
+ struct io_uring_sqe *sqe;
+ int i, j, ret;
+ loff_t off;
+
+ off = FILE_SIZE - BS;
+ for (j = 0; j < 8; j++) {
+ for (i = 0; i < BUFFERS; i++) {
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_read(sqe, fd, vecs[i].iov_base,
+ vecs[i].iov_len, off);
+ if (!off)
+ off = FILE_SIZE - BS;
+ else
+ off -= BS;
+ }
+ ret = io_uring_submit(ring);
+ if (ret != BUFFERS) {
+ fprintf(stderr, "submitted %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ }
+
+ sleep(1);
+
+ ret = __sys_io_uring_enter(ring->ring_fd, 0, BUFFERS * 8,
+ IORING_ENTER_GETEVENTS, NULL);
+
+ for (i = 0; i < BUFFERS * 8; i++) {
+ struct io_uring_cqe *cqe;
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait=%d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ return T_EXIT_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring_params p = { };
+ struct io_uring ring;
+ char buf[256];
+ char *fname;
+ int ret, fd;
+
+ p.flags = IORING_SETUP_IOPOLL | IORING_SETUP_CQSIZE;
+ p.cq_entries = 64;
+ ret = t_create_ring_params(64, &ring, &p);
+ if (ret == T_SETUP_SKIP)
+ return 0;
+ if (ret != T_SETUP_OK) {
+ fprintf(stderr, "ring create failed: %d\n", ret);
+ return 1;
+ }
+
+ if (argc > 1) {
+ fname = argv[1];
+ } else {
+ srand((unsigned)time(NULL));
+ snprintf(buf, sizeof(buf), ".basic-rw-%u-%u",
+ (unsigned)rand(), (unsigned)getpid());
+ fname = buf;
+ t_create_file(fname, FILE_SIZE);
+ }
+
+ fd = open(fname, O_RDONLY | O_DIRECT);
+ if (fd < 0) {
+ if (errno == EINVAL) {
+ if (fname != argv[1])
+ unlink(fname);
+ return T_EXIT_SKIP;
+ }
+ perror("open");
+ goto err;
+ }
+
+ vecs = t_create_buffers(BUFFERS, BS);
+
+ ret = test(&ring, fd);
+
+ if (fname != argv[1])
+ unlink(fname);
+ return ret;
+err:
+ if (fname != argv[1])
+ unlink(fname);
+ return T_EXIT_FAIL;
+}
diff --git a/contrib/libs/liburing/test/iopoll-overflow.t/ya.make b/contrib/libs/liburing/test/iopoll-overflow.t/ya.make
new file mode 100644
index 0000000000..e8994d965a
--- /dev/null
+++ b/contrib/libs/liburing/test/iopoll-overflow.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ iopoll-overflow.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/iopoll.c b/contrib/libs/liburing/test/iopoll.c
index dfb73265a8..b77b82d945 100644
--- a/contrib/libs/liburing/test/iopoll.c
+++ b/contrib/libs/liburing/test/iopoll.c
@@ -88,6 +88,8 @@ static int __test_io(const char *file, struct io_uring *ring, int write, int sqt
}
fd = open(file, open_flags);
if (fd < 0) {
+ if (errno == EINVAL)
+ return 0;
perror("file open");
goto err;
}
@@ -202,7 +204,80 @@ err:
return 1;
}
-extern unsigned __io_uring_flush_sq(struct io_uring *ring);
+static void sig_alrm(int sig)
+{
+ fprintf(stderr, "Ran out of time for peek test!\n");
+ exit(T_EXIT_FAIL);
+}
+
+/*
+ * if we are polling, io_uring_cqe_peek() always needs to enter the kernel
+ */
+static int test_io_uring_cqe_peek(const char *file)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring ring;
+ struct sigaction act;
+ int fd, i, ret = T_EXIT_FAIL;
+
+ if (no_iopoll)
+ return 0;
+
+ ret = io_uring_queue_init(64, &ring, IORING_SETUP_IOPOLL);
+ if (ret) {
+ fprintf(stderr, "ring create failed: %d\n", ret);
+ return 1;
+ }
+
+ fd = open(file, O_RDONLY | O_DIRECT);
+ if (fd < 0) {
+ if (errno == EINVAL) {
+ io_uring_queue_exit(&ring);
+ return T_EXIT_SKIP;
+ }
+ perror("file open");
+ goto err;
+ }
+
+ for (i = 0; i < BUFFERS; i++) {
+ struct io_uring_sqe *sqe;
+ off_t offset = BS * (rand() % BUFFERS);
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
+ sqe->user_data = 1;
+ }
+
+ /*
+ * Set alarm for 5 seconds, we should be done way before that
+ */
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = sig_alrm;
+ sigaction(SIGALRM, &act, NULL);
+ alarm(5);
+
+ ret = io_uring_submit(&ring);
+ if (ret != BUFFERS) {
+ fprintf(stderr, "submit=%d\n", ret);
+ goto err;
+ }
+
+ ret = T_EXIT_PASS;
+ i = 0;
+ do {
+ ret = io_uring_peek_cqe(&ring, &cqe);
+ if (ret)
+ continue;
+ io_uring_cqe_seen(&ring, cqe);
+ i++;
+ } while (i < BUFFERS);
+
+err:
+ if (fd != -1)
+ close(fd);
+ io_uring_queue_exit(&ring);
+ return ret;
+}
/*
* if we are polling io_uring_submit needs to always enter the
@@ -228,6 +303,8 @@ static int test_io_uring_submit_enters(const char *file)
open_flags = O_WRONLY | O_DIRECT;
fd = open(file, open_flags);
if (fd < 0) {
+ if (errno == EINVAL)
+ return T_EXIT_SKIP;
perror("file open");
goto err;
}
@@ -365,9 +442,18 @@ int main(int argc, char *argv[])
}
ret = test_io_uring_submit_enters(fname);
- if (ret) {
- fprintf(stderr, "test_io_uring_submit_enters failed\n");
- goto err;
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test_io_uring_submit_enters failed\n");
+ goto err;
+ }
+
+ /*
+ * Keep this last, it exits on failure
+ */
+ ret = test_io_uring_cqe_peek(fname);
+ if (ret == T_EXIT_FAIL) {
+ fprintf(stderr, "test_io_uring_cqe_peek failed\n");
+ goto err;
}
if (fname != argv[1])
diff --git a/contrib/libs/liburing/test/lfs-openat-write.c b/contrib/libs/liburing/test/lfs-openat-write.c
index 8e3c404de4..c2f14dc308 100644
--- a/contrib/libs/liburing/test/lfs-openat-write.c
+++ b/contrib/libs/liburing/test/lfs-openat-write.c
@@ -1,10 +1,6 @@
#include "../config-host.h"
/* SPDX-License-Identifier: MIT */
-#define _LARGEFILE_SOURCE
-#define _FILE_OFFSET_BITS 64
-
-#include <liburing.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -15,16 +11,18 @@
#include <sys/resource.h>
#include <unistd.h>
+#include "liburing.h"
#include "helpers.h"
static const int RSIZE = 2;
-static const int OPEN_FLAGS = O_RDWR | O_CREAT;
+static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE;
static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR;
-#define DIE(...) do {\
- fprintf(stderr, __VA_ARGS__);\
- abort();\
- } while(0);
+#define DIE(...) \
+ do { \
+ fprintf(stderr, __VA_ARGS__); \
+ abort(); \
+ } while(0)
static int do_write(struct io_uring *ring, int fd, off_t offset)
{
diff --git a/contrib/libs/liburing/test/lfs-openat.c b/contrib/libs/liburing/test/lfs-openat.c
index 1d93df7e4c..394a7461b4 100644
--- a/contrib/libs/liburing/test/lfs-openat.c
+++ b/contrib/libs/liburing/test/lfs-openat.c
@@ -1,9 +1,6 @@
#include "../config-host.h"
/* SPDX-License-Identifier: MIT */
-#define _LARGEFILE_SOURCE
-#define _FILE_OFFSET_BITS 64
-
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -16,13 +13,14 @@
#include "liburing.h"
-#define DIE(...) do {\
- fprintf(stderr, __VA_ARGS__);\
- abort();\
- } while(0);
+#define DIE(...) \
+ do { \
+ fprintf(stderr, __VA_ARGS__); \
+ abort(); \
+ } while(0)
static const int RSIZE = 2;
-static const int OPEN_FLAGS = O_RDWR | O_CREAT;
+static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE;
static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR;
static int open_io_uring(struct io_uring *ring, int dfd, const char *fn)
diff --git a/contrib/libs/liburing/test/link_drain.c b/contrib/libs/liburing/test/link_drain.c
index ec8021f807..3f4e4aef2c 100644
--- a/contrib/libs/liburing/test/link_drain.c
+++ b/contrib/libs/liburing/test/link_drain.c
@@ -97,7 +97,7 @@ err:
return 1;
}
-int test_link_drain_multi(struct io_uring *ring)
+static int test_link_drain_multi(struct io_uring *ring)
{
struct io_uring_cqe *cqe;
struct io_uring_sqe *sqe[9];
@@ -199,15 +199,17 @@ err:
}
-int main(int argc, char *argv[])
+static int test_drain(bool defer)
{
struct io_uring ring;
int i, ret;
+ unsigned int flags = 0;
- if (argc > 1)
- return 0;
+ if (defer)
+ flags = IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN;
- ret = io_uring_queue_init(100, &ring, 0);
+ ret = io_uring_queue_init(100, &ring, flags);
if (ret) {
printf("ring setup failed\n");
return 1;
@@ -228,3 +230,27 @@ int main(int argc, char *argv[])
return ret;
}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = test_drain(false);
+ if (ret) {
+ fprintf(stderr, "test_drain(false) failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ if (t_probe_defer_taskrun()) {
+ ret = test_drain(true);
+ if (ret) {
+ fprintf(stderr, "test_drain(true) failed\n");
+ return T_EXIT_FAIL;
+ }
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/madvise.c b/contrib/libs/liburing/test/madvise.c
index bd44a9741c..20c452c4a6 100644
--- a/contrib/libs/liburing/test/madvise.c
+++ b/contrib/libs/liburing/test/madvise.c
@@ -183,7 +183,7 @@ int main(int argc, char *argv[])
}
/* too hard to reliably test, just ignore */
- if (0 && bad > good)
+ if ((0) && bad > good)
fprintf(stderr, "Suspicious timings (%u > %u)\n", bad, good);
if (fname != argv[1])
unlink(fname);
diff --git a/contrib/libs/liburing/test/msg-ring-flags.c b/contrib/libs/liburing/test/msg-ring-flags.c
new file mode 100644
index 0000000000..d533b8f72d
--- /dev/null
+++ b/contrib/libs/liburing/test/msg-ring-flags.c
@@ -0,0 +1,193 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: test ring messaging with flags command
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+#define CUSTOM_FLAG 0x42
+#define USER_DATA 0x5aa5
+#define LEN 0x20
+#define ID 0x1
+
+struct data {
+ pthread_barrier_t barrier;
+ int fd;
+};
+
+static int recv_msg(struct io_uring *ring)
+{
+ struct io_uring_cqe *cqe;
+ int ret;
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait cqe %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ if (cqe->user_data != USER_DATA) {
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
+ return T_EXIT_FAIL;
+ }
+ if (cqe->res != LEN) {
+ fprintf(stderr, "len %x\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
+ if (cqe->flags != CUSTOM_FLAG) {
+ fprintf(stderr, "flags %x\n", cqe->flags);
+ return T_EXIT_FAIL;
+ }
+
+ return T_EXIT_PASS;
+}
+
+static int send_msg(struct io_uring *ring, int target_fd)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ int ret;
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "get sqe failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ io_uring_prep_msg_ring_cqe_flags(sqe, target_fd, LEN, USER_DATA,
+ 0, CUSTOM_FLAG);
+ sqe->user_data = ID;
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
+
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ if (cqe->res != 0) {
+ if (cqe->res == -EINVAL)
+ return T_EXIT_SKIP;
+ fprintf(stderr, "cqe res %d\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
+ if (cqe->user_data != ID) {
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
+ return T_EXIT_FAIL;
+ }
+
+ io_uring_cqe_seen(ring, cqe);
+ return T_EXIT_PASS;
+}
+
+static void *thread_fn(void *data)
+{
+ struct data *d = data;
+ struct io_uring ring;
+ int ret;
+
+ ret = io_uring_queue_init(2, &ring, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER);
+ if (ret) {
+ fprintf(stderr, "ring init failed %d\n", ret);
+ pthread_barrier_wait(&d->barrier);
+ return NULL;
+ }
+
+ d->fd = ring.ring_fd;
+ pthread_barrier_wait(&d->barrier);
+
+ if (recv_msg(&ring))
+ return (void *) 1;
+
+ return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring, ring2;
+ pthread_t thread;
+ struct data d;
+ void *ret2;
+ int ret, i;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = io_uring_queue_init(2, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "io_uring_queue_init failed for ring1: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_queue_init(2, &ring2, 0);
+ if (ret) {
+ fprintf(stderr, "io_uring_queue_init failed for ring2: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = send_msg(&ring, ring2.ring_fd);
+ if (ret) {
+ if (ret != T_EXIT_SKIP)
+ fprintf(stderr, "send_msg failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = recv_msg(&ring2);
+ if (ret) {
+ fprintf(stderr, "recv_msg failed: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < 8; i++) {
+ ret = send_msg(&ring, ring2.ring_fd);
+ if (ret) {
+ if (ret != T_EXIT_SKIP)
+ fprintf(stderr, "send_msg failed: %d\n", ret);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < 8; i++) {
+ ret = recv_msg(&ring2);
+ if (ret) {
+ fprintf(stderr, "recv_msg failed: %d\n", ret);
+ return ret;
+ }
+ }
+
+ pthread_barrier_init(&d.barrier, NULL, 2);
+ d.fd = -1;
+ pthread_create(&thread, NULL, thread_fn, &d);
+ pthread_barrier_wait(&d.barrier);
+ if (d.fd == -1)
+ return T_EXIT_FAIL;
+
+ ret = send_msg(&ring, d.fd);
+ if (ret) {
+ fprintf(stderr, "send msg failed: %d\n", ret);
+ return ret;
+ }
+ pthread_join(thread, &ret2);
+ if (ret2) {
+ fprintf(stderr, "Remote test failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/msg-ring-flags.t/ya.make b/contrib/libs/liburing/test/msg-ring-flags.t/ya.make
new file mode 100644
index 0000000000..1520ca32a0
--- /dev/null
+++ b/contrib/libs/liburing/test/msg-ring-flags.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ msg-ring-flags.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/msg-ring-overflow.c b/contrib/libs/liburing/test/msg-ring-overflow.c
new file mode 100644
index 0000000000..1a3a6ad200
--- /dev/null
+++ b/contrib/libs/liburing/test/msg-ring-overflow.c
@@ -0,0 +1,160 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: test ring messaging command
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+static int no_msg;
+
+static int test(struct io_uring *ring, unsigned dst_flags)
+{
+ struct io_uring_params p = { };
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct io_uring dst;
+ int ret, i, err_ret = T_EXIT_FAIL;
+
+ p.flags = dst_flags | IORING_SETUP_CQSIZE;
+ p.cq_entries = 4;
+ ret = io_uring_queue_init_params(4, &dst, &p);
+ if (ret) {
+ fprintf(stderr, "Destination ring create failed %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ for (i = 0; i < 8; i++) {
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "get sqe failed\n");
+ goto err;
+ }
+
+ io_uring_prep_msg_ring(sqe, dst.ring_fd, 0x10, 0x1234, 0);
+ sqe->user_data = i + 1;
+ }
+
+ ret = io_uring_submit(ring);
+ if (ret != 8) {
+ /*
+ * Likely an old kernel that doesn't support the opcode,
+ * just skip the test.
+ */
+ if (ret == 1) {
+ err_ret = T_EXIT_SKIP;
+ no_msg = 1;
+ goto err;
+ }
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
+ goto err;
+ }
+
+ for (i = 0; i < 8; i++) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ goto err;
+ }
+ switch (cqe->user_data) {
+ case 1 ... 8:
+ if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP) {
+ no_msg = 1;
+ goto out;
+ }
+ if (cqe->res != 0) {
+ fprintf(stderr, "cqe res %d\n", cqe->res);
+ goto err;
+ }
+ break;
+ case 0x1234:
+ if (cqe->res != 0x10) {
+ fprintf(stderr, "invalid len %x\n", cqe->res);
+ goto err;
+ }
+ break;
+ default:
+ fprintf(stderr, "Invalid user_data\n");
+ goto err;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ for (i = 0; i < 8; i++) {
+ ret = io_uring_wait_cqe(&dst, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ goto err;
+ }
+ switch (cqe->user_data) {
+ case 0x1234:
+ if (cqe->res != 0x10) {
+ fprintf(stderr, "invalid len %x\n", cqe->res);
+ goto err;
+ }
+ break;
+ default:
+ fprintf(stderr, "Invalid user_data\n");
+ goto err;
+ }
+ io_uring_cqe_seen(&dst, cqe);
+ }
+
+out:
+ io_uring_queue_exit(&dst);
+ return no_msg ? T_EXIT_SKIP : T_EXIT_PASS;
+err:
+ io_uring_queue_exit(&dst);
+ return err_ret;
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring src;
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = io_uring_queue_init(8, &src, 0);
+ if (ret) {
+ fprintf(stderr, "ring setup failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = test(&src, 0);
+ if (ret && !no_msg) {
+ fprintf(stderr, "test failed\n");
+ return ret;
+ }
+ if (no_msg)
+ return T_EXIT_SKIP;
+
+ ret = test(&src, IORING_SETUP_IOPOLL);
+ if (ret) {
+ fprintf(stderr, "test IOPOLL failed\n");
+ return ret;
+ }
+
+ ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER);
+ if (ret) {
+ fprintf(stderr, "test defer failed\n");
+ return ret;
+ }
+
+ ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_IOPOLL);
+ if (ret) {
+ fprintf(stderr, "test defer IOPOLL failed\n");
+ return ret;
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/msg-ring-overflow.t/ya.make b/contrib/libs/liburing/test/msg-ring-overflow.t/ya.make
new file mode 100644
index 0000000000..ab0076307f
--- /dev/null
+++ b/contrib/libs/liburing/test/msg-ring-overflow.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ msg-ring-overflow.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/msg-ring.c b/contrib/libs/liburing/test/msg-ring.c
index 079c1609d0..221fb7895a 100644
--- a/contrib/libs/liburing/test/msg-ring.c
+++ b/contrib/libs/liburing/test/msg-ring.c
@@ -94,17 +94,23 @@ static void *wait_cqe_fn(void *data)
goto err;
}
+ io_uring_cqe_seen(ring, cqe);
return NULL;
err:
+ io_uring_cqe_seen(ring, cqe);
return (void *) (unsigned long) 1;
}
static int test_remote(struct io_uring *ring, struct io_uring *target)
{
+ pthread_t thread;
+ void *tret;
struct io_uring_cqe *cqe;
struct io_uring_sqe *sqe;
int ret;
+ pthread_create(&thread, NULL, wait_cqe_fn, target);
+
sqe = io_uring_get_sqe(ring);
if (!sqe) {
fprintf(stderr, "get sqe failed\n");
@@ -135,6 +141,80 @@ static int test_remote(struct io_uring *ring, struct io_uring *target)
}
io_uring_cqe_seen(ring, cqe);
+ pthread_join(thread, &tret);
+ return 0;
+err:
+ return 1;
+}
+
+static void *remote_submit_fn(void *data)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct io_uring *target = data;
+ struct io_uring ring;
+ int ret;
+
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "thread ring setup failed: %d\n", ret);
+ goto err;
+ }
+ sqe = io_uring_get_sqe(&ring);
+ if (!sqe) {
+ fprintf(stderr, "get sqe failed\n");
+ goto err;
+ }
+
+ io_uring_prep_msg_ring(sqe, target->ring_fd, 0x20, 0x5aa5, 0);
+ sqe->user_data = 1;
+
+ ret = io_uring_submit(&ring);
+ if (ret <= 0) {
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ goto err;
+ }
+ if (cqe->res != 0 || cqe->user_data != 1) {
+ fprintf(stderr, "invalid cqe\n");
+ goto err;
+ }
+ io_uring_cqe_seen(&ring, cqe);
+ io_uring_queue_exit(&ring);
+ return NULL;
+err:
+ return (void *) (unsigned long) 1;
+}
+
+static int test_remote_submit(struct io_uring *target)
+{
+ struct io_uring_cqe *cqe;
+ pthread_t thread;
+ void *tret;
+ int ret;
+
+ pthread_create(&thread, NULL, remote_submit_fn, target);
+
+ ret = io_uring_wait_cqe(target, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ goto err;
+ }
+ if (cqe->res != 0x20) {
+ fprintf(stderr, "cqe res %d\n", cqe->res);
+ return -1;
+ }
+ if (cqe->user_data != 0x5aa5) {
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
+ return -1;
+ }
+ io_uring_cqe_seen(target, cqe);
+ pthread_join(thread, &tret);
return 0;
err:
return 1;
@@ -192,11 +272,52 @@ err:
return 1;
}
+static int test_disabled_ring(struct io_uring *ring, int flags)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct io_uring disabled_ring;
+ int ret;
+
+ flags |= IORING_SETUP_R_DISABLED;
+ ret = io_uring_queue_init(8, &disabled_ring, flags);
+ if (ret) {
+ fprintf(stderr, "ring setup failed: %d\n", ret);
+ return 1;
+ }
+
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_msg_ring(sqe, disabled_ring.ring_fd, 0x10, 0x1234, 0);
+ sqe->user_data = 1;
+
+ ret = io_uring_submit(ring);
+ if (ret != 1) {
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
+ return 1;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "wait completion %d\n", ret);
+ return 1;
+ }
+ if (cqe->res != 0 && cqe->res != -EBADFD) {
+ fprintf(stderr, "cqe res %d\n", cqe->res);
+ return 1;
+ }
+ if (cqe->user_data != 1) {
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
+ return 1;
+ }
+
+ io_uring_cqe_seen(ring, cqe);
+ io_uring_queue_exit(&disabled_ring);
+ return 0;
+}
+
int main(int argc, char *argv[])
{
struct io_uring ring, ring2, pring;
- pthread_t thread;
- void *tret;
int ret, i;
if (argc > 1)
@@ -221,41 +342,80 @@ int main(int argc, char *argv[])
ret = test_own(&ring);
if (ret) {
fprintf(stderr, "test_own failed\n");
- return ret;
+ return T_EXIT_FAIL;
}
- if (no_msg) {
- fprintf(stdout, "Skipped\n");
+ if (no_msg)
return T_EXIT_SKIP;
- }
ret = test_own(&pring);
if (ret) {
fprintf(stderr, "test_own iopoll failed\n");
- return ret;
+ return T_EXIT_FAIL;
}
ret = test_invalid(&ring, 0);
if (ret) {
fprintf(stderr, "test_invalid failed\n");
- return ret;
+ return T_EXIT_FAIL;
}
for (i = 0; i < 2; i++) {
ret = test_invalid(&ring, 1);
if (ret) {
fprintf(stderr, "test_invalid fixed failed\n");
- return ret;
+ return T_EXIT_FAIL;
}
}
- pthread_create(&thread, NULL, wait_cqe_fn, &ring2);
-
ret = test_remote(&ring, &ring2);
if (ret) {
fprintf(stderr, "test_remote failed\n");
- return ret;
+ return T_EXIT_FAIL;
}
- pthread_join(thread, &tret);
+ io_uring_queue_exit(&ring);
+ io_uring_queue_exit(&pring);
+
+ if (t_probe_defer_taskrun()) {
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN);
+ if (ret) {
+ fprintf(stderr, "deferred ring setup failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_own(&ring);
+ if (ret) {
+ fprintf(stderr, "test_own deferred failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ for (i = 0; i < 2; i++) {
+ ret = test_invalid(&ring, i);
+ if (ret) {
+ fprintf(stderr, "test_invalid(0) deferred failed\n");
+ return T_EXIT_FAIL;
+ }
+ }
+
+ ret = test_remote_submit(&ring);
+ if (ret) {
+ fprintf(stderr, "test_remote_submit failed\n");
+ return T_EXIT_FAIL;
+ }
+ io_uring_queue_exit(&ring);
+
+ if (test_disabled_ring(&ring2, 0)) {
+ fprintf(stderr, "test_disabled_ring failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ if (test_disabled_ring(&ring2, IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN)) {
+ fprintf(stderr, "test_disabled_ring defer failed\n");
+ return T_EXIT_FAIL;
+ }
+ }
+ io_uring_queue_exit(&ring2);
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/multicqes_drain.c b/contrib/libs/liburing/test/multicqes_drain.c
index 99e5fe1247..fb83441219 100644
--- a/contrib/libs/liburing/test/multicqes_drain.c
+++ b/contrib/libs/liburing/test/multicqes_drain.c
@@ -43,12 +43,16 @@ struct sqe_info {
* up an entry in multi_sqes when form a cancellation sqe.
* multi_cap: limitation of number of multishot sqes
*/
-const unsigned sqe_flags[4] = {0, IOSQE_IO_LINK, IOSQE_IO_DRAIN,
- IOSQE_IO_LINK | IOSQE_IO_DRAIN};
-int multi_sqes[max_entry], cnt = 0;
-int multi_cap = max_entry / 5;
+static const unsigned sqe_flags[4] = {
+ 0,
+ IOSQE_IO_LINK,
+ IOSQE_IO_DRAIN,
+ IOSQE_IO_LINK | IOSQE_IO_DRAIN
+};
+static int multi_sqes[max_entry], cnt = 0;
+static int multi_cap = max_entry / 5;
-int write_pipe(int pipe, char *str)
+static int write_pipe(int pipe, char *str)
{
int ret;
do {
@@ -58,7 +62,7 @@ int write_pipe(int pipe, char *str)
return ret;
}
-void read_pipe(int pipe)
+static void read_pipe(int pipe)
{
char str[4] = {0};
int ret;
@@ -68,18 +72,21 @@ void read_pipe(int pipe)
perror("read");
}
-int trigger_event(int p[])
+static int trigger_event(struct io_uring *ring, int p[])
{
int ret;
if ((ret = write_pipe(p[1], "foo")) != 3) {
fprintf(stderr, "bad write return %d\n", ret);
return 1;
}
+ usleep(1000);
+ io_uring_get_events(ring);
read_pipe(p[0]);
return 0;
}
-void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe, unsigned sqe_flags, int arg)
+static void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe,
+ unsigned sqe_flags, int arg)
{
switch (op) {
case multi:
@@ -99,7 +106,7 @@ void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe, unsigned sqe_flags, int
sqe->flags = sqe_flags;
}
-__u8 generate_flags(int sqe_op)
+static __u8 generate_flags(int sqe_op)
{
__u8 flags = 0;
/*
@@ -137,7 +144,7 @@ __u8 generate_flags(int sqe_op)
* - ensure number of multishot sqes doesn't exceed multi_cap
* - don't generate multishot sqes after high watermark
*/
-int generate_opcode(int i, int pre_flags)
+static int generate_opcode(int i, int pre_flags)
{
int sqe_op;
int high_watermark = max_entry - max_entry / 5;
@@ -164,7 +171,7 @@ static inline void add_multishot_sqe(int index)
multi_sqes[cnt++] = index;
}
-int remove_multishot_sqe()
+static int remove_multishot_sqe(void)
{
int ret;
@@ -232,10 +239,8 @@ static int test_generic_drain(struct io_uring *ring)
if (si[i].op != multi && si[i].op != single)
continue;
- if (trigger_event(pipes[i]))
+ if (trigger_event(ring, pipes[i]))
goto err;
-
- io_uring_get_events(ring);
}
sleep(1);
i = 0;
@@ -313,13 +318,11 @@ static int test_simple_drain(struct io_uring *ring)
}
for (i = 0; i < 2; i++) {
- if (trigger_event(pipe1))
+ if (trigger_event(ring, pipe1))
goto err;
- io_uring_get_events(ring);
}
- if (trigger_event(pipe2))
- goto err;
- io_uring_get_events(ring);
+ if (trigger_event(ring, pipe2))
+ goto err;
for (i = 0; i < 2; i++) {
sqe[i] = io_uring_get_sqe(ring);
diff --git a/contrib/libs/liburing/test/nvme.h b/contrib/libs/liburing/test/nvme.h
index 53ad1142a8..87abf8a64b 100644
--- a/contrib/libs/liburing/test/nvme.h
+++ b/contrib/libs/liburing/test/nvme.h
@@ -57,8 +57,8 @@ enum nvme_io_opcode {
nvme_cmd_read = 0x02,
};
-int nsid;
-__u32 lba_shift;
+static int nsid;
+static __u32 lba_shift;
struct nvme_lbaf {
__le16 ms;
@@ -120,7 +120,8 @@ static inline int ilog2(uint32_t i)
return log;
}
-int nvme_get_info(const char *file)
+__attribute__((__unused__))
+static int nvme_get_info(const char *file)
{
struct nvme_id_ns ns;
int fd, err;
diff --git a/contrib/libs/liburing/test/pipe-bug.c b/contrib/libs/liburing/test/pipe-bug.c
new file mode 100644
index 0000000000..cb45f6fa1d
--- /dev/null
+++ b/contrib/libs/liburing/test/pipe-bug.c
@@ -0,0 +1,96 @@
+#include "../config-host.h"
+// SPDX-License-Identifier: MIT
+
+/*
+ * Description: tests bug fixed in
+ * "io_uring: don't gate task_work run on TIF_NOTIFY_SIGNAL"
+ *
+ * See: https://github.com/axboe/liburing/issues/665
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "helpers.h"
+#include "liburing.h"
+
+#define CHECK(x) \
+do { \
+ if (!(x)) { \
+ fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \
+ return -1; \
+ } \
+} while (0)
+
+static int pipe_bug(void)
+{
+ struct io_uring_params p;
+ struct io_uring ring;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ char buf[1024];
+ int fds[2];
+ struct __kernel_timespec to = {
+ .tv_sec = 1
+ };
+
+ CHECK(pipe(fds) == 0);
+
+ memset(&p, 0, sizeof(p));
+ CHECK(t_create_ring_params(8, &ring, &p) == 0);
+
+ /* WRITE */
+ sqe = io_uring_get_sqe(&ring);
+ CHECK(sqe);
+ io_uring_prep_write(sqe, fds[1], "foobar", strlen("foobar"), 0); /* or -1 */
+ CHECK(io_uring_submit(&ring) == 1);
+ CHECK(io_uring_wait_cqe(&ring, &cqe) == 0);
+
+ io_uring_cqe_seen(&ring, cqe);
+
+ /* CLOSE */
+ sqe = io_uring_get_sqe(&ring);
+ CHECK(sqe);
+ io_uring_prep_close(sqe, fds[1]);
+ CHECK(io_uring_submit(&ring) == 1);
+ CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0);
+ io_uring_cqe_seen(&ring, cqe);
+
+ /* READ */
+ sqe = io_uring_get_sqe(&ring);
+ CHECK(sqe);
+ io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0); /* or -1 */
+ CHECK(io_uring_submit(&ring) == 1);
+ CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0);
+ io_uring_cqe_seen(&ring, cqe);
+ memset(buf, 0, sizeof(buf));
+
+ /* READ */
+ sqe = io_uring_get_sqe(&ring);
+ CHECK(sqe);
+ io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0); /* or -1 */
+ CHECK(io_uring_submit(&ring) == 1);
+ CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0);
+ io_uring_cqe_seen(&ring, cqe);
+
+ close(fds[0]);
+ io_uring_queue_exit(&ring);
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int i;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ for (i = 0; i < 10000; i++) {
+ if (pipe_bug())
+ return T_EXIT_FAIL;
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/pipe-bug.t/ya.make b/contrib/libs/liburing/test/pipe-bug.t/ya.make
new file mode 100644
index 0000000000..1304228eb8
--- /dev/null
+++ b/contrib/libs/liburing/test/pipe-bug.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ pipe-bug.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/poll-link.c b/contrib/libs/liburing/test/poll-link.c
index 27346c65ae..fda1182e7a 100644
--- a/contrib/libs/liburing/test/poll-link.c
+++ b/contrib/libs/liburing/test/poll-link.c
@@ -17,8 +17,8 @@
#include "helpers.h"
#include "liburing.h"
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static int recv_thread_ready = 0;
static int recv_thread_done = 0;
@@ -72,7 +72,7 @@ static void *send_thread(void *arg)
return 0;
}
-void *recv_thread(void *arg)
+static void *recv_thread(void *arg)
{
struct sockaddr_in addr = { };
struct data *data = arg;
diff --git a/contrib/libs/liburing/test/poll-many.c b/contrib/libs/liburing/test/poll-many.c
index 8f6a89efdd..fb00cf6327 100644
--- a/contrib/libs/liburing/test/poll-many.c
+++ b/contrib/libs/liburing/test/poll-many.c
@@ -15,6 +15,7 @@
#include <fcntl.h>
#include "liburing.h"
+#include "helpers.h"
#define NFILES 5000
#define BATCH 500
@@ -138,6 +139,21 @@ static int arm_polls(struct io_uring *ring)
return 0;
}
+static int do_test(struct io_uring *ring)
+{
+ int i;
+
+ if (arm_polls(ring))
+ return 1;
+
+ for (i = 0; i < NLOOPS; i++) {
+ trigger_polls();
+ if (reap_polls(ring))
+ return 1;
+ }
+ return 0;
+}
+
int main(int argc, char *argv[])
{
struct io_uring ring;
@@ -150,7 +166,7 @@ int main(int argc, char *argv[])
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
perror("getrlimit");
- goto err_noring;
+ return T_EXIT_FAIL;
}
if (rlim.rlim_cur < (2 * NFILES + 5)) {
@@ -160,14 +176,14 @@ int main(int argc, char *argv[])
if (errno == EPERM)
goto err_nofail;
perror("setrlimit");
- goto err_noring;
+ return T_EXIT_FAIL;
}
}
for (i = 0; i < NFILES; i++) {
if (pipe(p[i].fd) < 0) {
perror("pipe");
- goto err_noring;
+ return T_EXIT_FAIL;
}
}
@@ -177,31 +193,37 @@ int main(int argc, char *argv[])
if (ret) {
if (ret == -EINVAL) {
fprintf(stdout, "No CQSIZE, trying without\n");
- ret = io_uring_queue_init(RING_SIZE, &ring, 0);
+
+ params.flags &= ~IORING_SETUP_CQSIZE;
+ params.cq_entries = 0;
+ ret = io_uring_queue_init_params(RING_SIZE, &ring, &params);
if (ret) {
fprintf(stderr, "ring setup failed: %d\n", ret);
- return 1;
+ return T_EXIT_FAIL;
}
}
}
- if (arm_polls(&ring))
- goto err;
-
- for (i = 0; i < NLOOPS; i++) {
- trigger_polls();
- ret = reap_polls(&ring);
- if (ret)
- goto err;
+ if (do_test(&ring)) {
+ fprintf(stderr, "test (normal) failed\n");
+ return T_EXIT_FAIL;
}
-
io_uring_queue_exit(&ring);
+
+ if (t_probe_defer_taskrun()) {
+ params.flags |= IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN;
+ ret = io_uring_queue_init_params(RING_SIZE, &ring, &params);
+ if (ret) {
+ fprintf(stderr, "ring DEFER setup failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ if (do_test(&ring)) {
+ fprintf(stderr, "test (DEFER) failed\n");
+ return T_EXIT_FAIL;
+ }
+ io_uring_queue_exit(&ring);
+ }
return 0;
-err:
- io_uring_queue_exit(&ring);
-err_noring:
- fprintf(stderr, "poll-many failed\n");
- return 1;
err_nofail:
fprintf(stderr, "poll-many: not enough files available (and not root), "
"skipped\n");
diff --git a/contrib/libs/liburing/test/poll-mshot-overflow.c b/contrib/libs/liburing/test/poll-mshot-overflow.c
index b31633d507..94a82bd64d 100644
--- a/contrib/libs/liburing/test/poll-mshot-overflow.c
+++ b/contrib/libs/liburing/test/poll-mshot-overflow.c
@@ -13,7 +13,7 @@
#include "liburing.h"
#include "helpers.h"
-int check_final_cqe(struct io_uring *ring)
+static int check_final_cqe(struct io_uring *ring)
{
struct io_uring_cqe *cqe;
int count = 0;
@@ -138,20 +138,123 @@ static int test(bool defer_taskrun)
return ret;
}
+static int test_downgrade(bool support_defer)
+{
+ struct io_uring_cqe cqes[128];
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct io_uring ring;
+ int fds[2];
+ int ret, i, cqe_count, tmp = 0, more_cqe_count;
+
+ if (pipe(fds) != 0) {
+ perror("pipe");
+ return -1;
+ }
+
+ struct io_uring_params params = {
+ .flags = IORING_SETUP_CQSIZE,
+ .cq_entries = 2
+ };
+
+ ret = io_uring_queue_init_params(2, &ring, &params);
+ if (ret) {
+ fprintf(stderr, "queue init: %d\n", ret);
+ return -1;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ if (!sqe) {
+ fprintf(stderr, "get sqe failed\n");
+ return -1;
+ }
+ io_uring_prep_poll_multishot(sqe, fds[0], POLLIN);
+ io_uring_sqe_set_data64(sqe, 1);
+ io_uring_submit(&ring);
+
+ for (i = 0; i < 8; i++) {
+ ret = write(fds[1], &tmp, sizeof(tmp));
+ if (ret != sizeof(tmp)) {
+ perror("write");
+ return -1;
+ }
+ ret = read(fds[0], &tmp, sizeof(tmp));
+ if (ret != sizeof(tmp)) {
+ perror("read");
+ return -1;
+ }
+ }
+
+ cqe_count = 0;
+ while (!io_uring_peek_cqe(&ring, &cqe)) {
+ cqes[cqe_count++] = *cqe;
+ io_uring_cqe_seen(&ring, cqe);
+ }
+
+ /* Some kernels might allow overflows to poll,
+ * but if they didn't it should stop the MORE flag
+ */
+ if (cqe_count < 3) {
+ fprintf(stderr, "too few cqes: %d\n", cqe_count);
+ return -1;
+ } else if (cqe_count == 8) {
+ more_cqe_count = cqe_count;
+ /* downgrade only available since support_defer */
+ if (support_defer) {
+ fprintf(stderr, "did not downgrade on overflow\n");
+ return -1;
+ }
+ } else {
+ more_cqe_count = cqe_count - 1;
+ cqe = &cqes[cqe_count - 1];
+ if (cqe->flags & IORING_CQE_F_MORE) {
+ fprintf(stderr, "incorrect MORE flag %x\n", cqe->flags);
+ return -1;
+ }
+ }
+
+ for (i = 0; i < more_cqe_count; i++) {
+ cqe = &cqes[i];
+ if (!(cqe->flags & IORING_CQE_F_MORE)) {
+ fprintf(stderr, "missing MORE flag\n");
+ return -1;
+ }
+ if (cqe->res < 0) {
+ fprintf(stderr, "bad res: %d\n", cqe->res);
+ return -1;
+ }
+ }
+
+ close(fds[0]);
+ close(fds[1]);
+ io_uring_queue_exit(&ring);
+ return 0;
+}
+
int main(int argc, char *argv[])
{
int ret;
+ bool support_defer;
if (argc > 1)
return T_EXIT_SKIP;
+ support_defer = t_probe_defer_taskrun();
+ ret = test_downgrade(support_defer);
+ if (ret) {
+ fprintf(stderr, "%s: test_downgrade(%d) failed\n", argv[0], support_defer);
+ return T_EXIT_FAIL;
+ }
+
ret = test(false);
+ if (ret == T_EXIT_SKIP)
+ return ret;
if (ret != T_EXIT_PASS) {
fprintf(stderr, "%s: test(false) failed\n", argv[0]);
return ret;
}
- if (t_probe_defer_taskrun()) {
+ if (support_defer) {
ret = test(true);
if (ret != T_EXIT_PASS) {
fprintf(stderr, "%s: test(true) failed\n", argv[0]);
diff --git a/contrib/libs/liburing/test/poll-race-mshot.c b/contrib/libs/liburing/test/poll-race-mshot.c
new file mode 100644
index 0000000000..5b2755fab4
--- /dev/null
+++ b/contrib/libs/liburing/test/poll-race-mshot.c
@@ -0,0 +1,277 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: check that racing wakeups don't re-issue a poll multishot,
+ * this can leak ring provided buffers. also test if ring
+ * provided buffers for regular receive can leak if we hit a
+ * poll race.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include <sys/socket.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+#define NREQS 64
+#define BUF_SIZE 64
+
+static int no_buf_ring;
+
+struct data {
+ pthread_barrier_t barrier;
+ int fd;
+};
+
+static void *thread(void *data)
+{
+ struct data *d = data;
+ char buf[BUF_SIZE];
+ int ret, i, fd;
+
+ memset(buf, 0x5a, BUF_SIZE);
+ pthread_barrier_wait(&d->barrier);
+ fd = d->fd;
+ for (i = 0; i < NREQS; i++) {
+ ret = write(fd, buf, sizeof(buf));
+ if (ret != BUF_SIZE) {
+ if (ret < 0) {
+ perror("write");
+ printf("bad fd %d\n", fd);
+ } else
+ fprintf(stderr, "wrote short %d\n", ret);
+ }
+ }
+ return NULL;
+}
+
+static int test(struct io_uring *ring, struct data *d)
+{
+ struct io_uring_buf_ring *br;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int fd[2], ret, i;
+ pthread_t t;
+ void *buf, *ptr;
+ void *ret2;
+
+ if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd) < 0) {
+ perror("socketpair");
+ return T_EXIT_FAIL;
+ }
+
+ d->fd = fd[1];
+
+ if (posix_memalign((void **) &buf, 16384, BUF_SIZE * NREQS))
+ return T_EXIT_FAIL;
+
+ br = io_uring_setup_buf_ring(ring, NREQS, 1, 0, &ret);
+ if (!br) {
+ if (ret == -EINVAL) {
+ no_buf_ring = 1;
+ return T_EXIT_SKIP;
+ }
+ fprintf(stderr, "buf ring reg %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ptr = buf;
+ for (i = 0; i < NREQS; i++) {
+ io_uring_buf_ring_add(br, ptr, BUF_SIZE, i + 1,
+ io_uring_buf_ring_mask(NREQS), i);
+ ptr += BUF_SIZE;
+ }
+ io_uring_buf_ring_advance(br, NREQS);
+
+ pthread_create(&t, NULL, thread, d);
+
+ for (i = 0; i < NREQS; i++) {
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_recv(sqe, fd[0], NULL, 0, 0);
+ sqe->flags |= IOSQE_BUFFER_SELECT;
+ sqe->buf_group = 1;
+ }
+
+ pthread_barrier_wait(&d->barrier);
+
+ ret = io_uring_submit(ring);
+ if (ret != NREQS) {
+ fprintf(stderr, "submit %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ i = 0;
+ do {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "cqe wait %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ i++;
+ if (cqe->res != BUF_SIZE) {
+ fprintf(stderr, "Bad cqe res %d\n", cqe->res);
+ break;
+ }
+ if (cqe->flags & IORING_CQE_F_BUFFER) {
+ int bid = cqe->flags >> 16;
+
+ if (bid > NREQS) {
+ fprintf(stderr, "Bad BID %d\n", bid);
+ return T_EXIT_FAIL;
+ }
+ } else {
+ fprintf(stderr, "No BID set!\n");
+ printf("ret=%d\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ if (i > NREQS) {
+ fprintf(stderr, "Got too many requests?\n");
+ return T_EXIT_FAIL;
+ }
+ } while (i < NREQS);
+
+ pthread_join(t, &ret2);
+ free(buf);
+ io_uring_free_buf_ring(ring, br, NREQS, 1);
+ close(fd[0]);
+ close(fd[1]);
+ return T_EXIT_PASS;
+}
+
+static int test_mshot(struct io_uring *ring, struct data *d)
+{
+ struct io_uring_buf_ring *br;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int fd[2], ret, i;
+ pthread_t t;
+ void *buf, *ptr;
+ void *ret2;
+
+ if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd) < 0) {
+ perror("socketpair");
+ return T_EXIT_FAIL;
+ }
+
+ d->fd = fd[1];
+
+ if (posix_memalign((void *) &buf, 16384, BUF_SIZE * NREQS))
+ return T_EXIT_FAIL;
+
+ br = io_uring_setup_buf_ring(ring, NREQS, 1, 0, &ret);
+ if (!br) {
+ fprintf(stderr, "buf ring reg %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ptr = buf;
+ for (i = 0; i < NREQS; i++) {
+ io_uring_buf_ring_add(br, ptr, BUF_SIZE, i + 1,
+ io_uring_buf_ring_mask(NREQS), i);
+ ptr += BUF_SIZE;
+ }
+ io_uring_buf_ring_advance(br, NREQS);
+
+ pthread_create(&t, NULL, thread, d);
+
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_recv_multishot(sqe, fd[0], NULL, 0, 0);
+ sqe->flags |= IOSQE_BUFFER_SELECT;
+ sqe->buf_group = 1;
+
+ pthread_barrier_wait(&d->barrier);
+
+ ret = io_uring_submit(ring);
+ if (ret != 1) {
+ fprintf(stderr, "submit %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ i = 0;
+ do {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "cqe wait %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ i++;
+ if (!(cqe->flags & IORING_CQE_F_MORE))
+ break;
+ if (cqe->res != BUF_SIZE) {
+ fprintf(stderr, "Bad cqe res %d\n", cqe->res);
+ break;
+ }
+ if (cqe->flags & IORING_CQE_F_BUFFER) {
+ int bid = cqe->flags >> 16;
+
+ if (bid > NREQS) {
+ fprintf(stderr, "Bad BID %d\n", bid);
+ return T_EXIT_FAIL;
+ }
+ } else {
+ fprintf(stderr, "No BID set!\n");
+ printf("ret=%d\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ if (i > NREQS) {
+ fprintf(stderr, "Got too many requests?\n");
+ return T_EXIT_FAIL;
+ }
+ } while (1);
+
+ if (i != NREQS + 1) {
+ fprintf(stderr, "Only got %d requests\n", i);
+ return T_EXIT_FAIL;
+ }
+
+ pthread_join(t, &ret2);
+ io_uring_free_buf_ring(ring, br, NREQS, 1);
+ free(buf);
+ close(fd[0]);
+ close(fd[1]);
+ return T_EXIT_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring;
+ struct data d;
+ int i, ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ pthread_barrier_init(&d.barrier, NULL, 2);
+
+ for (i = 0; i < 1000; i++) {
+ io_uring_queue_init(NREQS, &ring, 0);
+ ret = test(&ring, &d);
+ if (ret != T_EXIT_PASS) {
+ if (no_buf_ring)
+ break;
+ fprintf(stderr, "Test failed loop %d\n", i);
+ return T_EXIT_FAIL;
+ }
+ io_uring_queue_exit(&ring);
+ }
+
+ if (no_buf_ring)
+ return T_EXIT_SKIP;
+
+ for (i = 0; i < 1000; i++) {
+ io_uring_queue_init(NREQS, &ring, 0);
+ ret = test_mshot(&ring, &d);
+ if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "Test mshot failed loop %d\n", i);
+ return T_EXIT_FAIL;
+ }
+ io_uring_queue_exit(&ring);
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/poll-race-mshot.t/ya.make b/contrib/libs/liburing/test/poll-race-mshot.t/ya.make
new file mode 100644
index 0000000000..14ebf80acd
--- /dev/null
+++ b/contrib/libs/liburing/test/poll-race-mshot.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ poll-race-mshot.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/poll-race.c b/contrib/libs/liburing/test/poll-race.c
new file mode 100644
index 0000000000..37e1fb92d9
--- /dev/null
+++ b/contrib/libs/liburing/test/poll-race.c
@@ -0,0 +1,106 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: check that multiple receives on the same socket don't get
+ * stalled if multiple wakers race with the socket readiness.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/socket.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+#define NREQS 64
+
+struct data {
+ pthread_barrier_t barrier;
+ int fd;
+};
+
+static void *thread(void *data)
+{
+ struct data *d = data;
+ char buf[64];
+ int ret, i;
+
+ pthread_barrier_wait(&d->barrier);
+ for (i = 0; i < NREQS; i++) {
+ ret = write(d->fd, buf, sizeof(buf));
+ if (ret != 64)
+ fprintf(stderr, "wrote short %d\n", ret);
+ }
+ return NULL;
+}
+
+static int test(struct io_uring *ring, struct data *d)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int fd[2], ret, i;
+ char buf[64];
+ pthread_t t;
+ void *ret2;
+
+ if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd) < 0) {
+ perror("socketpair");
+ return T_EXIT_FAIL;
+ }
+
+ d->fd = fd[1];
+
+ pthread_create(&t, NULL, thread, d);
+
+ for (i = 0; i < NREQS; i++) {
+ sqe = io_uring_get_sqe(ring);
+ io_uring_prep_recv(sqe, fd[0], buf, sizeof(buf), 0);
+ }
+
+ pthread_barrier_wait(&d->barrier);
+
+ ret = io_uring_submit(ring);
+ if (ret != NREQS) {
+ fprintf(stderr, "submit %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ for (i = 0; i < NREQS; i++) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "cqe wait %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ close(fd[0]);
+ close(fd[1]);
+ pthread_join(t, &ret2);
+ return T_EXIT_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring;
+ struct data d;
+ int i, ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ pthread_barrier_init(&d.barrier, NULL, 2);
+
+ io_uring_queue_init(NREQS, &ring, 0);
+
+ for (i = 0; i < 1000; i++) {
+ ret = test(&ring, &d);
+ if (ret != T_EXIT_PASS) {
+ fprintf(stderr, "Test failed\n");
+ return T_EXIT_FAIL;
+ }
+ }
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/poll-race.t/ya.make b/contrib/libs/liburing/test/poll-race.t/ya.make
new file mode 100644
index 0000000000..2333a17060
--- /dev/null
+++ b/contrib/libs/liburing/test/poll-race.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ poll-race.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/poll.c b/contrib/libs/liburing/test/poll.c
index cfba077af6..7c54e6239f 100644
--- a/contrib/libs/liburing/test/poll.c
+++ b/contrib/libs/liburing/test/poll.c
@@ -12,16 +12,27 @@
#include <signal.h>
#include <poll.h>
#include <sys/wait.h>
+#include <assert.h>
+#include "helpers.h"
#include "liburing.h"
-static void sig_alrm(int sig)
+static void do_setsockopt(int fd, int level, int optname, int val)
{
- fprintf(stderr, "Timed out!\n");
- exit(1);
+ if (setsockopt(fd, level, optname, &val, sizeof(val)))
+ t_error(1, errno, "setsockopt %d.%d: %d", level, optname, val);
}
-int main(int argc, char *argv[])
+static bool check_cq_empty(struct io_uring *ring)
+{
+ struct io_uring_cqe *cqe = NULL;
+ int ret;
+
+ ret = io_uring_peek_cqe(ring, &cqe); /* nothing should be there */
+ return ret == -EAGAIN;
+}
+
+static int test_basic(void)
{
struct io_uring_cqe *cqe;
struct io_uring_sqe *sqe;
@@ -30,34 +41,22 @@ int main(int argc, char *argv[])
pid_t p;
int ret;
- if (argc > 1)
- return 0;
-
if (pipe(pipe1) != 0) {
perror("pipe");
return 1;
}
p = fork();
- switch (p) {
- case -1:
+ if (p == -1) {
perror("fork");
exit(2);
- case 0: {
- struct sigaction act;
-
+ } else if (p == 0) {
ret = io_uring_queue_init(1, &ring, 0);
if (ret) {
fprintf(stderr, "child: ring setup failed: %d\n", ret);
return 1;
}
- memset(&act, 0, sizeof(act));
- act.sa_handler = sig_alrm;
- act.sa_flags = SA_RESTART;
- sigaction(SIGALRM, &act, NULL);
- alarm(1);
-
sqe = io_uring_get_sqe(&ring);
if (!sqe) {
fprintf(stderr, "get sqe failed\n");
@@ -93,18 +92,237 @@ int main(int argc, char *argv[])
(long) cqe->res);
return 1;
}
+
+ io_uring_queue_exit(&ring);
exit(0);
- }
- default:
- do {
- errno = 0;
- ret = write(pipe1[1], "foo", 3);
- } while (ret == -1 && errno == EINTR);
+ }
+
+ do {
+ errno = 0;
+ ret = write(pipe1[1], "foo", 3);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret != 3) {
+ fprintf(stderr, "parent: bad write return %d\n", ret);
+ return 1;
+ }
+ close(pipe1[0]);
+ close(pipe1[1]);
+ return 0;
+}
+
+static int test_missing_events(void)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct io_uring ring;
+ int i, ret, sp[2];
+ char buf[2] = {};
+ int res_mask = 0;
+
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN);
+ if (ret) {
+ fprintf(stderr, "ring setup failed: %d\n", ret);
+ return 1;
+ }
- if (ret != 3) {
- fprintf(stderr, "parent: bad write return %d\n", ret);
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) {
+ perror("Failed to create Unix-domain socket pair\n");
+ return 1;
+ }
+ do_setsockopt(sp[0], SOL_SOCKET, SO_SNDBUF, 1);
+ ret = send(sp[0], buf, sizeof(buf), 0);
+ if (ret != sizeof(buf)) {
+ perror("send failed\n");
+ return 1;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_poll_multishot(sqe, sp[0], POLLIN|POLLOUT);
+ ret = io_uring_submit(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
+ return 1;
+ }
+
+ /* trigger EPOLLIN */
+ ret = send(sp[1], buf, sizeof(buf), 0);
+ if (ret != sizeof(buf)) {
+ fprintf(stderr, "send sp[1] failed %i %i\n", ret, errno);
+ return 1;
+ }
+
+ /* trigger EPOLLOUT */
+ ret = recv(sp[1], buf, sizeof(buf), 0);
+ if (ret != sizeof(buf)) {
+ perror("recv failed\n");
+ return 1;
+ }
+
+ for (i = 0; ; i++) {
+ if (i == 0)
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ else
+ ret = io_uring_peek_cqe(&ring, &cqe);
+
+ if (i != 0 && ret == -EAGAIN) {
+ break;
+ }
+ if (ret) {
+ fprintf(stderr, "wait completion %d, %i\n", ret, i);
return 1;
}
+ res_mask |= cqe->res;
+ io_uring_cqe_seen(&ring, cqe);
+ }
+
+ if ((res_mask & (POLLIN|POLLOUT)) != (POLLIN|POLLOUT)) {
+ fprintf(stderr, "missing poll events %i\n", res_mask);
+ return 1;
+ }
+ io_uring_queue_exit(&ring);
+ close(sp[0]);
+ close(sp[1]);
+ return 0;
+}
+
+#define NR_SQES 2048
+
+static int test_self_poll(void)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct io_uring ring;
+ int ret, i, j;
+
+ ret = io_uring_queue_init(NR_SQES, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "ring setup failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ for (j = 0; j < 32; j++) {
+ for (i = 0; i < NR_SQES; i++) {
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
+ }
+
+ ret = io_uring_submit(&ring);
+ assert(ret == NR_SQES);
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_nop(sqe);
+ ret = io_uring_submit(&ring);
+ assert(ret == 1);
+
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ io_uring_cqe_seen(&ring, cqe);
+
+ io_uring_queue_exit(&ring);
+ return T_EXIT_PASS;
+}
+
+static int test_disabled_ring_lazy_polling(int early_poll)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct io_uring ring, ring2;
+ unsigned head;
+ int ret, i = 0;
+
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
+ IORING_SETUP_DEFER_TASKRUN |
+ IORING_SETUP_R_DISABLED);
+ if (ret) {
+ fprintf(stderr, "ring setup failed: %d\n", ret);
+ return 1;
+ }
+ ret = io_uring_queue_init(8, &ring2, 0);
+ if (ret) {
+ fprintf(stderr, "ring2 setup failed: %d\n", ret);
+ return 1;
+ }
+
+ if (early_poll) {
+ /* start polling disabled DEFER_TASKRUN ring */
+ sqe = io_uring_get_sqe(&ring2);
+ io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
+ ret = io_uring_submit(&ring2);
+ assert(ret == 1);
+ assert(check_cq_empty(&ring2));
+ }
+
+ /* enable rings, which should also activate pollwq */
+ ret = io_uring_enable_rings(&ring);
+ assert(ret >= 0);
+
+ if (!early_poll) {
+ /* start polling enabled DEFER_TASKRUN ring */
+ sqe = io_uring_get_sqe(&ring2);
+ io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
+ ret = io_uring_submit(&ring2);
+ assert(ret == 1);
+ assert(check_cq_empty(&ring2));
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_nop(sqe);
+ ret = io_uring_submit(&ring);
+ assert(ret == 1);
+
+ io_uring_for_each_cqe(&ring2, head, cqe) {
+ i++;
+ }
+ if (i != 1) {
+ fprintf(stderr, "fail, polling stuck\n");
+ return 1;
+ }
+ io_uring_queue_exit(&ring);
+ io_uring_queue_exit(&ring2);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ if (argc > 1)
return 0;
+
+ ret = test_basic();
+ if (ret) {
+ fprintf(stderr, "test_basic() failed %i\n", ret);
+ return T_EXIT_FAIL;
}
+
+
+ if (t_probe_defer_taskrun()) {
+ ret = test_missing_events();
+ if (ret) {
+ fprintf(stderr, "test_missing_events() failed %i\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_disabled_ring_lazy_polling(false);
+ if (ret) {
+ fprintf(stderr, "test_disabled_ring_lazy_polling(false) failed %i\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = test_disabled_ring_lazy_polling(true);
+ if (ret) {
+ fprintf(stderr, "test_disabled_ring_lazy_polling(true) failed %i\n", ret);
+ return T_EXIT_FAIL;
+ }
+ }
+
+ ret = test_self_poll();
+ if (ret) {
+ fprintf(stderr, "test_self_poll failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ return 0;
}
diff --git a/contrib/libs/liburing/test/pollfree.c b/contrib/libs/liburing/test/pollfree.c
index 4ed61e3091..20a8bec60b 100644
--- a/contrib/libs/liburing/test/pollfree.c
+++ b/contrib/libs/liburing/test/pollfree.c
@@ -253,7 +253,7 @@ static void kill_and_wait(int pid, int* status)
}
}
-static void setup_test()
+static void setup_test(void)
{
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
setpgrp();
@@ -343,7 +343,7 @@ static void loop(void)
#define __NR_io_uring_enter 426
#endif
-uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0};
+static uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0};
void execute_call(int call)
{
@@ -404,13 +404,13 @@ int main(int argc, char *argv[])
if (argc > 1)
return 0;
- ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
+ ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
if (ret == MAP_FAILED)
return 0;
- ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
+ ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
if (ret == MAP_FAILED)
return 0;
- ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
+ ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
if (ret == MAP_FAILED)
return 0;
loop();
diff --git a/contrib/libs/liburing/test/read-before-exit.c b/contrib/libs/liburing/test/read-before-exit.c
index 6510a09263..2fa632c5e1 100644
--- a/contrib/libs/liburing/test/read-before-exit.c
+++ b/contrib/libs/liburing/test/read-before-exit.c
@@ -15,6 +15,8 @@
#include "liburing.h"
#include "helpers.h"
+static int no_iopoll;
+
struct data {
struct io_uring *ring;
int timer_fd1;
@@ -23,7 +25,7 @@ struct data {
uint64_t buf2;
};
-void *submit(void *data)
+static void *submit(void *data)
{
struct io_uring_sqe *sqe;
struct data *d = data;
@@ -36,8 +38,21 @@ void *submit(void *data)
io_uring_prep_read(sqe, d->timer_fd2, &d->buf2, sizeof(d->buf2), 0);
ret = io_uring_submit(d->ring);
- if (ret != 2)
+ if (ret != 2) {
+ struct io_uring_cqe *cqe;
+
+ /*
+ * Kernels without submit-all-on-error behavior will
+ * fail submitting all, check if that's the case and
+ * don't error
+ */
+ ret = io_uring_peek_cqe(d->ring, &cqe);
+ if (!ret && cqe->res == -EOPNOTSUPP) {
+ no_iopoll = 1;
+ return NULL;
+ }
return (void *) (uintptr_t) 1;
+ }
/* Exit suddenly. */
return NULL;
@@ -96,9 +111,11 @@ int main(int argc, char *argv[])
for (i = 0; i < 1000; i++) {
ret = test(IORING_SETUP_IOPOLL);
if (ret) {
- fprintf(stderr, "Test IOPOLL failed\n");
+ fprintf(stderr, "Test IOPOLL failed loop %d\n", ret);
return ret;
}
+ if (no_iopoll)
+ break;
}
for (i = 0; i < 100; i++) {
diff --git a/contrib/libs/liburing/test/read-write.c b/contrib/libs/liburing/test/read-write.c
index 953b0afc53..2ca1fde1a4 100644
--- a/contrib/libs/liburing/test/read-write.c
+++ b/contrib/libs/liburing/test/read-write.c
@@ -77,6 +77,8 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
fd = open(file, open_flags);
if (fd < 0) {
+ if (errno == EINVAL)
+ return 0;
perror("file open");
goto err;
}
@@ -636,6 +638,53 @@ static int test_rem_buf(int batch, int sqe_flags)
return ret;
}
+static int test_rem_buf_single(int to_rem)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct io_uring ring;
+ int ret, expected;
+ int bgid = 1;
+
+ if (no_buf_select)
+ return 0;
+
+ ret = io_uring_queue_init(64, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "ring create failed: %d\n", ret);
+ return 1;
+ }
+
+ ret = provide_buffers_iovec(&ring, bgid);
+ if (ret)
+ return ret;
+
+ expected = (to_rem > BUFFERS) ? BUFFERS : to_rem;
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_remove_buffers(sqe, to_rem, bgid);
+
+ ret = io_uring_submit(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "submit: %d\n", ret);
+ return -1;
+ }
+
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait_cqe=%d\n", ret);
+ return 1;
+ }
+ if (cqe->res != expected) {
+ fprintf(stderr, "cqe->res=%d, expected=%d\n", cqe->res, expected);
+ return 1;
+ }
+ io_uring_cqe_seen(&ring, cqe);
+
+ io_uring_queue_exit(&ring);
+ return ret;
+}
+
static int test_io_link(const char *file)
{
const int nr_links = 100;
@@ -949,6 +998,12 @@ int main(int argc, char *argv[])
}
}
+ ret = test_rem_buf_single(BUFFERS + 1);
+ if (ret) {
+ fprintf(stderr, "test_rem_buf_single(BUFFERS + 1) failed\n");
+ goto err;
+ }
+
if (fname != argv[1])
unlink(fname);
return 0;
diff --git a/contrib/libs/liburing/test/recv-msgall.c b/contrib/libs/liburing/test/recv-msgall.c
index 89b12b7268..e0d94f33b1 100644
--- a/contrib/libs/liburing/test/recv-msgall.c
+++ b/contrib/libs/liburing/test/recv-msgall.c
@@ -19,14 +19,18 @@
#define MAX_MSG 128
#define HOST "127.0.0.1"
static __be16 bind_port;
+struct recv_data {
+ pthread_barrier_t barrier;
+ int use_recvmsg;
+ struct msghdr msg;
+};
static int recv_prep(struct io_uring *ring, struct iovec *iov, int *sock,
- int use_recvmsg)
+ struct recv_data *rd)
{
struct sockaddr_in saddr;
struct io_uring_sqe *sqe;
int sockfd, ret, val;
- struct msghdr msg = { };
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
@@ -48,14 +52,17 @@ static int recv_prep(struct io_uring *ring, struct iovec *iov, int *sock,
bind_port = saddr.sin_port;
sqe = io_uring_get_sqe(ring);
- if (!use_recvmsg) {
+ if (!rd->use_recvmsg) {
io_uring_prep_recv(sqe, sockfd, iov->iov_base, iov->iov_len,
MSG_WAITALL);
} else {
- msg.msg_namelen = sizeof(struct sockaddr_in);
- msg.msg_iov = iov;
- msg.msg_iovlen = 1;
- io_uring_prep_recvmsg(sqe, sockfd, &msg, MSG_WAITALL);
+ struct msghdr *msg = &rd->msg;
+
+ memset(msg, 0, sizeof(*msg));
+ msg->msg_namelen = sizeof(struct sockaddr_in);
+ msg->msg_iov = iov;
+ msg->msg_iovlen = 1;
+ io_uring_prep_recvmsg(sqe, sockfd, msg, MSG_WAITALL);
}
sqe->user_data = 2;
@@ -102,11 +109,6 @@ err:
return 1;
}
-struct recv_data {
- pthread_mutex_t mutex;
- int use_recvmsg;
-};
-
static void *recv_fn(void *data)
{
struct recv_data *rd = data;
@@ -121,20 +123,20 @@ static void *recv_fn(void *data)
ret = t_create_ring_params(1, &ring, &p);
if (ret == T_SETUP_SKIP) {
- pthread_mutex_unlock(&rd->mutex);
+ pthread_barrier_wait(&rd->barrier);
ret = 0;
goto err;
} else if (ret < 0) {
- pthread_mutex_unlock(&rd->mutex);
+ pthread_barrier_wait(&rd->barrier);
goto err;
}
- ret = recv_prep(&ring, &iov, &sock, rd->use_recvmsg);
+ ret = recv_prep(&ring, &iov, &sock, rd);
if (ret) {
fprintf(stderr, "recv_prep failed: %d\n", ret);
goto err;
}
- pthread_mutex_unlock(&rd->mutex);
+ pthread_barrier_wait(&rd->barrier);
ret = do_recv(&ring);
close(sock);
io_uring_queue_exit(&ring);
@@ -218,28 +220,24 @@ err:
static int test(int use_recvmsg)
{
- pthread_mutexattr_t attr;
pthread_t recv_thread;
struct recv_data rd;
int ret;
void *retval;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_setpshared(&attr, 1);
- pthread_mutex_init(&rd.mutex, &attr);
- pthread_mutex_lock(&rd.mutex);
+ pthread_barrier_init(&rd.barrier, NULL, 2);
rd.use_recvmsg = use_recvmsg;
ret = pthread_create(&recv_thread, NULL, recv_fn, &rd);
if (ret) {
fprintf(stderr, "Thread create failed: %d\n", ret);
- pthread_mutex_unlock(&rd.mutex);
return 1;
}
- pthread_mutex_lock(&rd.mutex);
+ pthread_barrier_wait(&rd.barrier);
do_send();
pthread_join(recv_thread, &retval);
+ pthread_barrier_destroy(&rd.barrier);
return (intptr_t)retval;
}
diff --git a/contrib/libs/liburing/test/recv-multishot.c b/contrib/libs/liburing/test/recv-multishot.c
index 67a53567b7..c80fa18547 100644
--- a/contrib/libs/liburing/test/recv-multishot.c
+++ b/contrib/libs/liburing/test/recv-multishot.c
@@ -10,6 +10,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
+#include <assert.h>
#include "liburing.h"
#include "helpers.h"
@@ -265,11 +266,19 @@ static int test(struct args *args)
bool const is_last = i == recv_cqes - 1;
+ /*
+ * Older kernels could terminate multishot early due to overflow,
+ * but later ones will not. So discriminate based on the MORE flag.
+ */
+ bool const early_last = args->early_error == ERROR_EARLY_OVERFLOW &&
+ !args->wait_each &&
+ i == N_CQE_OVERFLOW &&
+ !(cqe->flags & IORING_CQE_F_MORE);
+
bool const should_be_last =
(cqe->res <= 0) ||
(args->stream && is_last) ||
- (args->early_error == ERROR_EARLY_OVERFLOW &&
- !args->wait_each && i == N_CQE_OVERFLOW);
+ early_last;
int *this_recv;
int orig_payload_size = cqe->res;
@@ -329,7 +338,7 @@ static int test(struct args *args)
case ERROR_EARLY_LAST:
fprintf(stderr, "bad error_early\n");
goto cleanup;
- };
+ }
if (cqe->res <= 0 && cqe->flags & IORING_CQE_F_BUFFER) {
fprintf(stderr, "final BUFFER flag set\n");
@@ -462,6 +471,84 @@ cleanup:
return ret;
}
+static int test_enobuf(void)
+{
+ struct io_uring ring;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqes[16];
+ char buffs[256];
+ int ret, i, fds[2];
+
+ if (t_create_ring(8, &ring, 0) != T_SETUP_OK) {
+ fprintf(stderr, "ring create\n");
+ return -1;
+ }
+
+ ret = t_create_socket_pair(fds, false);
+ if (ret) {
+ fprintf(stderr, "t_create_socket_pair\n");
+ return ret;
+ }
+
+ sqe = io_uring_get_sqe(&ring);
+ assert(sqe);
+ /* deliberately only 2 provided buffers */
+ io_uring_prep_provide_buffers(sqe, &buffs[0], 1, 2, 0, 0);
+ io_uring_sqe_set_data64(sqe, 0);
+
+ sqe = io_uring_get_sqe(&ring);
+ assert(sqe);
+ io_uring_prep_recv_multishot(sqe, fds[0], NULL, 0, 0);
+ io_uring_sqe_set_data64(sqe, 1);
+ sqe->buf_group = 0;
+ sqe->flags |= IOSQE_BUFFER_SELECT;
+
+ ret = io_uring_submit(&ring);
+ if (ret != 2) {
+ fprintf(stderr, "bad submit %d\n", ret);
+ return -1;
+ }
+ for (i = 0; i < 3; i++) {
+ do {
+ ret = write(fds[1], "?", 1);
+ } while (ret == -1 && errno == EINTR);
+ }
+
+ ret = io_uring_wait_cqes(&ring, &cqes[0], 4, NULL, NULL);
+ if (ret) {
+ fprintf(stderr, "wait cqes\n");
+ return ret;
+ }
+
+ ret = io_uring_peek_batch_cqe(&ring, &cqes[0], 4);
+ if (ret != 4) {
+ fprintf(stderr, "peek batch cqes\n");
+ return -1;
+ }
+
+ /* provide buffers */
+ assert(cqes[0]->user_data == 0);
+ assert(cqes[0]->res == 0);
+
+ /* valid recv */
+ assert(cqes[1]->user_data == 1);
+ assert(cqes[2]->user_data == 1);
+ assert(cqes[1]->res == 1);
+ assert(cqes[2]->res == 1);
+ assert(cqes[1]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE));
+ assert(cqes[2]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE));
+
+ /* missing buffer */
+ assert(cqes[3]->user_data == 1);
+ assert(cqes[3]->res == -ENOBUFS);
+ assert(!(cqes[3]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE)));
+
+ close(fds[0]);
+ close(fds[1]);
+ io_uring_queue_exit(&ring);
+ return 0;
+}
+
int main(int argc, char *argv[])
{
int ret;
@@ -502,5 +589,11 @@ int main(int argc, char *argv[])
}
}
+ ret = test_enobuf();
+ if (ret) {
+ fprintf(stderr, "test_enobuf() failed: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
return T_EXIT_PASS;
}
diff --git a/contrib/libs/liburing/test/reg-hint.c b/contrib/libs/liburing/test/reg-hint.c
new file mode 100644
index 0000000000..fb099d8915
--- /dev/null
+++ b/contrib/libs/liburing/test/reg-hint.c
@@ -0,0 +1,57 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Test alloc hint sanity after unregistering the file table
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+int main(int argc, char *argv[])
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ struct io_uring ring;
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ io_uring_queue_init(1, &ring, 0);
+
+ ret = io_uring_register_files_sparse(&ring, 16);
+ if (ret) {
+ if (ret == -EINVAL)
+ return T_EXIT_SKIP;
+
+ fprintf(stderr, "Failed to register file table: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+ io_uring_unregister_files(&ring);
+
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_socket_direct_alloc(sqe, AF_UNIX, SOCK_DGRAM, 0, 0);
+
+ ret = io_uring_submit(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "submit %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ ret = io_uring_wait_cqe(&ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait cqe: %d\n", ret);
+ return T_EXIT_FAIL;
+ }
+
+ if (cqe->res != -ENFILE) {
+ fprintf(stderr, "Bad CQE res: %d\n", cqe->res);
+ return T_EXIT_FAIL;
+ }
+
+ io_uring_cqe_seen(&ring, cqe);
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/reg-hint.t/ya.make b/contrib/libs/liburing/test/reg-hint.t/ya.make
new file mode 100644
index 0000000000..ef01ee9b41
--- /dev/null
+++ b/contrib/libs/liburing/test/reg-hint.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ reg-hint.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/reg-reg-ring.c b/contrib/libs/liburing/test/reg-reg-ring.c
new file mode 100644
index 0000000000..2bce730027
--- /dev/null
+++ b/contrib/libs/liburing/test/reg-reg-ring.c
@@ -0,0 +1,91 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Test io_uring_register with a registered ring (IORING_REGISTER_USE_REGISTERED_RING)
+ *
+ */
+#include <stdio.h>
+
+#include "helpers.h"
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring;
+ unsigned values[2];
+ int ret;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "ring setup failed\n");
+ return T_EXIT_FAIL;
+ }
+
+ if (!(ring.features & IORING_FEAT_REG_REG_RING)) {
+ fprintf(stderr, "IORING_FEAT_REG_REG_RING not available in kernel\n");
+ io_uring_queue_exit(&ring);
+ return T_EXIT_SKIP;
+ }
+
+ ret = io_uring_close_ring_fd(&ring);
+ if (ret != -EINVAL) {
+ fprintf(stderr, "closing ring fd should EINVAL before register\n");
+ goto err;
+ }
+
+ ret = io_uring_unregister_ring_fd(&ring);
+ if (ret != -EINVAL) {
+ fprintf(stderr, "unregistering not-registered ring fd should fail\n");
+ goto err;
+ }
+
+ ret = io_uring_register_ring_fd(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "registering ring fd failed\n");
+ goto err;
+ }
+
+ ret = io_uring_register_ring_fd(&ring);
+ if (ret != -EEXIST) {
+ fprintf(stderr, "registering already-registered ring fd should fail\n");
+ goto err;
+ }
+
+ /* Test a simple io_uring_register operation expected to work.
+ * io_uring_register_iowq_max_workers is arbitrary.
+ */
+ values[0] = values[1] = 0;
+ ret = io_uring_register_iowq_max_workers(&ring, values);
+ if (ret || (values[0] == 0 && values[1] == 0)) {
+ fprintf(stderr, "io_uring_register operation failed before closing ring fd\n");
+ goto err;
+ }
+
+ ret = io_uring_close_ring_fd(&ring);
+ if (ret != 1) {
+ fprintf(stderr, "closing ring fd failed\n");
+ goto err;
+ }
+
+ values[0] = values[1] = 0;
+ ret = io_uring_register_iowq_max_workers(&ring, values);
+ if (ret || (values[0] == 0 && values[1] == 0)) {
+ fprintf(stderr, "io_uring_register operation failed after closing ring fd\n");
+ goto err;
+ }
+
+ ret = io_uring_close_ring_fd(&ring);
+ if (ret != -EBADF) {
+ fprintf(stderr, "closing already-closed ring fd should fail\n");
+ goto err;
+ }
+
+ io_uring_queue_exit(&ring);
+ return T_EXIT_PASS;
+
+err:
+ io_uring_queue_exit(&ring);
+ return T_EXIT_FAIL;
+}
diff --git a/contrib/libs/liburing/test/reg-reg-ring.t/ya.make b/contrib/libs/liburing/test/reg-reg-ring.t/ya.make
new file mode 100644
index 0000000000..ddb58c45f2
--- /dev/null
+++ b/contrib/libs/liburing/test/reg-reg-ring.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ reg-reg-ring.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/regbuf-merge.c b/contrib/libs/liburing/test/regbuf-merge.c
new file mode 100644
index 0000000000..bb2e1286cb
--- /dev/null
+++ b/contrib/libs/liburing/test/regbuf-merge.c
@@ -0,0 +1,92 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#include <endian.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "helpers.h"
+
+#ifndef __NR_io_uring_register
+#define __NR_io_uring_register 427
+#endif
+#ifndef __NR_io_uring_setup
+#define __NR_io_uring_setup 425
+#endif
+
+#define SIZEOF_IO_URING_SQE 64
+#define SIZEOF_IO_URING_CQE 16
+#define SQ_HEAD_OFFSET 0
+#define SQ_TAIL_OFFSET 64
+#define SQ_RING_MASK_OFFSET 256
+#define SQ_RING_ENTRIES_OFFSET 264
+#define SQ_FLAGS_OFFSET 276
+#define SQ_DROPPED_OFFSET 272
+#define CQ_HEAD_OFFSET 128
+#define CQ_TAIL_OFFSET 192
+#define CQ_RING_MASK_OFFSET 260
+#define CQ_RING_ENTRIES_OFFSET 268
+#define CQ_RING_OVERFLOW_OFFSET 284
+#define CQ_FLAGS_OFFSET 280
+#define CQ_CQES_OFFSET 320
+
+static long syz_io_uring_setup(volatile long a0, volatile long a1, volatile long a2, volatile long a3, volatile long a4, volatile long a5)
+{
+ uint32_t entries = (uint32_t)a0;
+ struct io_uring_params* setup_params = (struct io_uring_params*)a1;
+ void* vma1 = (void*)a2;
+ void* vma2 = (void*)a3;
+ void** ring_ptr_out = (void**)a4;
+ void** sqes_ptr_out = (void**)a5;
+ uint32_t fd_io_uring = syscall(__NR_io_uring_setup, entries, setup_params);
+ uint32_t sq_ring_sz = setup_params->sq_off.array + setup_params->sq_entries * sizeof(uint32_t);
+ uint32_t cq_ring_sz = setup_params->cq_off.cqes + setup_params->cq_entries * SIZEOF_IO_URING_CQE;
+ uint32_t ring_sz = sq_ring_sz > cq_ring_sz ? sq_ring_sz : cq_ring_sz;
+ *ring_ptr_out = mmap(vma1, ring_sz, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring, IORING_OFF_SQ_RING);
+ uint32_t sqes_sz = setup_params->sq_entries * SIZEOF_IO_URING_SQE;
+ *sqes_ptr_out = mmap(vma2, sqes_sz, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring, IORING_OFF_SQES);
+ return fd_io_uring;
+}
+
+static uint64_t r[1] = {0xffffffffffffffff};
+
+int main(int argc, char *argv[])
+{
+ intptr_t res = 0;
+
+ if (argc > 1)
+ return T_EXIT_SKIP;
+
+ mmap((void *) 0x1ffff000ul, 0x1000ul, PROT_NONE,
+ MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0ul);
+ mmap((void *) 0x20000000ul, 0x1000000ul, PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0ul);
+ mmap((void *) 0x21000000ul, 0x1000ul, PROT_NONE,
+ MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0ul);
+
+ *(uint32_t*)0x20000684 = 0;
+ *(uint32_t*)0x20000688 = 0;
+ *(uint32_t*)0x2000068c = 0;
+ *(uint32_t*)0x20000690 = 0;
+ *(uint32_t*)0x20000698 = -1;
+ memset((void*)0x2000069c, 0, 12);
+
+ res = syz_io_uring_setup(0x2fd6, 0x20000680, 0x20ffd000, 0x20ffc000,
+ 0x20000700, 0x20000740);
+ if (res != -1)
+ r[0] = res;
+
+ *(uint64_t*)0x20002840 = 0;
+ *(uint64_t*)0x20002848 = 0;
+ *(uint64_t*)0x20002850 = 0x20000840;
+ *(uint64_t*)0x20002858 = 0x1000;
+ syscall(__NR_io_uring_register, r[0], 0ul, 0x20002840ul, 2ul);
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/regbuf-merge.t/ya.make b/contrib/libs/liburing/test/regbuf-merge.t/ya.make
new file mode 100644
index 0000000000..9226844487
--- /dev/null
+++ b/contrib/libs/liburing/test/regbuf-merge.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ regbuf-merge.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/rename.c b/contrib/libs/liburing/test/rename.c
index c72a36ea1b..d11ad17b33 100644
--- a/contrib/libs/liburing/test/rename.c
+++ b/contrib/libs/liburing/test/rename.c
@@ -1,7 +1,7 @@
#include "../config-host.h"
/* SPDX-License-Identifier: MIT */
/*
- * Description: run various nop tests
+ * Description: run various rename tests
*
*/
#include <errno.h>
diff --git a/contrib/libs/liburing/test/ring-leak.c b/contrib/libs/liburing/test/ring-leak.c
index 26338a48f1..e052802314 100644
--- a/contrib/libs/liburing/test/ring-leak.c
+++ b/contrib/libs/liburing/test/ring-leak.c
@@ -242,7 +242,6 @@ int main(int argc, char *argv[])
update);
return 1;
}
- break;
}
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) != 0) {
diff --git a/contrib/libs/liburing/test/ring-leak2.c b/contrib/libs/liburing/test/ring-leak2.c
index b0b43413ef..4a33f1f440 100644
--- a/contrib/libs/liburing/test/ring-leak2.c
+++ b/contrib/libs/liburing/test/ring-leak2.c
@@ -47,7 +47,7 @@ static struct io_uring *client_ring;
static int client_eventfd = -1;
-int setup_io_uring(struct io_uring *ring)
+static int setup_io_uring(struct io_uring *ring)
{
struct io_uring_params p = { };
int ret;
diff --git a/contrib/libs/liburing/test/ringbuf-read.c b/contrib/libs/liburing/test/ringbuf-read.c
index 2eede18213..5ff6738b04 100644
--- a/contrib/libs/liburing/test/ringbuf-read.c
+++ b/contrib/libs/liburing/test/ringbuf-read.c
@@ -38,7 +38,6 @@ static int verify_buffer(char *buf, char val)
static int test(const char *filename, int dio, int async)
{
- struct io_uring_buf_reg reg = { };
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
struct io_uring ring;
@@ -53,10 +52,13 @@ static int test(const char *filename, int dio, int async)
return 1;
}
- if (dio)
+ if (dio) {
fd = open(filename, O_DIRECT | O_RDONLY);
- else
+ if (fd < 0 && errno == EINVAL)
+ return T_EXIT_SKIP;
+ } else {
fd = open(filename, O_RDONLY);
+ }
if (fd < 0) {
perror("open");
return 1;
@@ -66,15 +68,9 @@ static int test(const char *filename, int dio, int async)
if (posix_memalign((void **) &buf, 4096, FSIZE))
return 1;
- if (posix_memalign((void **) &br, 4096, 4096))
- return 1;
-
- reg.ring_addr = (unsigned long) br;
- reg.ring_entries = NR_BUFS;
- reg.bgid = 1;
- ret = io_uring_register_buf_ring(&ring, &reg, 0);
- if (ret) {
+ br = io_uring_setup_buf_ring(&ring, NR_BUFS, 1, 0, &ret);
+ if (!br) {
if (ret == -EINVAL) {
no_buf_ring = 1;
return 0;
@@ -164,7 +160,7 @@ int main(int argc, char *argv[])
close(fd);
ret = test(fname, 1, 0);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "dio test failed\n");
goto err;
}
@@ -178,13 +174,13 @@ int main(int argc, char *argv[])
}
ret = test(fname, 1, 1);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "dio async test failed\n");
goto err;
}
ret = test(fname, 0, 1);
- if (ret) {
+ if (ret == T_EXIT_FAIL) {
fprintf(stderr, "buffered async test failed\n");
goto err;
}
diff --git a/contrib/libs/liburing/test/send-zerocopy.c b/contrib/libs/liburing/test/send-zerocopy.c
index b201e68317..27300f9209 100644
--- a/contrib/libs/liburing/test/send-zerocopy.c
+++ b/contrib/libs/liburing/test/send-zerocopy.c
@@ -5,7 +5,6 @@
#include <stdint.h>
#include <assert.h>
#include <errno.h>
-#include <error.h>
#include <limits.h>
#include <fcntl.h>
#include <unistd.h>
@@ -13,7 +12,6 @@
#include <string.h>
#include <arpa/inet.h>
-#include <linux/errqueue.h>
#include <linux/if_packet.h>
#include <linux/ipv6.h>
#include <linux/socket.h>
@@ -35,16 +33,18 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/mman.h>
+#include <linux/mman.h>
#include "liburing.h"
#include "helpers.h"
#define MAX_MSG 128
-#define PORT 10200
#define HOST "127.0.0.1"
#define HOSTV6 "::1"
+#define MAX_IOV 32
#define CORK_REQS 5
#define RX_TAG 10000
#define BUFFER_OFFSET 41
@@ -58,10 +58,17 @@ enum {
BUF_T_SMALL,
BUF_T_NONALIGNED,
BUF_T_LARGE,
+ BUF_T_HUGETLB,
+
+ __BUF_NR,
};
+/* 32MB, should be enough to trigger a short send */
+#define LARGE_BUF_SIZE (1U << 25)
+
+static size_t page_sz;
static char *tx_buffer, *rx_buffer;
-static struct iovec buffers_iov[4];
+static struct iovec buffers_iov[__BUF_NR];
static bool has_sendmsg;
static bool check_cq_empty(struct io_uring *ring)
@@ -116,43 +123,72 @@ static int test_basic_send(struct io_uring *ring, int sock_tx, int sock_rx)
return T_EXIT_PASS;
}
-static int test_send_faults(struct io_uring *ring, int sock_tx, int sock_rx)
+static int test_send_faults(int sock_tx, int sock_rx)
{
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
int msg_flags = 0;
unsigned zc_flags = 0;
int payload_size = 100;
- int ret, i, nr_cqes = 2;
+ int ret, i, nr_cqes, nr_reqs = 3;
+ struct io_uring ring;
- sqe = io_uring_get_sqe(ring);
+ ret = io_uring_queue_init(32, &ring, IORING_SETUP_SUBMIT_ALL);
+ if (ret) {
+ fprintf(stderr, "queue init failed: %d\n", ret);
+ return -1;
+ }
+
+ /* invalid buffer */
+ sqe = io_uring_get_sqe(&ring);
io_uring_prep_send_zc(sqe, sock_tx, (void *)1UL, payload_size,
msg_flags, zc_flags);
sqe->user_data = 1;
- sqe = io_uring_get_sqe(ring);
+ /* invalid address */
+ sqe = io_uring_get_sqe(&ring);
io_uring_prep_send_zc(sqe, sock_tx, tx_buffer, payload_size,
msg_flags, zc_flags);
- sqe->user_data = 2;
io_uring_prep_send_set_addr(sqe, (const struct sockaddr *)1UL,
sizeof(struct sockaddr_in6));
+ sqe->user_data = 2;
- ret = io_uring_submit(ring);
- assert(ret == 2);
+ /* invalid send/recv flags */
+ sqe = io_uring_get_sqe(&ring);
+ io_uring_prep_send_zc(sqe, sock_tx, tx_buffer, payload_size,
+ msg_flags, ~0U);
+ sqe->user_data = 3;
+ ret = io_uring_submit(&ring);
+ assert(ret == nr_reqs);
+
+ nr_cqes = nr_reqs;
for (i = 0; i < nr_cqes; i++) {
- ret = io_uring_wait_cqe(ring, &cqe);
+ ret = io_uring_wait_cqe(&ring, &cqe);
assert(!ret);
- assert(cqe->user_data <= 2);
+ assert(cqe->user_data <= nr_reqs);
if (!(cqe->flags & IORING_CQE_F_NOTIF)) {
- assert(cqe->res == -EFAULT);
+ int expected = (cqe->user_data == 3) ? -EINVAL : -EFAULT;
+
+ if (cqe->res != expected) {
+ fprintf(stderr, "invalid cqe res %i vs expected %i, "
+ "user_data %i\n",
+ cqe->res, expected, (int)cqe->user_data);
+ return -1;
+ }
if (cqe->flags & IORING_CQE_F_MORE)
nr_cqes++;
+ } else {
+ if (cqe->res != 0 || cqe->flags != IORING_CQE_F_NOTIF) {
+ fprintf(stderr, "invalid notif cqe %i %i\n",
+ cqe->res, cqe->flags);
+ return -1;
+ }
}
- io_uring_cqe_seen(ring, cqe);
+ io_uring_cqe_seen(&ring, cqe);
}
- assert(check_cq_empty(ring));
+ assert(check_cq_empty(&ring));
return T_EXIT_PASS;
}
@@ -161,10 +197,9 @@ static int create_socketpair_ip(struct sockaddr_storage *addr,
bool ipv6, bool client_connect,
bool msg_zc, bool tcp)
{
- int family, addr_size;
- int ret, val;
- int listen_sock = -1;
- int sock;
+ socklen_t addr_size;
+ int family, sock, listen_sock = -1;
+ int ret;
memset(addr, 0, sizeof(*addr));
if (ipv6) {
@@ -172,14 +207,14 @@ static int create_socketpair_ip(struct sockaddr_storage *addr,
family = AF_INET6;
saddr->sin6_family = family;
- saddr->sin6_port = htons(PORT);
+ saddr->sin6_port = htons(0);
addr_size = sizeof(*saddr);
} else {
struct sockaddr_in *saddr = (struct sockaddr_in *)addr;
family = AF_INET;
saddr->sin_family = family;
- saddr->sin_port = htons(PORT);
+ saddr->sin_port = htons(0);
saddr->sin_addr.s_addr = htonl(INADDR_ANY);
addr_size = sizeof(*saddr);
}
@@ -194,16 +229,19 @@ static int create_socketpair_ip(struct sockaddr_storage *addr,
perror("socket");
return 1;
}
- val = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
- val = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
ret = bind(sock, (struct sockaddr *)addr, addr_size);
if (ret < 0) {
perror("bind");
return 1;
}
+
+ ret = getsockname(sock, (struct sockaddr *)addr, &addr_size);
+ if (ret < 0) {
+ fprintf(stderr, "getsockname failed %i\n", errno);
+ return 1;
+ }
+
if (tcp) {
ret = listen(sock, 128);
assert(ret != -1);
@@ -238,11 +276,17 @@ static int create_socketpair_ip(struct sockaddr_storage *addr,
}
}
if (msg_zc) {
- val = 1;
+#ifdef SO_ZEROCOPY
+ int val = 1;
+
if (setsockopt(*sock_client, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) {
perror("setsockopt zc");
return 1;
}
+#else
+ fprintf(stderr, "no SO_ZEROCOPY\n");
+ return 1;
+#endif
}
if (tcp) {
*sock_server = accept(listen_sock, NULL, NULL);
@@ -255,25 +299,40 @@ static int create_socketpair_ip(struct sockaddr_storage *addr,
return 0;
}
+struct send_conf {
+ bool fixed_buf;
+ bool mix_register;
+ bool cork;
+ bool force_async;
+ bool use_sendmsg;
+ bool tcp;
+ bool zc;
+ bool iovec;
+ bool long_iovec;
+ bool poll_first;
+ int buf_index;
+ struct sockaddr_storage *addr;
+};
+
static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_server,
- bool fixed_buf, struct sockaddr_storage *addr,
- bool cork, bool mix_register,
- int buf_idx, bool force_async, bool use_sendmsg)
+ struct send_conf *conf)
{
- struct iovec iov[CORK_REQS];
+ struct iovec iov[MAX_IOV];
struct msghdr msghdr[CORK_REQS];
const unsigned zc_flags = 0;
struct io_uring_sqe *sqe;
struct io_uring_cqe *cqe;
- int nr_reqs = cork ? CORK_REQS : 1;
+ int nr_reqs = conf->cork ? CORK_REQS : 1;
int i, ret, nr_cqes, addr_len = 0;
- size_t send_size = buffers_iov[buf_idx].iov_len;
+ size_t send_size = buffers_iov[conf->buf_index].iov_len;
size_t chunk_size = send_size / nr_reqs;
size_t chunk_size_last = send_size - chunk_size * (nr_reqs - 1);
- char *buf = buffers_iov[buf_idx].iov_base;
+ char *buf = buffers_iov[conf->buf_index].iov_base;
- if (addr) {
- sa_family_t fam = ((struct sockaddr_in *)addr)->sin_family;
+ assert(MAX_IOV >= CORK_REQS);
+
+ if (conf->addr) {
+ sa_family_t fam = ((struct sockaddr_in *)conf->addr)->sin_family;
addr_len = (fam == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6);
@@ -282,46 +341,87 @@ static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_se
memset(rx_buffer, 0, send_size);
for (i = 0; i < nr_reqs; i++) {
- bool real_fixed_buf = fixed_buf;
+ bool real_fixed_buf = conf->fixed_buf;
size_t cur_size = chunk_size;
int msg_flags = MSG_WAITALL;
- if (mix_register)
+ if (conf->mix_register)
real_fixed_buf = rand() & 1;
- if (cork && i != nr_reqs - 1)
+ if (i != nr_reqs - 1)
msg_flags |= MSG_MORE;
- if (i == nr_reqs - 1)
+ else
cur_size = chunk_size_last;
sqe = io_uring_get_sqe(ring);
- if (!use_sendmsg) {
- io_uring_prep_send_zc(sqe, sock_client, buf + i * chunk_size,
- cur_size, msg_flags, zc_flags);
+ if (!conf->use_sendmsg) {
+ if (conf->zc) {
+ io_uring_prep_send_zc(sqe, sock_client, buf + i * chunk_size,
+ cur_size, msg_flags, zc_flags);
+ } else {
+ io_uring_prep_send(sqe, sock_client, buf + i * chunk_size,
+ cur_size, msg_flags);
+ }
+
if (real_fixed_buf) {
sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
- sqe->buf_index = buf_idx;
+ sqe->buf_index = conf->buf_index;
}
- if (addr)
- io_uring_prep_send_set_addr(sqe, (const struct sockaddr *)addr,
+ if (conf->addr)
+ io_uring_prep_send_set_addr(sqe, (const struct sockaddr *)conf->addr,
addr_len);
} else {
- io_uring_prep_sendmsg_zc(sqe, sock_client, &msghdr[i], msg_flags);
+ struct iovec *io;
+ int iov_len;
+
+ if (conf->zc)
+ io_uring_prep_sendmsg_zc(sqe, sock_client, &msghdr[i], msg_flags);
+ else
+ io_uring_prep_sendmsg(sqe, sock_client, &msghdr[i], msg_flags);
+
+ if (!conf->iovec) {
+ io = &iov[i];
+ iov_len = 1;
+ iov[i].iov_len = cur_size;
+ iov[i].iov_base = buf + i * chunk_size;
+ } else {
+ char *it = buf;
+ int j;
+
+ assert(nr_reqs == 1);
+ iov_len = conf->long_iovec ? MAX_IOV : 4;
+ io = iov;
+
+ for (j = 0; j < iov_len; j++)
+ io[j].iov_len = 1;
+ /* first want to be easily advanced */
+ io[0].iov_base = it;
+ it += io[0].iov_len;
+ /* this should cause retry */
+ io[1].iov_len = chunk_size - iov_len + 1;
+ io[1].iov_base = it;
+ it += io[1].iov_len;
+ /* fill the rest */
+ for (j = 2; j < iov_len; j++) {
+ io[j].iov_base = it;
+ it += io[j].iov_len;
+ }
+ }
memset(&msghdr[i], 0, sizeof(msghdr[i]));
- iov[i].iov_len = cur_size;
- iov[i].iov_base = buf + i * chunk_size;
- msghdr[i].msg_iov = &iov[i];
- msghdr[i].msg_iovlen = 1;
- if (addr) {
- msghdr[i].msg_name = addr;
+ msghdr[i].msg_iov = io;
+ msghdr[i].msg_iovlen = iov_len;
+ if (conf->addr) {
+ msghdr[i].msg_name = conf->addr;
msghdr[i].msg_namelen = addr_len;
}
}
sqe->user_data = i;
- if (force_async)
+ if (conf->force_async)
sqe->flags |= IOSQE_ASYNC;
+ if (conf->poll_first)
+ sqe->ioprio |= IORING_RECVSEND_POLL_FIRST;
if (i != nr_reqs - 1)
sqe->flags |= IOSQE_IO_LINK;
}
@@ -336,7 +436,7 @@ static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_se
return 1;
}
- nr_cqes = 2 * nr_reqs + 1;
+ nr_cqes = nr_reqs + 1;
for (i = 0; i < nr_cqes; i++) {
int expected = chunk_size;
@@ -347,19 +447,26 @@ static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_se
}
if (cqe->user_data == RX_TAG) {
if (cqe->res != send_size) {
- fprintf(stderr, "rx failed %i\n", cqe->res);
+ fprintf(stderr, "rx failed res: %i, expected %i\n",
+ cqe->res, (int)send_size);
return 1;
}
io_uring_cqe_seen(ring, cqe);
continue;
}
-
+ if ((cqe->flags & IORING_CQE_F_MORE) && (cqe->flags & IORING_CQE_F_NOTIF)) {
+ fprintf(stderr, "unexpected cflags %i res %i\n",
+ cqe->flags, cqe->res);
+ return 1;
+ }
if (cqe->user_data >= nr_reqs) {
fprintf(stderr, "invalid user_data %lu\n",
(unsigned long)cqe->user_data);
return 1;
}
if (!(cqe->flags & IORING_CQE_F_NOTIF)) {
+ if (cqe->flags & IORING_CQE_F_MORE)
+ nr_cqes++;
if (cqe->user_data == nr_reqs - 1)
expected = chunk_size_last;
if (cqe->res != expected) {
@@ -368,12 +475,6 @@ static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_se
return 1;
}
}
- if ((cqe->flags & IORING_CQE_F_MORE) ==
- (cqe->flags & IORING_CQE_F_NOTIF)) {
- fprintf(stderr, "unexpected cflags %i res %i\n",
- cqe->flags, cqe->res);
- return 1;
- }
io_uring_cqe_seen(ring, cqe);
}
@@ -389,57 +490,96 @@ static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_se
static int test_inet_send(struct io_uring *ring)
{
+ struct send_conf conf;
struct sockaddr_storage addr;
int sock_client = -1, sock_server = -1;
int ret, j, i;
+ int buf_index;
- for (j = 0; j < 16; j++) {
+ for (j = 0; j < 32; j++) {
bool ipv6 = j & 1;
bool client_connect = j & 2;
bool msg_zc_set = j & 4;
bool tcp = j & 8;
+ bool swap_sockets = j & 16;
if (tcp && !client_connect)
continue;
-
+ if (swap_sockets && !tcp)
+ continue;
+#ifndef SO_ZEROCOPY
+ if (msg_zc_set)
+ continue;
+#endif
ret = create_socketpair_ip(&addr, &sock_client, &sock_server, ipv6,
client_connect, msg_zc_set, tcp);
if (ret) {
fprintf(stderr, "sock prep failed %d\n", ret);
return 1;
}
+ if (swap_sockets) {
+ int tmp_sock = sock_client;
- for (i = 0; i < 256; i++) {
- int buf_flavour = i & 3;
- bool fixed_buf = i & 4;
- struct sockaddr_storage *addr_arg = (i & 8) ? &addr : NULL;
- bool cork = i & 16;
- bool mix_register = i & 32;
- bool force_async = i & 64;
- bool use_sendmsg = i & 128;
+ sock_client = sock_server;
+ sock_server = tmp_sock;
+ }
- if (buf_flavour == BUF_T_LARGE && !tcp)
+ for (i = 0; i < 1024; i++) {
+ bool regbuf;
+
+ conf.use_sendmsg = i & 1;
+ conf.poll_first = i & 2;
+ conf.fixed_buf = i & 4;
+ conf.addr = (i & 8) ? &addr : NULL;
+ conf.cork = i & 16;
+ conf.mix_register = i & 32;
+ conf.force_async = i & 64;
+ conf.zc = i & 128;
+ conf.iovec = i & 256;
+ conf.long_iovec = i & 512;
+ conf.tcp = tcp;
+ regbuf = conf.mix_register || conf.fixed_buf;
+
+ if (conf.iovec && (!conf.use_sendmsg || regbuf || conf.cork))
continue;
- if (!buffers_iov[buf_flavour].iov_base)
+ if (!conf.zc) {
+ if (regbuf)
+ continue;
+ /*
+ * Non zerocopy send w/ addr was added together with sendmsg_zc,
+ * skip if we the kernel doesn't support it.
+ */
+ if (conf.addr && !has_sendmsg)
+ continue;
+ }
+ if (tcp && (conf.cork || conf.addr))
continue;
- if (tcp && (cork || addr_arg))
+ if (conf.mix_register && (!conf.cork || conf.fixed_buf))
continue;
- if (mix_register && (!cork || fixed_buf))
+ if (!client_connect && conf.addr == NULL)
continue;
- if (!client_connect && addr_arg == NULL)
+ if (conf.use_sendmsg && (regbuf || !has_sendmsg))
continue;
- if (use_sendmsg && (mix_register || fixed_buf || !has_sendmsg))
+ if (msg_zc_set && !conf.zc)
continue;
- ret = do_test_inet_send(ring, sock_client, sock_server, fixed_buf,
- addr_arg, cork, mix_register,
- buf_flavour, force_async, use_sendmsg);
- if (ret) {
- fprintf(stderr, "send failed fixed buf %i, conn %i, addr %i, "
- "cork %i\n",
- fixed_buf, client_connect, !!addr_arg,
- cork);
- return 1;
+ for (buf_index = 0; buf_index < ARRAY_SIZE(buffers_iov); buf_index++) {
+ size_t len = buffers_iov[buf_index].iov_len;
+
+ if (!buffers_iov[buf_index].iov_base)
+ continue;
+ if (!tcp && len > 4 * page_sz)
+ continue;
+
+ conf.buf_index = buf_index;
+ ret = do_test_inet_send(ring, sock_client, sock_server, &conf);
+ if (ret) {
+ fprintf(stderr, "send failed fixed buf %i, "
+ "conn %i, addr %i, cork %i\n",
+ conf.fixed_buf, client_connect,
+ !!conf.addr, conf.cork);
+ return 1;
+ }
}
}
@@ -589,6 +729,8 @@ int main(int argc, char *argv[])
if (argc > 1)
return T_EXIT_SKIP;
+ page_sz = sysconf(_SC_PAGESIZE);
+
/* create TCP IPv6 pair */
ret = create_socketpair_ip(&addr, &sp[0], &sp[1], true, true, false, true);
if (ret) {
@@ -596,30 +738,54 @@ int main(int argc, char *argv[])
return T_EXIT_FAIL;
}
- len = 1U << 25; /* 32MB, should be enough to trigger a short send */
- tx_buffer = aligned_alloc(4096, len);
- rx_buffer = aligned_alloc(4096, len);
+ len = LARGE_BUF_SIZE;
+ tx_buffer = aligned_alloc(page_sz, len);
+ rx_buffer = aligned_alloc(page_sz, len);
if (tx_buffer && rx_buffer) {
buffers_iov[BUF_T_LARGE].iov_base = tx_buffer;
buffers_iov[BUF_T_LARGE].iov_len = len;
} else {
+ if (tx_buffer)
+ free(tx_buffer);
+ if (rx_buffer)
+ free(rx_buffer);
+
printf("skip large buffer tests, can't alloc\n");
- len = 8192;
- tx_buffer = aligned_alloc(4096, len);
- rx_buffer = aligned_alloc(4096, len);
+ len = 2 * page_sz;
+ tx_buffer = aligned_alloc(page_sz, len);
+ rx_buffer = aligned_alloc(page_sz, len);
}
if (!tx_buffer || !rx_buffer) {
fprintf(stderr, "can't allocate buffers\n");
return T_EXIT_FAIL;
}
- buffers_iov[BUF_T_NORMAL].iov_base = tx_buffer + 4096;
- buffers_iov[BUF_T_NORMAL].iov_len = 4096;
+ srand((unsigned)time(NULL));
+ for (i = 0; i < len; i++)
+ tx_buffer[i] = i;
+ memset(rx_buffer, 0, len);
+
+ buffers_iov[BUF_T_NORMAL].iov_base = tx_buffer + page_sz;
+ buffers_iov[BUF_T_NORMAL].iov_len = page_sz;
buffers_iov[BUF_T_SMALL].iov_base = tx_buffer;
buffers_iov[BUF_T_SMALL].iov_len = 137;
buffers_iov[BUF_T_NONALIGNED].iov_base = tx_buffer + BUFFER_OFFSET;
- buffers_iov[BUF_T_NONALIGNED].iov_len = 8192 - BUFFER_OFFSET - 13;
+ buffers_iov[BUF_T_NONALIGNED].iov_len = 2 * page_sz - BUFFER_OFFSET - 13;
+
+ if (len == LARGE_BUF_SIZE) {
+ void *huge_page;
+ int off = page_sz + 27;
+
+ len = 1U << 22;
+ huge_page = mmap(NULL, len, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE | MAP_HUGETLB | MAP_HUGE_2MB | MAP_ANONYMOUS,
+ -1, 0);
+ if (huge_page != MAP_FAILED) {
+ buffers_iov[BUF_T_HUGETLB].iov_base = huge_page + off;
+ buffers_iov[BUF_T_HUGETLB].iov_len = len - off;
+ }
+ }
ret = io_uring_queue_init(32, &ring, 0);
if (ret) {
@@ -627,11 +793,6 @@ int main(int argc, char *argv[])
return T_EXIT_FAIL;
}
- srand((unsigned)time(NULL));
- for (i = 0; i < len; i++)
- tx_buffer[i] = i;
- memset(rx_buffer, 0, len);
-
ret = test_basic_send(&ring, sp[0], sp[1]);
if (ret == T_EXIT_SKIP)
return ret;
@@ -642,7 +803,7 @@ int main(int argc, char *argv[])
has_sendmsg = io_check_zc_sendmsg(&ring);
- ret = test_send_faults(&ring, sp[0], sp[1]);
+ ret = test_send_faults(sp[0], sp[1]);
if (ret) {
fprintf(stderr, "test_send_faults() failed\n");
return T_EXIT_FAIL;
@@ -672,6 +833,15 @@ int main(int argc, char *argv[])
return T_EXIT_FAIL;
}
+ if (buffers_iov[BUF_T_HUGETLB].iov_base) {
+ buffers_iov[BUF_T_HUGETLB].iov_base += 13;
+ buffers_iov[BUF_T_HUGETLB].iov_len -= 26;
+ }
+ if (buffers_iov[BUF_T_LARGE].iov_base) {
+ buffers_iov[BUF_T_LARGE].iov_base += 13;
+ buffers_iov[BUF_T_LARGE].iov_len -= 26;
+ }
+
ret = test_inet_send(&ring);
if (ret) {
fprintf(stderr, "test_inet_send() failed\n");
diff --git a/contrib/libs/liburing/test/send_recv.c b/contrib/libs/liburing/test/send_recv.c
index 5200494a6c..05b2ffa902 100644
--- a/contrib/libs/liburing/test/send_recv.c
+++ b/contrib/libs/liburing/test/send_recv.c
@@ -193,13 +193,13 @@ static int do_send(void)
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket");
- return 1;
+ goto err2;
}
ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret < 0) {
perror("connect");
- return 1;
+ goto err;
}
sqe = io_uring_get_sqe(&ring);
@@ -215,8 +215,7 @@ static int do_send(void)
ret = io_uring_wait_cqe(&ring, &cqe);
if (cqe->res == -EINVAL) {
fprintf(stdout, "send not supported, skipping\n");
- close(sockfd);
- return 0;
+ goto err;
}
if (cqe->res != iov.iov_len) {
fprintf(stderr, "failed cqe: %d\n", cqe->res);
@@ -224,9 +223,13 @@ static int do_send(void)
}
close(sockfd);
+ io_uring_queue_exit(&ring);
return 0;
+
err:
close(sockfd);
+err2:
+ io_uring_queue_exit(&ring);
return 1;
}
diff --git a/contrib/libs/liburing/test/send_recvmsg.c b/contrib/libs/liburing/test/send_recvmsg.c
index da64a0fb06..bea40c0796 100644
--- a/contrib/libs/liburing/test/send_recvmsg.c
+++ b/contrib/libs/liburing/test/send_recvmsg.c
@@ -185,22 +185,11 @@ static void *recv_fn(void *data)
if ((rd->buf_ring || rd->buf_select) && !rd->no_buf_add) {
if (rd->buf_ring) {
- struct io_uring_buf_reg reg = { };
- void *ptr;
-
- if (posix_memalign(&ptr, 4096, 4096))
- goto err;
-
- reg.ring_addr = (unsigned long) ptr;
- reg.ring_entries = 1;
- reg.bgid = BUF_BGID;
- if (io_uring_register_buf_ring(&ring, &reg, 0)) {
+ br = io_uring_setup_buf_ring(&ring, 1, BUF_BGID, 0, &ret);
+ if (!br) {
no_pbuf_ring = 1;
goto out;
}
-
- br = ptr;
- io_uring_buf_ring_init(br);
io_uring_buf_ring_add(br, buf, sizeof(buf), BUF_BID,
io_uring_buf_ring_mask(1), 0);
io_uring_buf_ring_advance(br, 1);
@@ -247,9 +236,9 @@ static void *recv_fn(void *data)
ret = do_recvmsg(&ring, buf, rd);
close(sockfd);
- io_uring_queue_exit(&ring);
if (br)
- free(br);
+ io_uring_free_buf_ring(&ring, br, 1, BUF_BGID);
+ io_uring_queue_exit(&ring);
err:
return (void *)(intptr_t)ret;
out:
@@ -257,7 +246,7 @@ out:
out_no_ring:
pthread_mutex_unlock(mutex);
if (br)
- free(br);
+ io_uring_free_buf_ring(&ring, br, 1, BUF_BGID);
return NULL;
}
diff --git a/contrib/libs/liburing/test/sendmsg_fs_cve.c b/contrib/libs/liburing/test/sendmsg_fs_cve.c
index 3829a5c085..786e7dc551 100644
--- a/contrib/libs/liburing/test/sendmsg_fs_cve.c
+++ b/contrib/libs/liburing/test/sendmsg_fs_cve.c
@@ -1,5 +1,5 @@
#include "../config-host.h"
-/* SPDX-License-Identifier: MIT */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* repro-CVE-2020-29373 -- Reproducer for CVE-2020-29373.
*
@@ -17,7 +17,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <unistd.h>
diff --git a/contrib/libs/liburing/test/sendmsg_fs_cve.t/ya.make b/contrib/libs/liburing/test/sendmsg_fs_cve.t/ya.make
index cb23a9fe65..94e6887afa 100644
--- a/contrib/libs/liburing/test/sendmsg_fs_cve.t/ya.make
+++ b/contrib/libs/liburing/test/sendmsg_fs_cve.t/ya.make
@@ -2,10 +2,15 @@
PROGRAM()
-LICENSE(GPL-2.0-or-later)
+LICENSE(
+ GPL-2.0-or-later AND
+ GPL-3.0-or-later
+)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
+WITHOUT_LICENSE_TEXTS()
+
PEERDIR(
contrib/libs/liburing
)
diff --git a/contrib/libs/liburing/test/single-issuer.c b/contrib/libs/liburing/test/single-issuer.c
index 22f104e94e..7d12fc1b17 100644
--- a/contrib/libs/liburing/test/single-issuer.c
+++ b/contrib/libs/liburing/test/single-issuer.c
@@ -6,7 +6,6 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
-#include <error.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -57,13 +56,13 @@ static int try_submit(struct io_uring *ring)
return ret;
if (ret != 1)
- error(1, ret, "submit %i", ret);
+ t_error(1, ret, "submit %i", ret);
ret = io_uring_wait_cqe(ring, &cqe);
if (ret)
- error(1, ret, "wait fail %i", ret);
+ t_error(1, ret, "wait fail %i", ret);
if (cqe->res || cqe->user_data != 42)
- error(1, ret, "invalid cqe");
+ t_error(1, ret, "invalid cqe");
io_uring_cqe_seen(ring, cqe);
return 0;
@@ -79,7 +78,6 @@ int main(int argc, char *argv[])
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER);
if (ret == -EINVAL) {
- fprintf(stderr, "SETUP_SINGLE_ISSUER is not supported, skip\n");
return T_EXIT_SKIP;
} else if (ret) {
fprintf(stderr, "io_uring_queue_init() failed %i\n", ret);
@@ -107,7 +105,7 @@ int main(int argc, char *argv[])
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
IORING_SETUP_R_DISABLED);
if (ret)
- error(1, ret, "ring init (2) %i", ret);
+ t_error(1, ret, "ring init (2) %i", ret);
if (!fork_t()) {
io_uring_enable_rings(&ring);
@@ -123,7 +121,7 @@ int main(int argc, char *argv[])
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
IORING_SETUP_R_DISABLED);
if (ret)
- error(1, ret, "ring init (3) %i", ret);
+ t_error(1, ret, "ring init (3) %i", ret);
io_uring_enable_rings(&ring);
if (!fork_t()) {
@@ -138,7 +136,7 @@ int main(int argc, char *argv[])
/* test that anyone can submit to a SQPOLL|SINGLE_ISSUER ring */
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_SQPOLL);
if (ret)
- error(1, ret, "ring init (4) %i", ret);
+ t_error(1, ret, "ring init (4) %i", ret);
ret = try_submit(&ring);
if (ret) {
@@ -158,7 +156,7 @@ int main(int argc, char *argv[])
/* test that IORING_ENTER_REGISTERED_RING doesn't break anything */
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER);
if (ret)
- error(1, ret, "ring init (5) %i", ret);
+ t_error(1, ret, "ring init (5) %i", ret);
if (!fork_t()) {
ret = try_submit(&ring);
diff --git a/contrib/libs/liburing/test/skip-cqe.c b/contrib/libs/liburing/test/skip-cqe.c
index c73e2b8dea..87010a4ca0 100644
--- a/contrib/libs/liburing/test/skip-cqe.c
+++ b/contrib/libs/liburing/test/skip-cqe.c
@@ -9,6 +9,7 @@
#include <assert.h>
#include "liburing.h"
+#include "helpers.h"
#define LINK_SIZE 6
#define TIMEOUT_USER_DATA (-1)
@@ -324,10 +325,8 @@ int main(int argc, char *argv[])
return 1;
}
- if (!(ring.features & IORING_FEAT_CQE_SKIP)) {
- printf("IOSQE_CQE_SKIP_SUCCESS is not supported, skip\n");
- return 0;
- }
+ if (!(ring.features & IORING_FEAT_CQE_SKIP))
+ return T_EXIT_SKIP;
for (i = 0; i < 4; i++) {
bool skip_last = i & 1;
diff --git a/contrib/libs/liburing/test/socket.c b/contrib/libs/liburing/test/socket.c
index c3250c8dc0..b4514e3154 100644
--- a/contrib/libs/liburing/test/socket.c
+++ b/contrib/libs/liburing/test/socket.c
@@ -273,7 +273,6 @@ static int do_send(int socket_direct, int alloc)
}
if (cqe->res < 0) {
if (cqe->res == -EINVAL) {
- fprintf(stdout, "No socket support, skipping\n");
no_socket = 1;
io_uring_cqe_seen(&ring, cqe);
return fallback_send(&ring, &saddr);
diff --git a/contrib/libs/liburing/test/sq-poll-dup.c b/contrib/libs/liburing/test/sq-poll-dup.c
index bbeb63e6cb..a821f21962 100644
--- a/contrib/libs/liburing/test/sq-poll-dup.c
+++ b/contrib/libs/liburing/test/sq-poll-dup.c
@@ -172,14 +172,21 @@ int main(int argc, char *argv[])
vecs = t_create_buffers(BUFFERS, BS);
fd = open(fname, O_RDONLY | O_DIRECT);
- if (fname != argv[1])
- unlink(fname);
-
if (fd < 0) {
+ int __e = errno;
+
+ if (fname != argv[1])
+ unlink(fname);
+
+ if (__e == EINVAL)
+ return T_EXIT_SKIP;
perror("open");
return -1;
}
+ if (fname != argv[1])
+ unlink(fname);
+
ret = test(fd, 0, 0);
if (ret) {
fprintf(stderr, "test 0 0 failed\n");
diff --git a/contrib/libs/liburing/test/sq-poll-kthread.c b/contrib/libs/liburing/test/sq-poll-kthread.c
index 4ec43a9323..f4d4801816 100644
--- a/contrib/libs/liburing/test/sq-poll-kthread.c
+++ b/contrib/libs/liburing/test/sq-poll-kthread.c
@@ -118,7 +118,7 @@ err_pipe:
return ret;
}
-int test_sq_poll_kthread_stopped(bool do_exit)
+static int test_sq_poll_kthread_stopped(bool do_exit)
{
pid_t pid;
int status = 0;
diff --git a/contrib/libs/liburing/test/sq-poll-share.c b/contrib/libs/liburing/test/sq-poll-share.c
index a2af97543f..c8a72107f9 100644
--- a/contrib/libs/liburing/test/sq-poll-share.c
+++ b/contrib/libs/liburing/test/sq-poll-share.c
@@ -90,13 +90,14 @@ int main(int argc, char *argv[])
vecs = t_create_buffers(BUFFERS, BS);
fd = open(fname, O_RDONLY | O_DIRECT);
- if (fname != argv[1])
- unlink(fname);
if (fd < 0) {
perror("open");
return -1;
}
+ if (fname != argv[1])
+ unlink(fname);
+
for (i = 0; i < NR_RINGS; i++) {
struct io_uring_params p = { };
diff --git a/contrib/libs/liburing/test/sqpoll-cancel-hang.c b/contrib/libs/liburing/test/sqpoll-cancel-hang.c
index 81a30e27de..302a662bcd 100644
--- a/contrib/libs/liburing/test/sqpoll-cancel-hang.c
+++ b/contrib/libs/liburing/test/sqpoll-cancel-hang.c
@@ -10,8 +10,16 @@
#include <time.h>
#include <unistd.h>
#include "liburing.h"
+#include "helpers.h"
#include "../src/syscall.h"
+/*
+ * This syzbot test is known broken on some archs, just allow the ones that
+ * are regularly tested.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
+ defined(__aarch64__)
+
static uint64_t current_time_ms(void)
{
struct timespec ts;
@@ -40,7 +48,7 @@ static void kill_and_wait(int pid, int* status)
#define WAIT_FLAGS __WALL
-uint64_t r[3] = {0xffffffffffffffff, 0x0, 0x0};
+static uint64_t r[3] = {0xffffffffffffffff, 0x0, 0x0};
static long syz_io_uring_setup(volatile long a0, volatile long a1,
volatile long a2, volatile long a3, volatile long a4, volatile long
@@ -93,7 +101,7 @@ SIZEOF_IO_URING_CQE + 63) & ~63;
}
-void trigger_bug(void)
+static void trigger_bug(void)
{
intptr_t res = 0;
*(uint32_t*)0x20000204 = 0;
@@ -134,7 +142,7 @@ void trigger_bug(void)
}
int main(void)
{
- mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
+ mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
int pid = fork();
if (pid < 0)
exit(1);
@@ -153,6 +161,9 @@ int main(void)
}
return 0;
}
-
-
-
+#else
+int main(void)
+{
+ return T_EXIT_SKIP;
+}
+#endif
diff --git a/contrib/libs/liburing/test/sqpoll-disable-exit.c b/contrib/libs/liburing/test/sqpoll-disable-exit.c
index b2a4160c58..6e5bfc6f47 100644
--- a/contrib/libs/liburing/test/sqpoll-disable-exit.c
+++ b/contrib/libs/liburing/test/sqpoll-disable-exit.c
@@ -137,7 +137,7 @@ static void kill_and_wait(int pid, int* status)
}
}
-static void setup_test()
+static void setup_test(void)
{
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
setpgrp();
@@ -189,9 +189,9 @@ void execute_one(void)
}
int main(void)
{
- mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
- mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
- mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
+ mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
+ mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
+ mmap((void *)0x21000000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
loop();
return 0;
}
diff --git a/contrib/libs/liburing/test/symlink.c b/contrib/libs/liburing/test/symlink.c
index 755b51d152..1fc6b8e1db 100644
--- a/contrib/libs/liburing/test/symlink.c
+++ b/contrib/libs/liburing/test/symlink.c
@@ -44,7 +44,8 @@ err:
return 1;
}
-int test_link_contents(const char* linkname, const char *expected_contents)
+static int test_link_contents(const char* linkname,
+ const char *expected_contents)
{
char buf[128];
int ret = readlink(linkname, buf, 127);
diff --git a/contrib/libs/liburing/test/test.h b/contrib/libs/liburing/test/test.h
index 3628163afe..e99a8d204d 100644
--- a/contrib/libs/liburing/test/test.h
+++ b/contrib/libs/liburing/test/test.h
@@ -14,7 +14,8 @@ typedef struct io_uring_test_config {
const char *description;
} io_uring_test_config;
-io_uring_test_config io_uring_test_configs[] = {
+__attribute__((__unused__))
+static io_uring_test_config io_uring_test_configs[] = {
{ 0, "default" },
{ IORING_SETUP_SQE128, "large SQE"},
{ IORING_SETUP_CQE32, "large CQE"},
diff --git a/contrib/libs/liburing/test/timeout-new.c b/contrib/libs/liburing/test/timeout-new.c
index d4aeced46b..e0f2935e63 100644
--- a/contrib/libs/liburing/test/timeout-new.c
+++ b/contrib/libs/liburing/test/timeout-new.c
@@ -13,9 +13,9 @@
#define TIMEOUT_MSEC 200
#define TIMEOUT_SEC 10
-int thread_ret0, thread_ret1;
-int cnt = 0;
-pthread_mutex_t mutex;
+static int thread_ret0, thread_ret1;
+static int cnt = 0;
+static pthread_mutex_t mutex;
static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
{
@@ -112,7 +112,8 @@ static int test_return_after_timeout(struct io_uring *ring)
return 0;
}
-int __reap_thread_fn(void *data) {
+static int __reap_thread_fn(void *data)
+{
struct io_uring *ring = (struct io_uring *)data;
struct io_uring_cqe *cqe;
struct __kernel_timespec ts;
@@ -124,12 +125,14 @@ int __reap_thread_fn(void *data) {
return io_uring_wait_cqe_timeout(ring, &cqe, &ts);
}
-void *reap_thread_fn0(void *data) {
+static void *reap_thread_fn0(void *data)
+{
thread_ret0 = __reap_thread_fn(data);
return NULL;
}
-void *reap_thread_fn1(void *data) {
+static void *reap_thread_fn1(void *data)
+{
thread_ret1 = __reap_thread_fn(data);
return NULL;
}
@@ -138,7 +141,8 @@ void *reap_thread_fn1(void *data) {
* This is to test issuing a sqe in main thread and reaping it in two child-thread
* at the same time. To see if timeout feature works or not.
*/
-int test_multi_threads_timeout() {
+static int test_multi_threads_timeout(void)
+{
struct io_uring ring;
int ret;
bool both_wait = false;
diff --git a/contrib/libs/liburing/test/timeout-overflow.c b/contrib/libs/liburing/test/timeout-overflow.c
deleted file mode 100644
index 8c57ff31b1..0000000000
--- a/contrib/libs/liburing/test/timeout-overflow.c
+++ /dev/null
@@ -1,205 +0,0 @@
-#include "../config-host.h"
-/* SPDX-License-Identifier: MIT */
-/*
- * Description: run timeout overflow test
- *
- */
-#include <errno.h>
-#include <stdio.h>
-#include <limits.h>
-#include <string.h>
-#include <sys/time.h>
-
-#include "liburing.h"
-#include "helpers.h"
-
-#define TIMEOUT_MSEC 200
-static int not_supported;
-
-static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
-{
- ts->tv_sec = msec / 1000;
- ts->tv_nsec = (msec % 1000) * 1000000;
-}
-
-static int check_timeout_support(void)
-{
- struct io_uring_sqe *sqe;
- struct io_uring_cqe *cqe;
- struct __kernel_timespec ts;
- struct io_uring_params p;
- struct io_uring ring;
- int ret;
-
- memset(&p, 0, sizeof(p));
- ret = io_uring_queue_init_params(1, &ring, &p);
- if (ret) {
- fprintf(stderr, "ring setup failed: %d\n", ret);
- return T_EXIT_FAIL;
- }
-
- /* not really a match, but same kernel added batched completions */
- if (p.features & IORING_FEAT_POLL_32BITS) {
- not_supported = 1;
- return T_EXIT_SKIP;
- }
-
- sqe = io_uring_get_sqe(&ring);
- msec_to_ts(&ts, TIMEOUT_MSEC);
- io_uring_prep_timeout(sqe, &ts, 1, 0);
-
- ret = io_uring_submit(&ring);
- if (ret < 0) {
- fprintf(stderr, "sqe submit failed: %d\n", ret);
- goto err;
- }
-
- ret = io_uring_wait_cqe(&ring, &cqe);
- if (ret < 0) {
- fprintf(stderr, "wait completion %d\n", ret);
- goto err;
- }
-
- if (cqe->res == -EINVAL) {
- not_supported = 1;
- fprintf(stdout, "Timeout not supported, ignored\n");
- return 0;
- }
-
- io_uring_cqe_seen(&ring, cqe);
- io_uring_queue_exit(&ring);
- return T_EXIT_PASS;
-err:
- io_uring_queue_exit(&ring);
- return T_EXIT_FAIL;
-}
-
-/*
- * We first setup 4 timeout requests, which require a count value of 1, 1, 2,
- * UINT_MAX, so the sequence is 1, 2, 4, 2. Before really timeout, this 4
- * requests will not lead the change of cq_cached_tail, so as sq_dropped.
- *
- * And before this patch. The order of this four requests will be req1->req2->
- * req4->req3. Actually, it should be req1->req2->req3->req4.
- *
- * Then, if there is 2 nop req. All timeout requests expect req4 will completed
- * successful after the patch. And req1/req2 will completed successful with
- * req3/req4 return -ETIME without this patch!
- */
-static int test_timeout_overflow(void)
-{
- struct io_uring_sqe *sqe;
- struct io_uring_cqe *cqe;
- struct __kernel_timespec ts;
- struct io_uring ring;
- int i, ret;
-
- ret = io_uring_queue_init(16, &ring, 0);
- if (ret) {
- fprintf(stderr, "ring setup failed: %d\n", ret);
- return 1;
- }
-
- msec_to_ts(&ts, TIMEOUT_MSEC);
- for (i = 0; i < 4; i++) {
- unsigned num = 0;
- sqe = io_uring_get_sqe(&ring);
- switch (i) {
- case 0:
- case 1:
- num = 1;
- break;
- case 2:
- num = 2;
- break;
- case 3:
- num = UINT_MAX;
- break;
- }
- io_uring_prep_timeout(sqe, &ts, num, 0);
- }
-
- for (i = 0; i < 2; i++) {
- sqe = io_uring_get_sqe(&ring);
- io_uring_prep_nop(sqe);
- io_uring_sqe_set_data(sqe, (void *) 1);
- }
- ret = io_uring_submit(&ring);
- if (ret < 0) {
- fprintf(stderr, "sqe submit failed: %d\n", ret);
- goto err;
- }
-
- i = 0;
- while (i < 6) {
- ret = io_uring_wait_cqe(&ring, &cqe);
- if (ret < 0) {
- fprintf(stderr, "wait completion %d\n", ret);
- goto err;
- }
-
- /*
- * cqe1: first nop req
- * cqe2: first timeout req, because of cqe1
- * cqe3: second timeout req because of cqe1 + cqe2
- * cqe4: second nop req
- * cqe5~cqe6: the left three timeout req
- */
- switch (i) {
- case 0:
- case 3:
- if (io_uring_cqe_get_data(cqe) != (void *) 1) {
- fprintf(stderr, "nop not seen as 1 or 2\n");
- goto err;
- }
- break;
- case 1:
- case 2:
- case 4:
- if (cqe->res == -ETIME) {
- fprintf(stderr, "expected not return -ETIME "
- "for the #%d timeout req\n", i - 1);
- goto err;
- }
- break;
- case 5:
- if (cqe->res != -ETIME) {
- fprintf(stderr, "expected return -ETIME for "
- "the #%d timeout req\n", i - 1);
- goto err;
- }
- break;
- }
- io_uring_cqe_seen(&ring, cqe);
- i++;
- }
-
- return 0;
-err:
- return 1;
-}
-
-int main(int argc, char *argv[])
-{
- int ret;
-
- if (argc > 1)
- return T_EXIT_SKIP;
-
- ret = check_timeout_support();
- if (ret == T_EXIT_FAIL) {
- fprintf(stderr, "check_timeout_support failed: %d\n", ret);
- return T_EXIT_FAIL;
- }
-
- if (not_supported)
- return T_EXIT_SKIP;
-
- ret = test_timeout_overflow();
- if (ret) {
- fprintf(stderr, "test_timeout_overflow failed\n");
- return T_EXIT_FAIL;
- }
-
- return T_EXIT_PASS;
-}
diff --git a/contrib/libs/liburing/test/timeout.c b/contrib/libs/liburing/test/timeout.c
index 41d8627938..d43c15db17 100644
--- a/contrib/libs/liburing/test/timeout.c
+++ b/contrib/libs/liburing/test/timeout.c
@@ -15,12 +15,14 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include "helpers.h"
#include "liburing.h"
#include "../src/syscall.h"
#define TIMEOUT_MSEC 200
static int not_supported;
static int no_modify;
+static int no_multishot;
static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
{
@@ -177,7 +179,7 @@ static int test_single_timeout_nr(struct io_uring *ring, int nr)
goto err;
}
i++;
- };
+ }
return 0;
err:
@@ -1304,7 +1306,6 @@ static int test_not_failing_links(void)
fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
return 1;
} else if (cqe->user_data == 1 && cqe->res == -EINVAL) {
- fprintf(stderr, "ETIME_SUCCESS is not supported, skip\n");
goto done;
} else if (cqe->res != -ETIME || cqe->user_data != 1) {
fprintf(stderr, "timeout failed %i %i\n", cqe->res,
@@ -1329,6 +1330,246 @@ done:
}
+static int test_timeout_multishot(struct io_uring *ring)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct __kernel_timespec ts;
+ int ret;
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ msec_to_ts(&ts, TIMEOUT_MSEC);
+ io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_MULTISHOT);
+ io_uring_sqe_set_data(sqe, (void *) 1);
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ for (int i = 0; i < 2; i++) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ ret = cqe->res;
+ if (ret == -EINVAL) {
+ no_multishot = 1;
+ return T_EXIT_SKIP;
+ }
+
+ if (!(cqe->flags & IORING_CQE_F_MORE)) {
+ fprintf(stderr, "%s: flag not set in cqe\n", __FUNCTION__);
+ goto err;
+ }
+
+ if (ret != -ETIME) {
+ fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret));
+ goto err;
+ }
+
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ io_uring_prep_timeout_remove(sqe, 1, 0);
+ io_uring_sqe_set_data(sqe, (void *) 2);
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ ret = cqe->res;
+ if (ret < 0) {
+ fprintf(stderr, "%s: remove failed: %s\n", __FUNCTION__, strerror(-ret));
+ goto err;
+ }
+
+ io_uring_cqe_seen(ring, cqe);
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ ret = cqe->res;
+ if (ret != -ECANCELED) {
+ fprintf(stderr, "%s: timeout canceled: %s %llu\n", __FUNCTION__, strerror(-ret), cqe->user_data);
+ goto err;
+ }
+
+ io_uring_cqe_seen(ring, cqe);
+ return 0;
+err:
+ return 1;
+}
+
+
+static int test_timeout_multishot_nr(struct io_uring *ring)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct __kernel_timespec ts;
+ int ret;
+
+ if (no_multishot)
+ return T_EXIT_SKIP;
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ msec_to_ts(&ts, TIMEOUT_MSEC);
+ io_uring_prep_timeout(sqe, &ts, 3, IORING_TIMEOUT_MULTISHOT);
+ io_uring_sqe_set_data(sqe, (void *) 1);
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ for (int i = 0; i < 3; i++) {
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ if (i < 2 && !(cqe->flags & IORING_CQE_F_MORE)) {
+ fprintf(stderr, "%s: flag not set in cqe\n", __FUNCTION__);
+ goto err;
+ }
+ if (i == 3 && (cqe->flags & IORING_CQE_F_MORE)) {
+ fprintf(stderr, "%s: flag set in cqe\n", __FUNCTION__);
+ goto err;
+ }
+
+ ret = cqe->res;
+ if (ret != -ETIME) {
+ fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret));
+ goto err;
+ }
+
+ io_uring_cqe_seen(ring, cqe);
+ }
+
+ msec_to_ts(&ts, 2 * TIMEOUT_MSEC);
+ ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts);
+ if (ret != -ETIME) {
+ fprintf(stderr, "%s: wait completion timeout %s\n", __FUNCTION__, strerror(-ret));
+ goto err;
+ }
+
+ return 0;
+err:
+ return 1;
+}
+
+
+static int test_timeout_multishot_overflow(struct io_uring *ring)
+{
+ struct io_uring_cqe *cqe;
+ struct io_uring_sqe *sqe;
+ struct __kernel_timespec ts;
+ int ret;
+
+ if (no_multishot)
+ return T_EXIT_SKIP;
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ msec_to_ts(&ts, 10);
+ io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_MULTISHOT);
+ io_uring_sqe_set_data(sqe, (void *) 1);
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ ret = cqe->res;
+ if (ret != -ETIME) {
+ fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret));
+ goto err;
+ }
+
+ io_uring_cqe_seen(ring, cqe);
+ sleep(1);
+
+ if (!((*ring->sq.kflags) & IORING_SQ_CQ_OVERFLOW)) {
+ goto err;
+ }
+
+ /* multishot timer should be gone */
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ io_uring_prep_timeout_remove(sqe, 1, 0);
+
+ ret = io_uring_submit(ring);
+ if (ret <= 0) {
+ fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret < 0) {
+ fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
+ goto err;
+ }
+
+ ret = cqe->res;
+ io_uring_cqe_seen(ring, cqe);
+ if (ret != -ETIME) {
+ fprintf(stderr, "%s: remove failed: %d %s\n", __FUNCTION__, ret, strerror(-ret));
+ goto err;
+ }
+
+ return 0;
+err:
+ return 1;
+}
+
+
int main(int argc, char *argv[])
{
struct io_uring ring, sqpoll_ring;
@@ -1421,6 +1662,40 @@ int main(int argc, char *argv[])
return ret;
}
+ ret = test_timeout_multishot(&ring);
+ if (ret && ret != T_EXIT_SKIP) {
+ fprintf(stderr, "test_timeout_multishot failed\n");
+ return ret;
+ }
+
+ ret = test_timeout_multishot_nr(&ring);
+ if (ret && ret != T_EXIT_SKIP) {
+ fprintf(stderr, "test_timeout_multishot_nr failed\n");
+ return ret;
+ }
+
+ /* io_uring_wait_cqe_timeout() may have left a timeout, reinit ring */
+ io_uring_queue_exit(&ring);
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "ring setup failed\n");
+ return 1;
+ }
+
+ ret = test_timeout_multishot_overflow(&ring);
+ if (ret && ret != T_EXIT_SKIP) {
+ fprintf(stderr, "test_timeout_multishot_overflow failed\n");
+ return ret;
+ }
+
+ /* io_uring_wait_cqe_timeout() may have left a timeout, reinit ring */
+ io_uring_queue_exit(&ring);
+ ret = io_uring_queue_init(8, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "ring setup failed\n");
+ return 1;
+ }
+
ret = test_single_timeout_wait(&ring, &p);
if (ret) {
fprintf(stderr, "test_single_timeout_wait failed\n");
diff --git a/contrib/libs/liburing/test/unlink.c b/contrib/libs/liburing/test/unlink.c
index b5094ccb59..95e613ae3f 100644
--- a/contrib/libs/liburing/test/unlink.c
+++ b/contrib/libs/liburing/test/unlink.c
@@ -1,7 +1,7 @@
#include "../config-host.h"
/* SPDX-License-Identifier: MIT */
/*
- * Description: run various nop tests
+ * Description: run various unlink tests
*
*/
#include <errno.h>
diff --git a/contrib/libs/liburing/test/version.c b/contrib/libs/liburing/test/version.c
new file mode 100644
index 0000000000..b7fbd8420b
--- /dev/null
+++ b/contrib/libs/liburing/test/version.c
@@ -0,0 +1,26 @@
+#include "../config-host.h"
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: check version macros and runtime checks work
+ *
+ */
+#include "liburing.h"
+#include "helpers.h"
+
+int main(int argc, char *argv[])
+{
+ if (!IO_URING_CHECK_VERSION(io_uring_major_version(), io_uring_minor_version()))
+ return T_EXIT_FAIL;
+
+ if (io_uring_major_version() != IO_URING_VERSION_MAJOR)
+ return T_EXIT_FAIL;
+
+ if (io_uring_minor_version() != IO_URING_VERSION_MINOR)
+ return T_EXIT_FAIL;
+
+#if !IO_URING_CHECK_VERSION(IO_URING_VERSION_MAJOR, IO_URING_VERSION_MINOR)
+ return T_EXIT_FAIL;
+#endif
+
+ return T_EXIT_PASS;
+}
diff --git a/contrib/libs/liburing/test/version.t/ya.make b/contrib/libs/liburing/test/version.t/ya.make
new file mode 100644
index 0000000000..236860709b
--- /dev/null
+++ b/contrib/libs/liburing/test/version.t/ya.make
@@ -0,0 +1,31 @@
+# Generated by devtools/yamaker.
+
+PROGRAM()
+
+WITHOUT_LICENSE_TEXTS()
+
+PEERDIR(
+ contrib/libs/liburing
+)
+
+ADDINCL(
+ contrib/libs/liburing/src/include
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_RUNTIME()
+
+CFLAGS(
+ -DLIBURING_BUILD_TEST
+ -D__SANE_USERSPACE_TYPES__
+)
+
+SRCDIR(contrib/libs/liburing/test)
+
+SRCS(
+ helpers.c
+ version.c
+)
+
+END()
diff --git a/contrib/libs/liburing/test/wakeup-hang.c b/contrib/libs/liburing/test/wakeup-hang.c
index 1d1140c15e..66d49ff873 100644
--- a/contrib/libs/liburing/test/wakeup-hang.c
+++ b/contrib/libs/liburing/test/wakeup-hang.c
@@ -6,10 +6,10 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
-#include <liburing.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/time.h>
+#include "liburing.h"
struct thread_data {
struct io_uring *ring;
diff --git a/contrib/libs/liburing/test/xattr.c b/contrib/libs/liburing/test/xattr.c
index e1f97e5829..0c5870d33d 100644
--- a/contrib/libs/liburing/test/xattr.c
+++ b/contrib/libs/liburing/test/xattr.c
@@ -52,10 +52,11 @@ static int io_uring_fsetxattr(struct io_uring *ring, int fd, const char *name,
}
ret = cqe->res;
- if (ret == -EINVAL)
- no_xattr = 1;
+ if (ret < 0) {
+ if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP)
+ no_xattr = 1;
+ }
io_uring_cqe_seen(ring, cqe);
-
return ret;
}
@@ -127,8 +128,11 @@ static int io_uring_setxattr(struct io_uring *ring, const char *path,
}
ret = cqe->res;
+ if (ret < 0) {
+ if (ret == -EINVAL || ret == -EOPNOTSUPP)
+ no_xattr = 1;
+ }
io_uring_cqe_seen(ring, cqe);
-
return ret;
}