]> granicus.if.org Git - strace/blob - tests/aio.c
Remove XLAT_END
[strace] / tests / aio.c
1 /*
2  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
3  * Copyright (c) 2015-2019 The strace developers.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8
9 #include "tests.h"
10 #include <fcntl.h>
11 #include <inttypes.h>
12 #include <stdio.h>
13 #include <time.h>
14 #include <unistd.h>
15 #include "scno.h"
16
17 #if defined __NR_io_setup \
18  && defined __NR_io_submit \
19  && defined __NR_io_getevents \
20  && defined __NR_io_cancel \
21  && defined __NR_io_destroy
22 # include <linux/aio_abi.h>
23
24 int
25 main(void)
26 {
27         static const long bogus_ctx =
28                 (long) 0xface1e55deadbeefLL;
29
30         static const char data2[] =
31                 "\0\1\2\3cat test test test 0123456789abcdef";
32
33         const unsigned int sizeof_data0 = 4096;
34         const unsigned int sizeof_data1 = 8192;
35         void *data0 = tail_alloc(sizeof_data0);
36         void *data1 = tail_alloc(sizeof_data1);
37
38         const struct iocb proto_cb[] = {
39                 {
40                         .aio_data = (unsigned long) 0xfeedface11111111ULL,
41                         .aio_reqprio = 11,
42                         .aio_buf = (unsigned long) data0,
43                         .aio_offset = (unsigned long) 0xdeface1facefeedULL,
44                         .aio_nbytes = sizeof_data0
45                 },
46                 {
47                         .aio_data = (unsigned long) 0xfeedface22222222ULL,
48                         .aio_reqprio = 22,
49                         .aio_buf = (unsigned long) data1,
50                         .aio_offset = (unsigned long) 0xdeface2cafef00dULL,
51                         .aio_nbytes = sizeof_data1
52                 }
53         };
54         const struct iocb *cb = tail_memdup(proto_cb, sizeof(proto_cb));
55
56         const struct iovec proto_iov0[] = {
57                 {
58                         .iov_base = data0,
59                         .iov_len = sizeof_data0 / 4
60                 },
61                 {
62                         .iov_base = data0 + sizeof_data0 / 4,
63                         .iov_len = sizeof_data0 / 4 * 3
64                 },
65         };
66         const struct iovec *iov0 = tail_memdup(proto_iov0, sizeof(proto_iov0));
67
68         const struct iovec proto_iov1[] = {
69                 {
70                         .iov_base = data1,
71                         .iov_len = sizeof_data1 / 4
72                 },
73                 {
74                         .iov_base = data1 + sizeof_data1 / 4,
75                         .iov_len = sizeof_data1 / 4 * 3
76                 },
77         };
78         const struct iovec *iov1 = tail_memdup(proto_iov1, sizeof(proto_iov1));
79
80         const struct iocb proto_cbv[] = {
81                 {
82                         .aio_data = (unsigned long) 0xfeed11111111faceULL,
83                         .aio_lio_opcode = 7,
84                         .aio_reqprio = 111,
85                         .aio_buf = (unsigned long) iov0,
86                         .aio_offset = (unsigned long) 0xdeface1facefeedULL,
87                         .aio_nbytes = ARRAY_SIZE(proto_iov0)
88                 },
89                 {
90                         .aio_data = (unsigned long) 0xfeed22222222faceULL,
91                         .aio_lio_opcode = 7,
92                         .aio_reqprio = 222,
93                         .aio_buf = (unsigned long) iov1,
94                         .aio_offset = (unsigned long) 0xdeface2cafef00dULL,
95                         .aio_nbytes = ARRAY_SIZE(proto_iov1)
96                 }
97         };
98         const struct iocb *cbv = tail_memdup(proto_cbv, sizeof(proto_cbv));
99
100         /* For additional decoder testing */
101         const struct iocb proto_cbv2[] = {
102                 {
103                         .aio_data = 0xbadfacedc0ffeeedULL,
104                         .aio_key = 0xdefaced0,
105                         .aio_lio_opcode = 0xf00d,
106                         .aio_reqprio = 0,
107                         .aio_fildes = 0xdefaced1,
108                         .aio_buf = 0,
109                 },
110                 {
111                         .aio_data = 0,
112                         .aio_key = 0xdefaced0,
113                         .aio_lio_opcode = 1,
114                         .aio_reqprio = 0xbeef,
115                         .aio_fildes = 0xdefaced1,
116                         .aio_buf = 0,
117                         /* In order to make record valid */
118                         .aio_nbytes = (size_t) 0x1020304050607080ULL,
119                         .aio_offset = 0xdeadda7abadc0dedULL,
120 # ifdef HAVE_STRUCT_IOCB_AIO_FLAGS
121                         .aio_flags = 0xfacef157,
122                         .aio_resfd = 0xded1ca7e,
123 # endif
124                 },
125                 {
126                         .aio_data = 0,
127                         .aio_key = 0xdefaced0,
128                         .aio_lio_opcode = 1,
129                         .aio_reqprio = 0xbeef,
130                         .aio_fildes = 0xdefaced1,
131                         .aio_buf = 0xbadc0ffeedefacedULL,
132                         .aio_nbytes = 0x8090a0b0c0d0e0f0ULL,
133                         .aio_offset = 0xdeadda7abadc0dedULL,
134                 },
135                 {
136                         .aio_data = 0,
137                         .aio_key = 0xdefaced0,
138                         .aio_lio_opcode = 1,
139                         .aio_reqprio = 0xbeef,
140                         .aio_fildes = 0xdefaced1,
141                         .aio_buf = (unsigned long)data2,
142                         .aio_nbytes = sizeof(data2),
143                         .aio_offset = 0xdeadda7abadc0dedULL,
144                 },
145                 {
146                         .aio_data = 0,
147                         .aio_key = 0xdefaced0,
148                         .aio_lio_opcode = 8,
149                         .aio_reqprio = 0xbeef,
150                         .aio_fildes = 0xdefaced1,
151                         .aio_buf = 0,
152                         .aio_nbytes = 0x8090a0b0c0d0e0f0ULL,
153                         .aio_offset = 0xdeadda7abadc0dedULL,
154                 },
155         };
156         const struct iocb *cbv2 = tail_memdup(proto_cbv2, sizeof(proto_cbv2));
157
158         const struct iocb proto_cbc = {
159                 .aio_data = (unsigned long) 0xdeadbeefbadc0dedULL,
160                 .aio_reqprio = 99,
161                 .aio_fildes = -42
162         };
163         const struct iocb *cbc = tail_memdup(&proto_cbc, sizeof(proto_cbc));
164
165         const long proto_cbs[] = {
166                 (long) &cb[0], (long) &cb[1]
167         };
168         const long *cbs = tail_memdup(proto_cbs, sizeof(proto_cbs));
169
170         const long proto_cbvs[] = {
171                 (long) &cbv[0], (long) &cbv[1],
172         };
173         const long *cbvs = tail_memdup(proto_cbvs, sizeof(proto_cbvs));
174
175         const long proto_cbvs2[] = {
176                 (long) &cbv2[0], (long) &cbv2[1], (long) &cbv2[2],
177                 (long) &cbv2[3], (long) &cbv2[4],
178                 (long) NULL, (long) 0xffffffffffffffffLL,
179         };
180         const long *cbvs2 = tail_memdup(proto_cbvs2, sizeof(proto_cbvs2));
181
182         TAIL_ALLOC_OBJECT_CONST_PTR(unsigned long, ctx);
183         *ctx = 0;
184
185         const unsigned int nr = ARRAY_SIZE(proto_cb);
186         const unsigned long lnr = (unsigned long) (0xdeadbeef00000000ULL | nr);
187
188         const struct io_event *ev = tail_alloc(nr * sizeof(struct io_event));
189         TAIL_ALLOC_OBJECT_CONST_PTR(struct timespec, ts);
190
191         (void) close(0);
192         if (open("/dev/zero", O_RDONLY))
193                 perror_msg_and_skip("open: %s", "/dev/zero");
194
195         long rc = syscall(__NR_io_setup, 0xdeadbeef, NULL);
196         printf("io_setup(%u, NULL) = %s\n", 0xdeadbeef, sprintrc(rc));
197
198         rc = syscall(__NR_io_setup, lnr, ctx + 1);
199         printf("io_setup(%u, %p) = %s\n", nr, ctx + 1, sprintrc(rc));
200
201         if (syscall(__NR_io_setup, lnr, ctx))
202                 perror_msg_and_skip("io_setup");
203         printf("io_setup(%u, [%#lx]) = 0\n", nr, *ctx);
204
205         rc = syscall(__NR_io_submit, bogus_ctx, (long) 0xca7faceddeadf00dLL,
206                      NULL);
207         printf("io_submit(%#lx, %ld, NULL) = %s\n",
208                bogus_ctx, (long) 0xca7faceddeadf00dLL, sprintrc(rc));
209
210         rc = syscall(__NR_io_submit, *ctx, nr, cbs + nr);
211         printf("io_submit(%#lx, %ld, %p) = %s\n",
212                *ctx, (long) nr, cbs + nr, sprintrc(rc));
213
214         rc = syscall(__NR_io_submit, *ctx, -1L, cbs);
215         printf("io_submit(%#lx, -1, %p) = %s\n",
216                *ctx, cbs, sprintrc(rc));
217
218         rc = syscall(__NR_io_submit, *ctx, nr, cbs);
219         if (rc != (long) nr)
220                 perror_msg_and_skip("io_submit");
221         printf("io_submit(%#lx, %u, ["
222                "{aio_data=%#" PRI__x64 ", aio_lio_opcode=IOCB_CMD_PREAD"
223                 ", aio_reqprio=11, aio_fildes=0, aio_buf=%p, aio_nbytes=%u"
224                 ", aio_offset=%" PRI__d64
225                "}, {aio_data=%#" PRI__x64 ", aio_lio_opcode=IOCB_CMD_PREAD"
226                 ", aio_reqprio=22, aio_fildes=0, aio_buf=%p, aio_nbytes=%u"
227                 ", aio_offset=%" PRI__d64 "}]) = %s\n",
228                *ctx, nr,
229                cb[0].aio_data, data0, sizeof_data0, cb[0].aio_offset,
230                cb[1].aio_data, data1, sizeof_data1, cb[1].aio_offset,
231                sprintrc(rc));
232
233         rc = syscall(__NR_io_getevents, bogus_ctx,
234                      (long) 0xca7faceddeadf00dLL, (long) 0xba5e1e505ca571e0LL,
235                      ev + 1, NULL);
236         printf("io_getevents(%#lx, %ld, %ld, %p, NULL) = %s\n",
237                bogus_ctx, (long) 0xca7faceddeadf00dLL,
238                (long) 0xba5e1e505ca571e0LL, ev + 1, sprintrc(rc));
239
240         rc = syscall(__NR_io_getevents, bogus_ctx,
241                      (long) 0xca7faceddeadf00dLL, (long) 0xba5e1e505ca571e0LL,
242                      NULL, ts + 1);
243         printf("io_getevents(%#lx, %ld, %ld, NULL, %p) = %s\n",
244                bogus_ctx, (long) 0xca7faceddeadf00dLL,
245                (long) 0xba5e1e505ca571e0LL, ts + 1, sprintrc(rc));
246
247         ts->tv_sec = 0xdeadbeefU;
248         ts->tv_nsec = 0xfacefeedU;
249         rc = syscall(__NR_io_getevents, bogus_ctx, 0, 0, 0, ts);
250         printf("io_getevents(%#lx, 0, 0, NULL"
251                ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
252                bogus_ctx, (long long) ts->tv_sec,
253                zero_extend_signed_to_ull(ts->tv_nsec), sprintrc(rc));
254
255         ts->tv_sec = (time_t) 0xcafef00ddeadbeefLL;
256         ts->tv_nsec = (long) 0xbadc0dedfacefeedLL;
257         rc = syscall(__NR_io_getevents, bogus_ctx, 0, 0, 0, ts);
258         printf("io_getevents(%#lx, 0, 0, NULL"
259                ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
260                bogus_ctx, (long long) ts->tv_sec,
261                zero_extend_signed_to_ull(ts->tv_nsec), sprintrc(rc));
262
263         ts->tv_sec = 0;
264         ts->tv_nsec = 123456789;
265         rc = syscall(__NR_io_getevents, *ctx, nr, nr + 1, ev, ts);
266         printf("io_getevents(%#lx, %ld, %ld, ["
267                "{data=%#" PRI__x64 ", obj=%p, res=%u, res2=0}, "
268                "{data=%#" PRI__x64 ", obj=%p, res=%u, res2=0}"
269                "], {tv_sec=0, tv_nsec=123456789}) = %s\n",
270                *ctx, (long) nr, (long) (nr + 1),
271                cb[0].aio_data, &cb[0], sizeof_data0,
272                cb[1].aio_data, &cb[1], sizeof_data1,
273                sprintrc(rc));
274
275         rc = syscall(__NR_io_cancel, bogus_ctx, NULL, NULL);
276         printf("io_cancel(%#lx, NULL, NULL) = %s\n", bogus_ctx, sprintrc(rc));
277
278         rc = syscall(__NR_io_cancel, *ctx, cbc + 1, ev);
279         printf("io_cancel(%#lx, %p, %p) = %s\n", *ctx, cbc + 1, ev,
280                sprintrc(rc));
281
282         rc = syscall(__NR_io_cancel, *ctx, cbc, ev);
283         printf("io_cancel(%#lx, {aio_data=%#" PRI__x64
284                 ", aio_lio_opcode=IOCB_CMD_PREAD, aio_reqprio=99"
285                 ", aio_fildes=-42}, %p) = %s\n",
286                *ctx, cbc->aio_data, ev, sprintrc(rc));
287
288         rc = syscall(__NR_io_submit, (unsigned long) 0xfacef157beeff00dULL,
289                      (long) 0xdeadc0defacefeedLL, NULL);
290         printf("io_submit(%#lx, %ld, NULL) = %s\n",
291                (long) 0xfacef157beeff00dULL,
292                (long) 0xdeadc0defacefeedLL, sprintrc(rc));
293
294         rc = syscall(__NR_io_submit, *ctx, -1L, cbvs + nr);
295         printf("io_submit(%#lx, %ld, %p) = %s\n",
296                *ctx, -1L, cbvs + nr, sprintrc(rc));
297
298         printf("io_submit(%#lx, %ld, ["
299                "{aio_data=%#" PRI__x64 ", aio_key=%u"
300                 ", aio_lio_opcode=%hu /* IOCB_CMD_??? */, aio_fildes=%d}"
301                 ", {aio_data=0, aio_key=%u, aio_lio_opcode=IOCB_CMD_PWRITE"
302                 ", aio_reqprio=IOPRIO_PRIO_VALUE(0x5 /* IOPRIO_CLASS_??? */"
303                 ", 7919), aio_fildes=%d, aio_buf=NULL"
304                 ", aio_nbytes=%" PRI__u64 ", aio_offset=%" PRI__d64
305 # ifdef HAVE_STRUCT_IOCB_AIO_FLAGS
306                 ", aio_flags=IOCB_FLAG_RESFD|IOCB_FLAG_IOPRIO|%#x, aio_resfd=%d"
307 # endif
308                "}, {aio_data=0, aio_key=%u, aio_lio_opcode=IOCB_CMD_PWRITE"
309                 ", aio_reqprio=%hd, aio_fildes=%d, aio_buf=%#" PRI__x64
310                 ", aio_nbytes=%" PRI__u64 ", aio_offset=%" PRI__d64
311                "}, {aio_data=0, aio_key=%u, aio_lio_opcode=IOCB_CMD_PWRITE"
312                 ", aio_reqprio=%hd, aio_fildes=%d"
313                 ", aio_buf=\"\\0\\1\\2\\3%.28s\"..."
314                 ", aio_nbytes=%" PRI__u64 ", aio_offset=%" PRI__d64
315                "}, {aio_data=0, aio_key=%u, aio_lio_opcode=IOCB_CMD_PWRITEV"
316                 ", aio_reqprio=%hd, aio_fildes=%d, aio_buf=%#" PRI__x64
317                 ", aio_nbytes=%" PRI__u64 ", aio_offset=%" PRI__d64
318                "}, NULL, %#lx, ... /* %p */]) = ",
319                *ctx, 1057L,
320                cbv2[0].aio_data, cbv2[0].aio_key,
321                cbv2[0].aio_lio_opcode, cbv2[0].aio_fildes,
322                cbv2[1].aio_key, cbv2[1].aio_fildes,
323                cbv2[1].aio_nbytes, cbv2[1].aio_offset,
324 # ifdef HAVE_STRUCT_IOCB_AIO_FLAGS
325                cbv2[1].aio_flags & ~3, cbv2[1].aio_resfd,
326 # endif
327                cbv2[2].aio_key, cbv2[2].aio_reqprio, cbv2[2].aio_fildes,
328                cbv2[2].aio_buf, cbv2[2].aio_nbytes, cbv2[2].aio_offset,
329                cbv2[3].aio_key, cbv2[3].aio_reqprio, cbv2[3].aio_fildes,
330                data2 + 4, cbv2[3].aio_nbytes, cbv2[3].aio_offset,
331                cbv2[4].aio_key, cbv2[4].aio_reqprio, cbv2[4].aio_fildes,
332                cbv2[4].aio_buf, cbv2[4].aio_nbytes, cbv2[4].aio_offset,
333                cbvs2[6], cbvs2 + 7);
334         rc = syscall(__NR_io_submit, *ctx, 1057L, cbvs2);
335         puts(sprintrc(rc));
336
337         rc = syscall(__NR_io_submit, *ctx, nr, cbvs);
338         if (rc != (long) nr)
339                 perror_msg_and_skip("io_submit");
340         printf("io_submit(%#lx, %u, ["
341                "{aio_data=%#" PRI__x64 ", aio_lio_opcode=IOCB_CMD_PREADV"
342                 ", aio_reqprio=%hd, aio_fildes=0, "
343                 "aio_buf=[{iov_base=%p, iov_len=%u}"
344                ", {iov_base=%p, iov_len=%u}], aio_offset=%" PRI__d64 "}, "
345                "{aio_data=%#" PRI__x64 ", aio_lio_opcode=IOCB_CMD_PREADV"
346                 ", aio_reqprio=%hd, aio_fildes=0"
347                 ", aio_buf=[{iov_base=%p, iov_len=%u}"
348                 ", {iov_base=%p, iov_len=%u}], aio_offset=%" PRI__d64 "}"
349                "]) = %s\n",
350                *ctx, nr,
351                cbv[0].aio_data, cbv[0].aio_reqprio,
352                iov0[0].iov_base, (unsigned int) iov0[0].iov_len,
353                iov0[1].iov_base, (unsigned int) iov0[1].iov_len,
354                cbv[0].aio_offset,
355                cbv[1].aio_data, cbv[1].aio_reqprio,
356                iov1[0].iov_base, (unsigned int) iov1[0].iov_len,
357                iov1[1].iov_base, (unsigned int) iov1[1].iov_len,
358                cbv[1].aio_offset,
359                sprintrc(rc));
360
361         rc = syscall(__NR_io_destroy, bogus_ctx);
362         printf("io_destroy(%#lx) = %s\n",
363                bogus_ctx, sprintrc(rc));
364
365         rc = syscall(__NR_io_destroy, *ctx);
366         printf("io_destroy(%#lx) = %s\n", *ctx, sprintrc(rc));
367
368         puts("+++ exited with 0 +++");
369         return 0;
370 }
371
372 #else
373
374 SKIP_MAIN_UNDEFINED("__NR_io_*")
375
376 #endif