blob: 63a0fcbf482f759d07b4573c0c15b3e2a7a1f7dc [file] [log] [blame]
Dmitry V. Levin13c21732015-08-26 12:49:07 +00001/*
Dmitry V. Levin9ad44092016-01-06 11:27:15 +00002 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
Dmitry V. Levin13c21732015-08-26 12:49:07 +00003 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
Dmitry V. Levin0c8853c2016-01-02 13:28:43 +000028#include "tests.h"
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000029#include <assert.h>
Dmitry V. Levinc36270a2016-01-11 02:20:04 +000030#include <fcntl.h>
Dmitry V. Levin13c21732015-08-26 12:49:07 +000031#include <inttypes.h>
32#include <stdio.h>
Dmitry V. Levind1c663a2015-12-16 02:00:01 +000033#include <time.h>
Dmitry V. Levin13c21732015-08-26 12:49:07 +000034#include <unistd.h>
Dmitry V. Levin13c21732015-08-26 12:49:07 +000035#include <sys/syscall.h>
36
37#if defined __NR_io_setup \
38 && defined __NR_io_submit \
39 && defined __NR_io_getevents \
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000040 && defined __NR_io_cancel \
Dmitry V. Levin13c21732015-08-26 12:49:07 +000041 && defined __NR_io_destroy
42# include <linux/aio_abi.h>
43
44int
45main(void)
46{
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000047 const unsigned int sizeof_data0 = 4096;
48 const unsigned int sizeof_data1 = 8192;
49 void *data0 = tail_alloc(sizeof_data0);
50 void *data1 = tail_alloc(sizeof_data1);
Dmitry V. Levin13c21732015-08-26 12:49:07 +000051
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000052 const struct iocb proto_cb[] = {
Dmitry V. Levin13c21732015-08-26 12:49:07 +000053 {
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000054 .aio_data = 0xfeedface11111111,
Dmitry V. Levin13c21732015-08-26 12:49:07 +000055 .aio_reqprio = 11,
56 .aio_buf = (unsigned long) data0,
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000057 .aio_offset = 0xdeface1facefeed,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000058 .aio_nbytes = sizeof_data0
Dmitry V. Levin13c21732015-08-26 12:49:07 +000059 },
60 {
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000061 .aio_data = 0xfeedface22222222,
Dmitry V. Levin13c21732015-08-26 12:49:07 +000062 .aio_reqprio = 22,
63 .aio_buf = (unsigned long) data1,
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000064 .aio_offset = 0xdeface2cafef00d,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000065 .aio_nbytes = sizeof_data1
Dmitry V. Levin13c21732015-08-26 12:49:07 +000066 }
67 };
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000068 const struct iocb *cb = tail_memdup(proto_cb, sizeof(proto_cb));
69
70 const struct iovec proto_iov0[] = {
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000071 {
72 .iov_base = data0,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000073 .iov_len = sizeof_data0 / 4
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000074 },
75 {
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000076 .iov_base = data0 + sizeof_data0 / 4,
77 .iov_len = sizeof_data0 / 4 * 3
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000078 },
79 };
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000080 const struct iovec *iov0 = tail_memdup(proto_iov0, sizeof(proto_iov0));
81
82 const struct iovec proto_iov1[] = {
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000083 {
84 .iov_base = data1,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000085 .iov_len = sizeof_data1 / 4
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000086 },
87 {
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000088 .iov_base = data1 + sizeof_data1 / 4,
89 .iov_len = sizeof_data1 / 4 * 3
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000090 },
91 };
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000092 const struct iovec *iov1 = tail_memdup(proto_iov1, sizeof(proto_iov1));
93
94 const struct iocb proto_cbv[] = {
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000095 {
96 .aio_data = 0xfeed11111111face,
97 .aio_lio_opcode = 7,
98 .aio_reqprio = 111,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +000099 .aio_buf = (unsigned long) iov0,
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000100 .aio_offset = 0xdeface1facefeed,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000101 .aio_nbytes = ARRAY_SIZE(proto_iov0)
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000102 },
103 {
104 .aio_data = 0xfeed22222222face,
105 .aio_lio_opcode = 7,
106 .aio_reqprio = 222,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000107 .aio_buf = (unsigned long) iov1,
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000108 .aio_offset = 0xdeface2cafef00d,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000109 .aio_nbytes = ARRAY_SIZE(proto_iov1)
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000110 }
111 };
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000112 const struct iocb *cbv = tail_memdup(proto_cbv, sizeof(proto_cbv));
113
114 const struct iocb proto_cbc = {
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000115 .aio_data = 0xdeadbeefbadc0ded,
116 .aio_reqprio = 99,
117 .aio_fildes = -42
118 };
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000119 const struct iocb *cbc = tail_memdup(&proto_cbc, sizeof(proto_cbc));
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000120
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000121 const long proto_cbs[] = {
122 (long) &cb[0], (long) &cb[1]
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000123 };
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000124 const long *cbs = tail_memdup(proto_cbs, sizeof(proto_cbs));
125
126 const long proto_cbvs[] = {
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000127 (long) &cbv[0], (long) &cbv[1],
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000128 };
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000129 const long *cbvs = tail_memdup(proto_cbvs, sizeof(proto_cbvs));
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000130
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000131 unsigned long *ctx = tail_alloc(sizeof(unsigned long));
132 *ctx = 0;
133
134 const unsigned int nr = ARRAY_SIZE(proto_cb);
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000135 const unsigned long lnr = (unsigned long) (0xdeadbeef00000000ULL | nr);
136
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000137 const struct io_event *ev = tail_alloc(nr * sizeof(struct io_event));
138 const struct timespec proto_ts = { .tv_nsec = 123456789 };
139 const struct timespec *ts = tail_memdup(&proto_ts, sizeof(proto_ts));
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000140
141 (void) close(0);
142 if (open("/dev/zero", O_RDONLY))
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000143 perror_msg_and_skip("open: %s", "/dev/zero");
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000144
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000145 if (syscall(__NR_io_setup, lnr, ctx))
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000146 perror_msg_and_skip("io_setup");
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000147 printf("io_setup(%u, [%lu]) = 0\n", nr, *ctx);
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000148
Dmitry V. Levin2868e2b2016-05-07 22:40:06 +0000149 assert(syscall(__NR_io_submit, *ctx, -1L, cbs) == -1);
150 printf("io_submit(%lu, -1, %p) = -1 %s (%m)\n",
151 *ctx, cbs, errno2name());
152
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000153 if (syscall(__NR_io_submit, *ctx, nr, cbs) != (long) nr)
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000154 perror_msg_and_skip("io_submit");
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000155 printf("io_submit(%lu, %u, ["
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000156 "{data=%#llx, pread, reqprio=11, fildes=0, "
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000157 "buf=%p, nbytes=%u, offset=%lld}, "
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000158 "{data=%#llx, pread, reqprio=22, fildes=0, "
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000159 "buf=%p, nbytes=%u, offset=%lld}"
160 "]) = %u\n",
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000161 *ctx, nr,
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000162 (unsigned long long) cb[0].aio_data, data0,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000163 sizeof_data0, (long long) cb[0].aio_offset,
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000164 (unsigned long long) cb[1].aio_data, data1,
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000165 sizeof_data1, (long long) cb[1].aio_offset,
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000166 nr);
167
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000168 assert(syscall(__NR_io_getevents, *ctx, nr, nr + 1, ev, ts) == (long) nr);
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000169 printf("io_getevents(%lu, %u, %u, ["
170 "{data=%#llx, obj=%p, res=%u, res2=0}, "
171 "{data=%#llx, obj=%p, res=%u, res2=0}"
172 "], {0, 123456789}) = %u\n",
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000173 *ctx, nr, nr + 1,
174 (unsigned long long) cb[0].aio_data, &cb[0], sizeof_data0,
175 (unsigned long long) cb[1].aio_data, &cb[1], sizeof_data1,
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000176 nr);
177
Dmitry V. Levin5327e9c2016-04-21 20:29:29 +0000178 assert(syscall(__NR_io_cancel, *ctx, cbc, ev) == -1);
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000179 printf("io_cancel(%lu, {data=%#llx, pread, reqprio=99, fildes=-42}, %p) "
Dmitry V. Levin5327e9c2016-04-21 20:29:29 +0000180 "= -1 %s (%m)\n",
181 *ctx, (unsigned long long) cbc->aio_data, ev, errno2name());
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000182
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000183 if (syscall(__NR_io_submit, *ctx, nr, cbvs) != (long) nr)
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000184 perror_msg_and_skip("io_submit");
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000185 printf("io_submit(%lu, %u, ["
186 "{data=%#llx, preadv, reqprio=%hd, fildes=0, "
187 "iovec=[{%p, %u}, {%p, %u}], offset=%lld}, "
188 "{data=%#llx, preadv, reqprio=%hd, fildes=0, "
189 "iovec=[{%p, %u}, {%p, %u}], offset=%lld}"
190 "]) = %u\n",
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000191 *ctx, nr,
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000192 (unsigned long long) cbv[0].aio_data, cbv[0].aio_reqprio,
193 iov0[0].iov_base, (unsigned int) iov0[0].iov_len,
194 iov0[1].iov_base, (unsigned int) iov0[1].iov_len,
195 (long long) cbv[0].aio_offset,
196 (unsigned long long) cbv[1].aio_data, cbv[1].aio_reqprio,
197 iov1[0].iov_base, (unsigned int) iov1[0].iov_len,
198 iov1[1].iov_base, (unsigned int) iov1[1].iov_len,
199 (long long) cbv[1].aio_offset,
200 nr);
201
Dmitry V. Levin68f7a662016-01-13 22:06:18 +0000202 assert(syscall(__NR_io_destroy, *ctx) == 0);
203 printf("io_destroy(%lu) = 0\n", *ctx);
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000204
205 puts("+++ exited with 0 +++");
206 return 0;
207}
208
209#else
210
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000211SKIP_MAIN_UNDEFINED("__NR_io_*")
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000212
213#endif