1*25da2beaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: MIT */
2*25da2beaSAndroid Build Coastguard Worker /*
3*25da2beaSAndroid Build Coastguard Worker * Check that IORING_OP_ACCEPT works, and send some data across to verify we
4*25da2beaSAndroid Build Coastguard Worker * didn't get a junk fd.
5*25da2beaSAndroid Build Coastguard Worker */
6*25da2beaSAndroid Build Coastguard Worker #include <stdio.h>
7*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
8*25da2beaSAndroid Build Coastguard Worker #include <stdint.h>
9*25da2beaSAndroid Build Coastguard Worker #include <assert.h>
10*25da2beaSAndroid Build Coastguard Worker #include <limits.h>
11*25da2beaSAndroid Build Coastguard Worker
12*25da2beaSAndroid Build Coastguard Worker #include <errno.h>
13*25da2beaSAndroid Build Coastguard Worker #include <fcntl.h>
14*25da2beaSAndroid Build Coastguard Worker #include <unistd.h>
15*25da2beaSAndroid Build Coastguard Worker #include <sys/socket.h>
16*25da2beaSAndroid Build Coastguard Worker #include <sys/time.h>
17*25da2beaSAndroid Build Coastguard Worker #include <sys/resource.h>
18*25da2beaSAndroid Build Coastguard Worker #include <sys/un.h>
19*25da2beaSAndroid Build Coastguard Worker #include <netinet/tcp.h>
20*25da2beaSAndroid Build Coastguard Worker #include <netinet/in.h>
21*25da2beaSAndroid Build Coastguard Worker #include <arpa/inet.h>
22*25da2beaSAndroid Build Coastguard Worker
23*25da2beaSAndroid Build Coastguard Worker #include "helpers.h"
24*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
25*25da2beaSAndroid Build Coastguard Worker
26*25da2beaSAndroid Build Coastguard Worker #define MAX_FDS 32
27*25da2beaSAndroid Build Coastguard Worker static int no_accept;
28*25da2beaSAndroid Build Coastguard Worker static int no_accept_multi;
29*25da2beaSAndroid Build Coastguard Worker
30*25da2beaSAndroid Build Coastguard Worker struct data {
31*25da2beaSAndroid Build Coastguard Worker char buf[128];
32*25da2beaSAndroid Build Coastguard Worker struct iovec iov;
33*25da2beaSAndroid Build Coastguard Worker };
34*25da2beaSAndroid Build Coastguard Worker
35*25da2beaSAndroid Build Coastguard Worker struct accept_test_args {
36*25da2beaSAndroid Build Coastguard Worker int accept_should_error;
37*25da2beaSAndroid Build Coastguard Worker bool fixed;
38*25da2beaSAndroid Build Coastguard Worker bool nonblock;
39*25da2beaSAndroid Build Coastguard Worker bool queue_accept_before_connect;
40*25da2beaSAndroid Build Coastguard Worker bool multishot;
41*25da2beaSAndroid Build Coastguard Worker int extra_loops;
42*25da2beaSAndroid Build Coastguard Worker };
43*25da2beaSAndroid Build Coastguard Worker
close_fds(int fds[],int nr)44*25da2beaSAndroid Build Coastguard Worker static void close_fds(int fds[], int nr)
45*25da2beaSAndroid Build Coastguard Worker {
46*25da2beaSAndroid Build Coastguard Worker int i;
47*25da2beaSAndroid Build Coastguard Worker
48*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++)
49*25da2beaSAndroid Build Coastguard Worker close(fds[i]);
50*25da2beaSAndroid Build Coastguard Worker }
51*25da2beaSAndroid Build Coastguard Worker
close_sock_fds(int s_fd[],int c_fd[],int nr,bool fixed)52*25da2beaSAndroid Build Coastguard Worker static void close_sock_fds(int s_fd[], int c_fd[], int nr, bool fixed)
53*25da2beaSAndroid Build Coastguard Worker {
54*25da2beaSAndroid Build Coastguard Worker if (!fixed)
55*25da2beaSAndroid Build Coastguard Worker close_fds(s_fd, nr);
56*25da2beaSAndroid Build Coastguard Worker close_fds(c_fd, nr);
57*25da2beaSAndroid Build Coastguard Worker }
58*25da2beaSAndroid Build Coastguard Worker
queue_send(struct io_uring * ring,int fd)59*25da2beaSAndroid Build Coastguard Worker static void queue_send(struct io_uring *ring, int fd)
60*25da2beaSAndroid Build Coastguard Worker {
61*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
62*25da2beaSAndroid Build Coastguard Worker struct data *d;
63*25da2beaSAndroid Build Coastguard Worker
64*25da2beaSAndroid Build Coastguard Worker d = t_malloc(sizeof(*d));
65*25da2beaSAndroid Build Coastguard Worker d->iov.iov_base = d->buf;
66*25da2beaSAndroid Build Coastguard Worker d->iov.iov_len = sizeof(d->buf);
67*25da2beaSAndroid Build Coastguard Worker
68*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
69*25da2beaSAndroid Build Coastguard Worker io_uring_prep_writev(sqe, fd, &d->iov, 1, 0);
70*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 1;
71*25da2beaSAndroid Build Coastguard Worker }
72*25da2beaSAndroid Build Coastguard Worker
queue_recv(struct io_uring * ring,int fd,bool fixed)73*25da2beaSAndroid Build Coastguard Worker static void queue_recv(struct io_uring *ring, int fd, bool fixed)
74*25da2beaSAndroid Build Coastguard Worker {
75*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
76*25da2beaSAndroid Build Coastguard Worker struct data *d;
77*25da2beaSAndroid Build Coastguard Worker
78*25da2beaSAndroid Build Coastguard Worker d = t_malloc(sizeof(*d));
79*25da2beaSAndroid Build Coastguard Worker d->iov.iov_base = d->buf;
80*25da2beaSAndroid Build Coastguard Worker d->iov.iov_len = sizeof(d->buf);
81*25da2beaSAndroid Build Coastguard Worker
82*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
83*25da2beaSAndroid Build Coastguard Worker io_uring_prep_readv(sqe, fd, &d->iov, 1, 0);
84*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 2;
85*25da2beaSAndroid Build Coastguard Worker if (fixed)
86*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_FIXED_FILE;
87*25da2beaSAndroid Build Coastguard Worker }
88*25da2beaSAndroid Build Coastguard Worker
queue_accept_conn(struct io_uring * ring,int fd,struct accept_test_args args)89*25da2beaSAndroid Build Coastguard Worker static void queue_accept_conn(struct io_uring *ring, int fd,
90*25da2beaSAndroid Build Coastguard Worker struct accept_test_args args)
91*25da2beaSAndroid Build Coastguard Worker {
92*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
93*25da2beaSAndroid Build Coastguard Worker int ret;
94*25da2beaSAndroid Build Coastguard Worker int fixed_idx = args.fixed ? 0 : -1;
95*25da2beaSAndroid Build Coastguard Worker int count = 1 + args.extra_loops;
96*25da2beaSAndroid Build Coastguard Worker bool multishot = args.multishot;
97*25da2beaSAndroid Build Coastguard Worker
98*25da2beaSAndroid Build Coastguard Worker while (count--) {
99*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
100*25da2beaSAndroid Build Coastguard Worker if (fixed_idx < 0) {
101*25da2beaSAndroid Build Coastguard Worker if (!multishot)
102*25da2beaSAndroid Build Coastguard Worker io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
103*25da2beaSAndroid Build Coastguard Worker else
104*25da2beaSAndroid Build Coastguard Worker io_uring_prep_multishot_accept(sqe, fd, NULL,
105*25da2beaSAndroid Build Coastguard Worker NULL, 0);
106*25da2beaSAndroid Build Coastguard Worker } else {
107*25da2beaSAndroid Build Coastguard Worker if (!multishot)
108*25da2beaSAndroid Build Coastguard Worker io_uring_prep_accept_direct(sqe, fd, NULL, NULL,
109*25da2beaSAndroid Build Coastguard Worker 0, fixed_idx);
110*25da2beaSAndroid Build Coastguard Worker else
111*25da2beaSAndroid Build Coastguard Worker io_uring_prep_multishot_accept_direct(sqe, fd,
112*25da2beaSAndroid Build Coastguard Worker NULL, NULL,
113*25da2beaSAndroid Build Coastguard Worker 0);
114*25da2beaSAndroid Build Coastguard Worker }
115*25da2beaSAndroid Build Coastguard Worker
116*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
117*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
118*25da2beaSAndroid Build Coastguard Worker }
119*25da2beaSAndroid Build Coastguard Worker }
120*25da2beaSAndroid Build Coastguard Worker
accept_conn(struct io_uring * ring,int fixed_idx,bool multishot)121*25da2beaSAndroid Build Coastguard Worker static int accept_conn(struct io_uring *ring, int fixed_idx, bool multishot)
122*25da2beaSAndroid Build Coastguard Worker {
123*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
124*25da2beaSAndroid Build Coastguard Worker int ret;
125*25da2beaSAndroid Build Coastguard Worker
126*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(ring, &cqe);
127*25da2beaSAndroid Build Coastguard Worker assert(!ret);
128*25da2beaSAndroid Build Coastguard Worker ret = cqe->res;
129*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(ring, cqe);
130*25da2beaSAndroid Build Coastguard Worker
131*25da2beaSAndroid Build Coastguard Worker if (fixed_idx >= 0) {
132*25da2beaSAndroid Build Coastguard Worker if (ret > 0) {
133*25da2beaSAndroid Build Coastguard Worker if (!multishot) {
134*25da2beaSAndroid Build Coastguard Worker close(ret);
135*25da2beaSAndroid Build Coastguard Worker return -EINVAL;
136*25da2beaSAndroid Build Coastguard Worker }
137*25da2beaSAndroid Build Coastguard Worker } else if (!ret) {
138*25da2beaSAndroid Build Coastguard Worker ret = fixed_idx;
139*25da2beaSAndroid Build Coastguard Worker }
140*25da2beaSAndroid Build Coastguard Worker }
141*25da2beaSAndroid Build Coastguard Worker return ret;
142*25da2beaSAndroid Build Coastguard Worker }
143*25da2beaSAndroid Build Coastguard Worker
start_accept_listen(struct sockaddr_in * addr,int port_off,int extra_flags)144*25da2beaSAndroid Build Coastguard Worker static int start_accept_listen(struct sockaddr_in *addr, int port_off,
145*25da2beaSAndroid Build Coastguard Worker int extra_flags)
146*25da2beaSAndroid Build Coastguard Worker {
147*25da2beaSAndroid Build Coastguard Worker int fd, ret;
148*25da2beaSAndroid Build Coastguard Worker
149*25da2beaSAndroid Build Coastguard Worker fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC | extra_flags,
150*25da2beaSAndroid Build Coastguard Worker IPPROTO_TCP);
151*25da2beaSAndroid Build Coastguard Worker
152*25da2beaSAndroid Build Coastguard Worker int32_t val = 1;
153*25da2beaSAndroid Build Coastguard Worker ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
154*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
155*25da2beaSAndroid Build Coastguard Worker ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
156*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
157*25da2beaSAndroid Build Coastguard Worker
158*25da2beaSAndroid Build Coastguard Worker struct sockaddr_in laddr;
159*25da2beaSAndroid Build Coastguard Worker
160*25da2beaSAndroid Build Coastguard Worker if (!addr)
161*25da2beaSAndroid Build Coastguard Worker addr = &laddr;
162*25da2beaSAndroid Build Coastguard Worker
163*25da2beaSAndroid Build Coastguard Worker addr->sin_family = AF_INET;
164*25da2beaSAndroid Build Coastguard Worker addr->sin_port = htons(0x1235 + port_off);
165*25da2beaSAndroid Build Coastguard Worker addr->sin_addr.s_addr = inet_addr("127.0.0.1");
166*25da2beaSAndroid Build Coastguard Worker
167*25da2beaSAndroid Build Coastguard Worker ret = bind(fd, (struct sockaddr*)addr, sizeof(*addr));
168*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
169*25da2beaSAndroid Build Coastguard Worker ret = listen(fd, 128);
170*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
171*25da2beaSAndroid Build Coastguard Worker
172*25da2beaSAndroid Build Coastguard Worker return fd;
173*25da2beaSAndroid Build Coastguard Worker }
174*25da2beaSAndroid Build Coastguard Worker
set_client_fd(struct sockaddr_in * addr)175*25da2beaSAndroid Build Coastguard Worker static int set_client_fd(struct sockaddr_in *addr)
176*25da2beaSAndroid Build Coastguard Worker {
177*25da2beaSAndroid Build Coastguard Worker int32_t val;
178*25da2beaSAndroid Build Coastguard Worker int fd, ret;
179*25da2beaSAndroid Build Coastguard Worker
180*25da2beaSAndroid Build Coastguard Worker fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
181*25da2beaSAndroid Build Coastguard Worker
182*25da2beaSAndroid Build Coastguard Worker val = 1;
183*25da2beaSAndroid Build Coastguard Worker ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
184*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
185*25da2beaSAndroid Build Coastguard Worker
186*25da2beaSAndroid Build Coastguard Worker int32_t flags = fcntl(fd, F_GETFL, 0);
187*25da2beaSAndroid Build Coastguard Worker assert(flags != -1);
188*25da2beaSAndroid Build Coastguard Worker
189*25da2beaSAndroid Build Coastguard Worker flags |= O_NONBLOCK;
190*25da2beaSAndroid Build Coastguard Worker ret = fcntl(fd, F_SETFL, flags);
191*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
192*25da2beaSAndroid Build Coastguard Worker
193*25da2beaSAndroid Build Coastguard Worker ret = connect(fd, (struct sockaddr *)addr, sizeof(*addr));
194*25da2beaSAndroid Build Coastguard Worker assert(ret == -1);
195*25da2beaSAndroid Build Coastguard Worker
196*25da2beaSAndroid Build Coastguard Worker flags = fcntl(fd, F_GETFL, 0);
197*25da2beaSAndroid Build Coastguard Worker assert(flags != -1);
198*25da2beaSAndroid Build Coastguard Worker
199*25da2beaSAndroid Build Coastguard Worker flags &= ~O_NONBLOCK;
200*25da2beaSAndroid Build Coastguard Worker ret = fcntl(fd, F_SETFL, flags);
201*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
202*25da2beaSAndroid Build Coastguard Worker
203*25da2beaSAndroid Build Coastguard Worker return fd;
204*25da2beaSAndroid Build Coastguard Worker }
205*25da2beaSAndroid Build Coastguard Worker
test_loop(struct io_uring * ring,struct accept_test_args args,int recv_s0,struct sockaddr_in * addr)206*25da2beaSAndroid Build Coastguard Worker static int test_loop(struct io_uring *ring,
207*25da2beaSAndroid Build Coastguard Worker struct accept_test_args args,
208*25da2beaSAndroid Build Coastguard Worker int recv_s0,
209*25da2beaSAndroid Build Coastguard Worker struct sockaddr_in *addr)
210*25da2beaSAndroid Build Coastguard Worker {
211*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
212*25da2beaSAndroid Build Coastguard Worker uint32_t head, count = 0;
213*25da2beaSAndroid Build Coastguard Worker int i, ret, s_fd[MAX_FDS], c_fd[MAX_FDS], done = 0;
214*25da2beaSAndroid Build Coastguard Worker bool fixed = args.fixed;
215*25da2beaSAndroid Build Coastguard Worker bool multishot = args.multishot;
216*25da2beaSAndroid Build Coastguard Worker uint32_t multishot_mask = 0;
217*25da2beaSAndroid Build Coastguard Worker int nr_fds = multishot ? MAX_FDS : 1;
218*25da2beaSAndroid Build Coastguard Worker
219*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr_fds; i++)
220*25da2beaSAndroid Build Coastguard Worker c_fd[i] = set_client_fd(addr);
221*25da2beaSAndroid Build Coastguard Worker
222*25da2beaSAndroid Build Coastguard Worker if (!args.queue_accept_before_connect)
223*25da2beaSAndroid Build Coastguard Worker queue_accept_conn(ring, recv_s0, args);
224*25da2beaSAndroid Build Coastguard Worker
225*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr_fds; i++) {
226*25da2beaSAndroid Build Coastguard Worker s_fd[i] = accept_conn(ring, fixed ? 0 : -1, multishot);
227*25da2beaSAndroid Build Coastguard Worker if (s_fd[i] == -EINVAL) {
228*25da2beaSAndroid Build Coastguard Worker if (args.accept_should_error)
229*25da2beaSAndroid Build Coastguard Worker goto out;
230*25da2beaSAndroid Build Coastguard Worker fprintf(stdout,
231*25da2beaSAndroid Build Coastguard Worker "%s %s Accept not supported, skipping\n",
232*25da2beaSAndroid Build Coastguard Worker fixed ? "Fixed" : "",
233*25da2beaSAndroid Build Coastguard Worker multishot ? "Multishot" : "");
234*25da2beaSAndroid Build Coastguard Worker if (multishot)
235*25da2beaSAndroid Build Coastguard Worker no_accept_multi = 1;
236*25da2beaSAndroid Build Coastguard Worker else
237*25da2beaSAndroid Build Coastguard Worker no_accept = 1;
238*25da2beaSAndroid Build Coastguard Worker goto out;
239*25da2beaSAndroid Build Coastguard Worker } else if (s_fd[i] < 0) {
240*25da2beaSAndroid Build Coastguard Worker if (args.accept_should_error &&
241*25da2beaSAndroid Build Coastguard Worker (s_fd[i] == -EBADF || s_fd[i] == -EINVAL))
242*25da2beaSAndroid Build Coastguard Worker goto out;
243*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "%s %s Accept[%d] got %d\n",
244*25da2beaSAndroid Build Coastguard Worker fixed ? "Fixed" : "",
245*25da2beaSAndroid Build Coastguard Worker multishot ? "Multishot" : "",
246*25da2beaSAndroid Build Coastguard Worker i, s_fd[i]);
247*25da2beaSAndroid Build Coastguard Worker goto err;
248*25da2beaSAndroid Build Coastguard Worker }
249*25da2beaSAndroid Build Coastguard Worker
250*25da2beaSAndroid Build Coastguard Worker if (multishot && fixed) {
251*25da2beaSAndroid Build Coastguard Worker if (s_fd[i] >= MAX_FDS) {
252*25da2beaSAndroid Build Coastguard Worker fprintf(stderr,
253*25da2beaSAndroid Build Coastguard Worker "Fixed Multishot Accept[%d] got outbound index: %d\n",
254*25da2beaSAndroid Build Coastguard Worker i, s_fd[i]);
255*25da2beaSAndroid Build Coastguard Worker goto err;
256*25da2beaSAndroid Build Coastguard Worker }
257*25da2beaSAndroid Build Coastguard Worker /*
258*25da2beaSAndroid Build Coastguard Worker * for fixed multishot accept test, the file slots
259*25da2beaSAndroid Build Coastguard Worker * allocated are [0, 32), this means we finally end up
260*25da2beaSAndroid Build Coastguard Worker * with each bit of a u32 being 1.
261*25da2beaSAndroid Build Coastguard Worker */
262*25da2beaSAndroid Build Coastguard Worker multishot_mask |= (1U << s_fd[i]);
263*25da2beaSAndroid Build Coastguard Worker }
264*25da2beaSAndroid Build Coastguard Worker }
265*25da2beaSAndroid Build Coastguard Worker
266*25da2beaSAndroid Build Coastguard Worker if (multishot) {
267*25da2beaSAndroid Build Coastguard Worker if (fixed && (~multishot_mask != 0U)) {
268*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "Fixed Multishot Accept misses events\n");
269*25da2beaSAndroid Build Coastguard Worker goto err;
270*25da2beaSAndroid Build Coastguard Worker }
271*25da2beaSAndroid Build Coastguard Worker goto out;
272*25da2beaSAndroid Build Coastguard Worker }
273*25da2beaSAndroid Build Coastguard Worker
274*25da2beaSAndroid Build Coastguard Worker queue_send(ring, c_fd[0]);
275*25da2beaSAndroid Build Coastguard Worker queue_recv(ring, s_fd[0], fixed);
276*25da2beaSAndroid Build Coastguard Worker
277*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit_and_wait(ring, 2);
278*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
279*25da2beaSAndroid Build Coastguard Worker
280*25da2beaSAndroid Build Coastguard Worker while (count < 2) {
281*25da2beaSAndroid Build Coastguard Worker io_uring_for_each_cqe(ring, head, cqe) {
282*25da2beaSAndroid Build Coastguard Worker if (cqe->res < 0) {
283*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "Got cqe res %d, user_data %i\n",
284*25da2beaSAndroid Build Coastguard Worker cqe->res, (int)cqe->user_data);
285*25da2beaSAndroid Build Coastguard Worker done = 1;
286*25da2beaSAndroid Build Coastguard Worker break;
287*25da2beaSAndroid Build Coastguard Worker }
288*25da2beaSAndroid Build Coastguard Worker assert(cqe->res == 128);
289*25da2beaSAndroid Build Coastguard Worker count++;
290*25da2beaSAndroid Build Coastguard Worker }
291*25da2beaSAndroid Build Coastguard Worker
292*25da2beaSAndroid Build Coastguard Worker assert(count <= 2);
293*25da2beaSAndroid Build Coastguard Worker io_uring_cq_advance(ring, count);
294*25da2beaSAndroid Build Coastguard Worker if (done)
295*25da2beaSAndroid Build Coastguard Worker goto err;
296*25da2beaSAndroid Build Coastguard Worker }
297*25da2beaSAndroid Build Coastguard Worker
298*25da2beaSAndroid Build Coastguard Worker out:
299*25da2beaSAndroid Build Coastguard Worker close_sock_fds(s_fd, c_fd, nr_fds, fixed);
300*25da2beaSAndroid Build Coastguard Worker return 0;
301*25da2beaSAndroid Build Coastguard Worker err:
302*25da2beaSAndroid Build Coastguard Worker close_sock_fds(s_fd, c_fd, nr_fds, fixed);
303*25da2beaSAndroid Build Coastguard Worker return 1;
304*25da2beaSAndroid Build Coastguard Worker }
305*25da2beaSAndroid Build Coastguard Worker
test(struct io_uring * ring,struct accept_test_args args)306*25da2beaSAndroid Build Coastguard Worker static int test(struct io_uring *ring, struct accept_test_args args)
307*25da2beaSAndroid Build Coastguard Worker {
308*25da2beaSAndroid Build Coastguard Worker struct sockaddr_in addr;
309*25da2beaSAndroid Build Coastguard Worker int ret = 0;
310*25da2beaSAndroid Build Coastguard Worker int loop;
311*25da2beaSAndroid Build Coastguard Worker int32_t recv_s0 = start_accept_listen(&addr, 0,
312*25da2beaSAndroid Build Coastguard Worker args.nonblock ? O_NONBLOCK : 0);
313*25da2beaSAndroid Build Coastguard Worker if (args.queue_accept_before_connect)
314*25da2beaSAndroid Build Coastguard Worker queue_accept_conn(ring, recv_s0, args);
315*25da2beaSAndroid Build Coastguard Worker for (loop = 0; loop < 1 + args.extra_loops; loop++) {
316*25da2beaSAndroid Build Coastguard Worker ret = test_loop(ring, args, recv_s0, &addr);
317*25da2beaSAndroid Build Coastguard Worker if (ret)
318*25da2beaSAndroid Build Coastguard Worker break;
319*25da2beaSAndroid Build Coastguard Worker }
320*25da2beaSAndroid Build Coastguard Worker
321*25da2beaSAndroid Build Coastguard Worker close(recv_s0);
322*25da2beaSAndroid Build Coastguard Worker return ret;
323*25da2beaSAndroid Build Coastguard Worker }
324*25da2beaSAndroid Build Coastguard Worker
sig_alrm(int sig)325*25da2beaSAndroid Build Coastguard Worker static void sig_alrm(int sig)
326*25da2beaSAndroid Build Coastguard Worker {
327*25da2beaSAndroid Build Coastguard Worker exit(0);
328*25da2beaSAndroid Build Coastguard Worker }
329*25da2beaSAndroid Build Coastguard Worker
test_accept_pending_on_exit(void)330*25da2beaSAndroid Build Coastguard Worker static int test_accept_pending_on_exit(void)
331*25da2beaSAndroid Build Coastguard Worker {
332*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
333*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
334*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
335*25da2beaSAndroid Build Coastguard Worker int fd, ret;
336*25da2beaSAndroid Build Coastguard Worker
337*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(32, &m_io_uring, 0);
338*25da2beaSAndroid Build Coastguard Worker assert(ret >= 0);
339*25da2beaSAndroid Build Coastguard Worker
340*25da2beaSAndroid Build Coastguard Worker fd = start_accept_listen(NULL, 0, 0);
341*25da2beaSAndroid Build Coastguard Worker
342*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&m_io_uring);
343*25da2beaSAndroid Build Coastguard Worker io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
344*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(&m_io_uring);
345*25da2beaSAndroid Build Coastguard Worker assert(ret != -1);
346*25da2beaSAndroid Build Coastguard Worker
347*25da2beaSAndroid Build Coastguard Worker signal(SIGALRM, sig_alrm);
348*25da2beaSAndroid Build Coastguard Worker alarm(1);
349*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(&m_io_uring, &cqe);
350*25da2beaSAndroid Build Coastguard Worker assert(!ret);
351*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(&m_io_uring, cqe);
352*25da2beaSAndroid Build Coastguard Worker
353*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
354*25da2beaSAndroid Build Coastguard Worker return 0;
355*25da2beaSAndroid Build Coastguard Worker }
356*25da2beaSAndroid Build Coastguard Worker
357*25da2beaSAndroid Build Coastguard Worker struct test_accept_many_args {
358*25da2beaSAndroid Build Coastguard Worker unsigned int usecs;
359*25da2beaSAndroid Build Coastguard Worker bool nonblock;
360*25da2beaSAndroid Build Coastguard Worker bool single_sock;
361*25da2beaSAndroid Build Coastguard Worker bool close_fds;
362*25da2beaSAndroid Build Coastguard Worker };
363*25da2beaSAndroid Build Coastguard Worker
364*25da2beaSAndroid Build Coastguard Worker /*
365*25da2beaSAndroid Build Coastguard Worker * Test issue many accepts and see if we handle cancellation on exit
366*25da2beaSAndroid Build Coastguard Worker */
test_accept_many(struct test_accept_many_args args)367*25da2beaSAndroid Build Coastguard Worker static int test_accept_many(struct test_accept_many_args args)
368*25da2beaSAndroid Build Coastguard Worker {
369*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
370*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
371*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
372*25da2beaSAndroid Build Coastguard Worker unsigned long cur_lim;
373*25da2beaSAndroid Build Coastguard Worker struct rlimit rlim;
374*25da2beaSAndroid Build Coastguard Worker int *fds, i, ret;
375*25da2beaSAndroid Build Coastguard Worker unsigned int nr = 128;
376*25da2beaSAndroid Build Coastguard Worker int nr_socks = args.single_sock ? 1 : nr;
377*25da2beaSAndroid Build Coastguard Worker
378*25da2beaSAndroid Build Coastguard Worker if (getrlimit(RLIMIT_NPROC, &rlim) < 0) {
379*25da2beaSAndroid Build Coastguard Worker perror("getrlimit");
380*25da2beaSAndroid Build Coastguard Worker return 1;
381*25da2beaSAndroid Build Coastguard Worker }
382*25da2beaSAndroid Build Coastguard Worker
383*25da2beaSAndroid Build Coastguard Worker cur_lim = rlim.rlim_cur;
384*25da2beaSAndroid Build Coastguard Worker rlim.rlim_cur = nr / 4;
385*25da2beaSAndroid Build Coastguard Worker
386*25da2beaSAndroid Build Coastguard Worker if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
387*25da2beaSAndroid Build Coastguard Worker perror("setrlimit");
388*25da2beaSAndroid Build Coastguard Worker return 1;
389*25da2beaSAndroid Build Coastguard Worker }
390*25da2beaSAndroid Build Coastguard Worker
391*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(2 * nr, &m_io_uring, 0);
392*25da2beaSAndroid Build Coastguard Worker assert(ret >= 0);
393*25da2beaSAndroid Build Coastguard Worker
394*25da2beaSAndroid Build Coastguard Worker fds = t_calloc(nr_socks, sizeof(int));
395*25da2beaSAndroid Build Coastguard Worker
396*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr_socks; i++)
397*25da2beaSAndroid Build Coastguard Worker fds[i] = start_accept_listen(NULL, i,
398*25da2beaSAndroid Build Coastguard Worker args.nonblock ? O_NONBLOCK : 0);
399*25da2beaSAndroid Build Coastguard Worker
400*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++) {
401*25da2beaSAndroid Build Coastguard Worker int sock_idx = args.single_sock ? 0 : i;
402*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&m_io_uring);
403*25da2beaSAndroid Build Coastguard Worker io_uring_prep_accept(sqe, fds[sock_idx], NULL, NULL, 0);
404*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 1 + i;
405*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(&m_io_uring);
406*25da2beaSAndroid Build Coastguard Worker assert(ret == 1);
407*25da2beaSAndroid Build Coastguard Worker }
408*25da2beaSAndroid Build Coastguard Worker
409*25da2beaSAndroid Build Coastguard Worker if (args.usecs)
410*25da2beaSAndroid Build Coastguard Worker usleep(args.usecs);
411*25da2beaSAndroid Build Coastguard Worker
412*25da2beaSAndroid Build Coastguard Worker if (args.close_fds)
413*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr_socks; i++)
414*25da2beaSAndroid Build Coastguard Worker close(fds[i]);
415*25da2beaSAndroid Build Coastguard Worker
416*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr; i++) {
417*25da2beaSAndroid Build Coastguard Worker if (io_uring_peek_cqe(&m_io_uring, &cqe))
418*25da2beaSAndroid Build Coastguard Worker break;
419*25da2beaSAndroid Build Coastguard Worker if (cqe->res != -ECANCELED) {
420*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "Expected cqe to be cancelled %d\n", cqe->res);
421*25da2beaSAndroid Build Coastguard Worker ret = 1;
422*25da2beaSAndroid Build Coastguard Worker goto out;
423*25da2beaSAndroid Build Coastguard Worker }
424*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(&m_io_uring, cqe);
425*25da2beaSAndroid Build Coastguard Worker }
426*25da2beaSAndroid Build Coastguard Worker ret = 0;
427*25da2beaSAndroid Build Coastguard Worker out:
428*25da2beaSAndroid Build Coastguard Worker rlim.rlim_cur = cur_lim;
429*25da2beaSAndroid Build Coastguard Worker if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
430*25da2beaSAndroid Build Coastguard Worker perror("setrlimit");
431*25da2beaSAndroid Build Coastguard Worker return 1;
432*25da2beaSAndroid Build Coastguard Worker }
433*25da2beaSAndroid Build Coastguard Worker
434*25da2beaSAndroid Build Coastguard Worker free(fds);
435*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
436*25da2beaSAndroid Build Coastguard Worker return ret;
437*25da2beaSAndroid Build Coastguard Worker }
438*25da2beaSAndroid Build Coastguard Worker
test_accept_cancel(unsigned usecs,unsigned int nr,bool multishot)439*25da2beaSAndroid Build Coastguard Worker static int test_accept_cancel(unsigned usecs, unsigned int nr, bool multishot)
440*25da2beaSAndroid Build Coastguard Worker {
441*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
442*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
443*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
444*25da2beaSAndroid Build Coastguard Worker int fd, i, ret;
445*25da2beaSAndroid Build Coastguard Worker
446*25da2beaSAndroid Build Coastguard Worker if (multishot && no_accept_multi)
447*25da2beaSAndroid Build Coastguard Worker return 0;
448*25da2beaSAndroid Build Coastguard Worker
449*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(32, &m_io_uring, 0);
450*25da2beaSAndroid Build Coastguard Worker assert(ret >= 0);
451*25da2beaSAndroid Build Coastguard Worker
452*25da2beaSAndroid Build Coastguard Worker fd = start_accept_listen(NULL, 0, 0);
453*25da2beaSAndroid Build Coastguard Worker
454*25da2beaSAndroid Build Coastguard Worker for (i = 1; i <= nr; i++) {
455*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&m_io_uring);
456*25da2beaSAndroid Build Coastguard Worker if (!multishot)
457*25da2beaSAndroid Build Coastguard Worker io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
458*25da2beaSAndroid Build Coastguard Worker else
459*25da2beaSAndroid Build Coastguard Worker io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0);
460*25da2beaSAndroid Build Coastguard Worker sqe->user_data = i;
461*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(&m_io_uring);
462*25da2beaSAndroid Build Coastguard Worker assert(ret == 1);
463*25da2beaSAndroid Build Coastguard Worker }
464*25da2beaSAndroid Build Coastguard Worker
465*25da2beaSAndroid Build Coastguard Worker if (usecs)
466*25da2beaSAndroid Build Coastguard Worker usleep(usecs);
467*25da2beaSAndroid Build Coastguard Worker
468*25da2beaSAndroid Build Coastguard Worker for (i = 1; i <= nr; i++) {
469*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&m_io_uring);
470*25da2beaSAndroid Build Coastguard Worker io_uring_prep_cancel64(sqe, i, 0);
471*25da2beaSAndroid Build Coastguard Worker sqe->user_data = nr + i;
472*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(&m_io_uring);
473*25da2beaSAndroid Build Coastguard Worker assert(ret == 1);
474*25da2beaSAndroid Build Coastguard Worker }
475*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < nr * 2; i++) {
476*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(&m_io_uring, &cqe);
477*25da2beaSAndroid Build Coastguard Worker assert(!ret);
478*25da2beaSAndroid Build Coastguard Worker /*
479*25da2beaSAndroid Build Coastguard Worker * Two cases here:
480*25da2beaSAndroid Build Coastguard Worker *
481*25da2beaSAndroid Build Coastguard Worker * 1) We cancel the accept4() before it got started, we should
482*25da2beaSAndroid Build Coastguard Worker * get '0' for the cancel request and '-ECANCELED' for the
483*25da2beaSAndroid Build Coastguard Worker * accept request.
484*25da2beaSAndroid Build Coastguard Worker * 2) We cancel the accept4() after it's already running, we
485*25da2beaSAndroid Build Coastguard Worker * should get '-EALREADY' for the cancel request and
486*25da2beaSAndroid Build Coastguard Worker * '-EINTR' for the accept request.
487*25da2beaSAndroid Build Coastguard Worker */
488*25da2beaSAndroid Build Coastguard Worker if (cqe->user_data == 0) {
489*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "unexpected 0 user data\n");
490*25da2beaSAndroid Build Coastguard Worker goto err;
491*25da2beaSAndroid Build Coastguard Worker } else if (cqe->user_data <= nr) {
492*25da2beaSAndroid Build Coastguard Worker if (cqe->res != -EINTR && cqe->res != -ECANCELED) {
493*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "Cancelled accept got %d\n", cqe->res);
494*25da2beaSAndroid Build Coastguard Worker goto err;
495*25da2beaSAndroid Build Coastguard Worker }
496*25da2beaSAndroid Build Coastguard Worker } else if (cqe->user_data <= nr * 2) {
497*25da2beaSAndroid Build Coastguard Worker if (cqe->res != -EALREADY && cqe->res != 0) {
498*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "Cancel got %d\n", cqe->res);
499*25da2beaSAndroid Build Coastguard Worker goto err;
500*25da2beaSAndroid Build Coastguard Worker }
501*25da2beaSAndroid Build Coastguard Worker }
502*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(&m_io_uring, cqe);
503*25da2beaSAndroid Build Coastguard Worker }
504*25da2beaSAndroid Build Coastguard Worker
505*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
506*25da2beaSAndroid Build Coastguard Worker close(fd);
507*25da2beaSAndroid Build Coastguard Worker return 0;
508*25da2beaSAndroid Build Coastguard Worker err:
509*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
510*25da2beaSAndroid Build Coastguard Worker close(fd);
511*25da2beaSAndroid Build Coastguard Worker return 1;
512*25da2beaSAndroid Build Coastguard Worker }
513*25da2beaSAndroid Build Coastguard Worker
test_accept(int count,bool before)514*25da2beaSAndroid Build Coastguard Worker static int test_accept(int count, bool before)
515*25da2beaSAndroid Build Coastguard Worker {
516*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
517*25da2beaSAndroid Build Coastguard Worker int ret;
518*25da2beaSAndroid Build Coastguard Worker struct accept_test_args args = {
519*25da2beaSAndroid Build Coastguard Worker .queue_accept_before_connect = before,
520*25da2beaSAndroid Build Coastguard Worker .extra_loops = count - 1
521*25da2beaSAndroid Build Coastguard Worker };
522*25da2beaSAndroid Build Coastguard Worker
523*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(32, &m_io_uring, 0);
524*25da2beaSAndroid Build Coastguard Worker assert(ret >= 0);
525*25da2beaSAndroid Build Coastguard Worker ret = test(&m_io_uring, args);
526*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
527*25da2beaSAndroid Build Coastguard Worker return ret;
528*25da2beaSAndroid Build Coastguard Worker }
529*25da2beaSAndroid Build Coastguard Worker
test_multishot_accept(int count,bool before)530*25da2beaSAndroid Build Coastguard Worker static int test_multishot_accept(int count, bool before)
531*25da2beaSAndroid Build Coastguard Worker {
532*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
533*25da2beaSAndroid Build Coastguard Worker int ret;
534*25da2beaSAndroid Build Coastguard Worker struct accept_test_args args = {
535*25da2beaSAndroid Build Coastguard Worker .queue_accept_before_connect = before,
536*25da2beaSAndroid Build Coastguard Worker .multishot = true,
537*25da2beaSAndroid Build Coastguard Worker .extra_loops = count - 1
538*25da2beaSAndroid Build Coastguard Worker };
539*25da2beaSAndroid Build Coastguard Worker
540*25da2beaSAndroid Build Coastguard Worker if (no_accept_multi)
541*25da2beaSAndroid Build Coastguard Worker return 0;
542*25da2beaSAndroid Build Coastguard Worker
543*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
544*25da2beaSAndroid Build Coastguard Worker assert(ret >= 0);
545*25da2beaSAndroid Build Coastguard Worker ret = test(&m_io_uring, args);
546*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
547*25da2beaSAndroid Build Coastguard Worker return ret;
548*25da2beaSAndroid Build Coastguard Worker }
549*25da2beaSAndroid Build Coastguard Worker
test_accept_multishot_wrong_arg()550*25da2beaSAndroid Build Coastguard Worker static int test_accept_multishot_wrong_arg()
551*25da2beaSAndroid Build Coastguard Worker {
552*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
553*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
554*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
555*25da2beaSAndroid Build Coastguard Worker int fd, ret;
556*25da2beaSAndroid Build Coastguard Worker
557*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(4, &m_io_uring, 0);
558*25da2beaSAndroid Build Coastguard Worker assert(ret >= 0);
559*25da2beaSAndroid Build Coastguard Worker
560*25da2beaSAndroid Build Coastguard Worker fd = start_accept_listen(NULL, 0, 0);
561*25da2beaSAndroid Build Coastguard Worker
562*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&m_io_uring);
563*25da2beaSAndroid Build Coastguard Worker io_uring_prep_multishot_accept_direct(sqe, fd, NULL, NULL, 0);
564*25da2beaSAndroid Build Coastguard Worker sqe->file_index = 1;
565*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(&m_io_uring);
566*25da2beaSAndroid Build Coastguard Worker assert(ret == 1);
567*25da2beaSAndroid Build Coastguard Worker
568*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(&m_io_uring, &cqe);
569*25da2beaSAndroid Build Coastguard Worker assert(!ret);
570*25da2beaSAndroid Build Coastguard Worker if (cqe->res != -EINVAL) {
571*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "file index should be IORING_FILE_INDEX_ALLOC \
572*25da2beaSAndroid Build Coastguard Worker if its accept in multishot direct mode\n");
573*25da2beaSAndroid Build Coastguard Worker goto err;
574*25da2beaSAndroid Build Coastguard Worker }
575*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(&m_io_uring, cqe);
576*25da2beaSAndroid Build Coastguard Worker
577*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
578*25da2beaSAndroid Build Coastguard Worker close(fd);
579*25da2beaSAndroid Build Coastguard Worker return 0;
580*25da2beaSAndroid Build Coastguard Worker err:
581*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
582*25da2beaSAndroid Build Coastguard Worker close(fd);
583*25da2beaSAndroid Build Coastguard Worker return 1;
584*25da2beaSAndroid Build Coastguard Worker }
585*25da2beaSAndroid Build Coastguard Worker
586*25da2beaSAndroid Build Coastguard Worker
test_accept_nonblock(bool queue_before_connect,int count)587*25da2beaSAndroid Build Coastguard Worker static int test_accept_nonblock(bool queue_before_connect, int count)
588*25da2beaSAndroid Build Coastguard Worker {
589*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
590*25da2beaSAndroid Build Coastguard Worker int ret;
591*25da2beaSAndroid Build Coastguard Worker struct accept_test_args args = {
592*25da2beaSAndroid Build Coastguard Worker .nonblock = true,
593*25da2beaSAndroid Build Coastguard Worker .queue_accept_before_connect = queue_before_connect,
594*25da2beaSAndroid Build Coastguard Worker .extra_loops = count - 1
595*25da2beaSAndroid Build Coastguard Worker };
596*25da2beaSAndroid Build Coastguard Worker
597*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(32, &m_io_uring, 0);
598*25da2beaSAndroid Build Coastguard Worker assert(ret >= 0);
599*25da2beaSAndroid Build Coastguard Worker ret = test(&m_io_uring, args);
600*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
601*25da2beaSAndroid Build Coastguard Worker return ret;
602*25da2beaSAndroid Build Coastguard Worker }
603*25da2beaSAndroid Build Coastguard Worker
test_accept_fixed(void)604*25da2beaSAndroid Build Coastguard Worker static int test_accept_fixed(void)
605*25da2beaSAndroid Build Coastguard Worker {
606*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
607*25da2beaSAndroid Build Coastguard Worker int ret, fd = -1;
608*25da2beaSAndroid Build Coastguard Worker struct accept_test_args args = {
609*25da2beaSAndroid Build Coastguard Worker .fixed = true
610*25da2beaSAndroid Build Coastguard Worker };
611*25da2beaSAndroid Build Coastguard Worker
612*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(32, &m_io_uring, 0);
613*25da2beaSAndroid Build Coastguard Worker assert(ret >= 0);
614*25da2beaSAndroid Build Coastguard Worker ret = io_uring_register_files(&m_io_uring, &fd, 1);
615*25da2beaSAndroid Build Coastguard Worker assert(ret == 0);
616*25da2beaSAndroid Build Coastguard Worker ret = test(&m_io_uring, args);
617*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
618*25da2beaSAndroid Build Coastguard Worker return ret;
619*25da2beaSAndroid Build Coastguard Worker }
620*25da2beaSAndroid Build Coastguard Worker
test_multishot_fixed_accept(void)621*25da2beaSAndroid Build Coastguard Worker static int test_multishot_fixed_accept(void)
622*25da2beaSAndroid Build Coastguard Worker {
623*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
624*25da2beaSAndroid Build Coastguard Worker int ret, fd[MAX_FDS];
625*25da2beaSAndroid Build Coastguard Worker struct accept_test_args args = {
626*25da2beaSAndroid Build Coastguard Worker .fixed = true,
627*25da2beaSAndroid Build Coastguard Worker .multishot = true
628*25da2beaSAndroid Build Coastguard Worker };
629*25da2beaSAndroid Build Coastguard Worker
630*25da2beaSAndroid Build Coastguard Worker if (no_accept_multi)
631*25da2beaSAndroid Build Coastguard Worker return 0;
632*25da2beaSAndroid Build Coastguard Worker
633*25da2beaSAndroid Build Coastguard Worker memset(fd, -1, sizeof(fd));
634*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
635*25da2beaSAndroid Build Coastguard Worker assert(ret >= 0);
636*25da2beaSAndroid Build Coastguard Worker ret = io_uring_register_files(&m_io_uring, fd, MAX_FDS);
637*25da2beaSAndroid Build Coastguard Worker assert(ret == 0);
638*25da2beaSAndroid Build Coastguard Worker ret = test(&m_io_uring, args);
639*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
640*25da2beaSAndroid Build Coastguard Worker return ret;
641*25da2beaSAndroid Build Coastguard Worker }
642*25da2beaSAndroid Build Coastguard Worker
test_accept_sqpoll(void)643*25da2beaSAndroid Build Coastguard Worker static int test_accept_sqpoll(void)
644*25da2beaSAndroid Build Coastguard Worker {
645*25da2beaSAndroid Build Coastguard Worker struct io_uring m_io_uring;
646*25da2beaSAndroid Build Coastguard Worker struct io_uring_params p = { };
647*25da2beaSAndroid Build Coastguard Worker int ret;
648*25da2beaSAndroid Build Coastguard Worker struct accept_test_args args = { };
649*25da2beaSAndroid Build Coastguard Worker
650*25da2beaSAndroid Build Coastguard Worker p.flags = IORING_SETUP_SQPOLL;
651*25da2beaSAndroid Build Coastguard Worker ret = t_create_ring_params(32, &m_io_uring, &p);
652*25da2beaSAndroid Build Coastguard Worker if (ret == T_SETUP_SKIP)
653*25da2beaSAndroid Build Coastguard Worker return 0;
654*25da2beaSAndroid Build Coastguard Worker else if (ret < 0)
655*25da2beaSAndroid Build Coastguard Worker return ret;
656*25da2beaSAndroid Build Coastguard Worker
657*25da2beaSAndroid Build Coastguard Worker args.accept_should_error = 1;
658*25da2beaSAndroid Build Coastguard Worker if (p.features & IORING_FEAT_SQPOLL_NONFIXED)
659*25da2beaSAndroid Build Coastguard Worker args.accept_should_error = 0;
660*25da2beaSAndroid Build Coastguard Worker
661*25da2beaSAndroid Build Coastguard Worker ret = test(&m_io_uring, args);
662*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&m_io_uring);
663*25da2beaSAndroid Build Coastguard Worker return ret;
664*25da2beaSAndroid Build Coastguard Worker }
665*25da2beaSAndroid Build Coastguard Worker
main(int argc,char * argv[])666*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
667*25da2beaSAndroid Build Coastguard Worker {
668*25da2beaSAndroid Build Coastguard Worker int ret;
669*25da2beaSAndroid Build Coastguard Worker
670*25da2beaSAndroid Build Coastguard Worker if (argc > 1)
671*25da2beaSAndroid Build Coastguard Worker return 0;
672*25da2beaSAndroid Build Coastguard Worker ret = test_accept(1, false);
673*25da2beaSAndroid Build Coastguard Worker if (ret) {
674*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept failed\n");
675*25da2beaSAndroid Build Coastguard Worker return ret;
676*25da2beaSAndroid Build Coastguard Worker }
677*25da2beaSAndroid Build Coastguard Worker if (no_accept)
678*25da2beaSAndroid Build Coastguard Worker return 0;
679*25da2beaSAndroid Build Coastguard Worker
680*25da2beaSAndroid Build Coastguard Worker ret = test_accept(2, false);
681*25da2beaSAndroid Build Coastguard Worker if (ret) {
682*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept(2) failed\n");
683*25da2beaSAndroid Build Coastguard Worker return ret;
684*25da2beaSAndroid Build Coastguard Worker }
685*25da2beaSAndroid Build Coastguard Worker
686*25da2beaSAndroid Build Coastguard Worker ret = test_accept(2, true);
687*25da2beaSAndroid Build Coastguard Worker if (ret) {
688*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept(2, true) failed\n");
689*25da2beaSAndroid Build Coastguard Worker return ret;
690*25da2beaSAndroid Build Coastguard Worker }
691*25da2beaSAndroid Build Coastguard Worker
692*25da2beaSAndroid Build Coastguard Worker ret = test_accept_nonblock(false, 1);
693*25da2beaSAndroid Build Coastguard Worker if (ret) {
694*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_nonblock failed\n");
695*25da2beaSAndroid Build Coastguard Worker return ret;
696*25da2beaSAndroid Build Coastguard Worker }
697*25da2beaSAndroid Build Coastguard Worker
698*25da2beaSAndroid Build Coastguard Worker ret = test_accept_nonblock(true, 1);
699*25da2beaSAndroid Build Coastguard Worker if (ret) {
700*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_nonblock(before, 1) failed\n");
701*25da2beaSAndroid Build Coastguard Worker return ret;
702*25da2beaSAndroid Build Coastguard Worker }
703*25da2beaSAndroid Build Coastguard Worker
704*25da2beaSAndroid Build Coastguard Worker ret = test_accept_nonblock(true, 3);
705*25da2beaSAndroid Build Coastguard Worker if (ret) {
706*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_nonblock(before,3) failed\n");
707*25da2beaSAndroid Build Coastguard Worker return ret;
708*25da2beaSAndroid Build Coastguard Worker }
709*25da2beaSAndroid Build Coastguard Worker
710*25da2beaSAndroid Build Coastguard Worker ret = test_accept_fixed();
711*25da2beaSAndroid Build Coastguard Worker if (ret) {
712*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_fixed failed\n");
713*25da2beaSAndroid Build Coastguard Worker return ret;
714*25da2beaSAndroid Build Coastguard Worker }
715*25da2beaSAndroid Build Coastguard Worker
716*25da2beaSAndroid Build Coastguard Worker ret = test_multishot_fixed_accept();
717*25da2beaSAndroid Build Coastguard Worker if (ret) {
718*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_multishot_fixed_accept failed\n");
719*25da2beaSAndroid Build Coastguard Worker return ret;
720*25da2beaSAndroid Build Coastguard Worker }
721*25da2beaSAndroid Build Coastguard Worker
722*25da2beaSAndroid Build Coastguard Worker ret = test_accept_multishot_wrong_arg();
723*25da2beaSAndroid Build Coastguard Worker if (ret) {
724*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_multishot_wrong_arg failed\n");
725*25da2beaSAndroid Build Coastguard Worker return ret;
726*25da2beaSAndroid Build Coastguard Worker }
727*25da2beaSAndroid Build Coastguard Worker
728*25da2beaSAndroid Build Coastguard Worker ret = test_accept_sqpoll();
729*25da2beaSAndroid Build Coastguard Worker if (ret) {
730*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_sqpoll failed\n");
731*25da2beaSAndroid Build Coastguard Worker return ret;
732*25da2beaSAndroid Build Coastguard Worker }
733*25da2beaSAndroid Build Coastguard Worker
734*25da2beaSAndroid Build Coastguard Worker ret = test_accept_cancel(0, 1, false);
735*25da2beaSAndroid Build Coastguard Worker if (ret) {
736*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_cancel nodelay failed\n");
737*25da2beaSAndroid Build Coastguard Worker return ret;
738*25da2beaSAndroid Build Coastguard Worker }
739*25da2beaSAndroid Build Coastguard Worker
740*25da2beaSAndroid Build Coastguard Worker ret = test_accept_cancel(10000, 1, false);
741*25da2beaSAndroid Build Coastguard Worker if (ret) {
742*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_cancel delay failed\n");
743*25da2beaSAndroid Build Coastguard Worker return ret;
744*25da2beaSAndroid Build Coastguard Worker }
745*25da2beaSAndroid Build Coastguard Worker
746*25da2beaSAndroid Build Coastguard Worker ret = test_accept_cancel(0, 4, false);
747*25da2beaSAndroid Build Coastguard Worker if (ret) {
748*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_cancel nodelay failed\n");
749*25da2beaSAndroid Build Coastguard Worker return ret;
750*25da2beaSAndroid Build Coastguard Worker }
751*25da2beaSAndroid Build Coastguard Worker
752*25da2beaSAndroid Build Coastguard Worker ret = test_accept_cancel(10000, 4, false);
753*25da2beaSAndroid Build Coastguard Worker if (ret) {
754*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_cancel delay failed\n");
755*25da2beaSAndroid Build Coastguard Worker return ret;
756*25da2beaSAndroid Build Coastguard Worker }
757*25da2beaSAndroid Build Coastguard Worker
758*25da2beaSAndroid Build Coastguard Worker ret = test_accept_cancel(0, 1, true);
759*25da2beaSAndroid Build Coastguard Worker if (ret) {
760*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
761*25da2beaSAndroid Build Coastguard Worker return ret;
762*25da2beaSAndroid Build Coastguard Worker }
763*25da2beaSAndroid Build Coastguard Worker
764*25da2beaSAndroid Build Coastguard Worker ret = test_accept_cancel(10000, 1, true);
765*25da2beaSAndroid Build Coastguard Worker if (ret) {
766*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_cancel multishot delay failed\n");
767*25da2beaSAndroid Build Coastguard Worker return ret;
768*25da2beaSAndroid Build Coastguard Worker }
769*25da2beaSAndroid Build Coastguard Worker
770*25da2beaSAndroid Build Coastguard Worker ret = test_accept_cancel(0, 4, true);
771*25da2beaSAndroid Build Coastguard Worker if (ret) {
772*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
773*25da2beaSAndroid Build Coastguard Worker return ret;
774*25da2beaSAndroid Build Coastguard Worker }
775*25da2beaSAndroid Build Coastguard Worker
776*25da2beaSAndroid Build Coastguard Worker ret = test_accept_cancel(10000, 4, true);
777*25da2beaSAndroid Build Coastguard Worker if (ret) {
778*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_cancel multishot delay failed\n");
779*25da2beaSAndroid Build Coastguard Worker return ret;
780*25da2beaSAndroid Build Coastguard Worker }
781*25da2beaSAndroid Build Coastguard Worker
782*25da2beaSAndroid Build Coastguard Worker ret = test_multishot_accept(1, false);
783*25da2beaSAndroid Build Coastguard Worker if (ret) {
784*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_multishot_accept(1, false) failed\n");
785*25da2beaSAndroid Build Coastguard Worker return ret;
786*25da2beaSAndroid Build Coastguard Worker }
787*25da2beaSAndroid Build Coastguard Worker
788*25da2beaSAndroid Build Coastguard Worker ret = test_multishot_accept(1, true);
789*25da2beaSAndroid Build Coastguard Worker if (ret) {
790*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_multishot_accept(1, true) failed\n");
791*25da2beaSAndroid Build Coastguard Worker return ret;
792*25da2beaSAndroid Build Coastguard Worker }
793*25da2beaSAndroid Build Coastguard Worker
794*25da2beaSAndroid Build Coastguard Worker ret = test_accept_many((struct test_accept_many_args) {});
795*25da2beaSAndroid Build Coastguard Worker if (ret) {
796*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_many failed\n");
797*25da2beaSAndroid Build Coastguard Worker return ret;
798*25da2beaSAndroid Build Coastguard Worker }
799*25da2beaSAndroid Build Coastguard Worker
800*25da2beaSAndroid Build Coastguard Worker ret = test_accept_many((struct test_accept_many_args) {
801*25da2beaSAndroid Build Coastguard Worker .usecs = 100000 });
802*25da2beaSAndroid Build Coastguard Worker if (ret) {
803*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_many(sleep) failed\n");
804*25da2beaSAndroid Build Coastguard Worker return ret;
805*25da2beaSAndroid Build Coastguard Worker }
806*25da2beaSAndroid Build Coastguard Worker
807*25da2beaSAndroid Build Coastguard Worker ret = test_accept_many((struct test_accept_many_args) {
808*25da2beaSAndroid Build Coastguard Worker .nonblock = true });
809*25da2beaSAndroid Build Coastguard Worker if (ret) {
810*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_many(nonblock) failed\n");
811*25da2beaSAndroid Build Coastguard Worker return ret;
812*25da2beaSAndroid Build Coastguard Worker }
813*25da2beaSAndroid Build Coastguard Worker
814*25da2beaSAndroid Build Coastguard Worker ret = test_accept_many((struct test_accept_many_args) {
815*25da2beaSAndroid Build Coastguard Worker .nonblock = true,
816*25da2beaSAndroid Build Coastguard Worker .single_sock = true,
817*25da2beaSAndroid Build Coastguard Worker .close_fds = true });
818*25da2beaSAndroid Build Coastguard Worker if (ret) {
819*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_many(nonblock,close) failed\n");
820*25da2beaSAndroid Build Coastguard Worker return ret;
821*25da2beaSAndroid Build Coastguard Worker }
822*25da2beaSAndroid Build Coastguard Worker
823*25da2beaSAndroid Build Coastguard Worker ret = test_accept_pending_on_exit();
824*25da2beaSAndroid Build Coastguard Worker if (ret) {
825*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_accept_pending_on_exit failed\n");
826*25da2beaSAndroid Build Coastguard Worker return ret;
827*25da2beaSAndroid Build Coastguard Worker }
828*25da2beaSAndroid Build Coastguard Worker return 0;
829*25da2beaSAndroid Build Coastguard Worker }
830