blob: fe6f948e0febb13dd74cc2a77ef4e58389482d60 [file] [log] [blame]
Dmitry V. Levin2b640342013-11-11 15:06:18 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "defs.h"
Dmitry V. Levinb7dd5e62014-09-08 15:20:10 +000032#ifdef HAVE_LIBAIO_H
33# include <libaio.h>
Dmitry V. Levin2b640342013-11-11 15:06:18 +000034#endif
35
Dmitry V. Levin2b640342013-11-11 15:06:18 +000036/* Not defined in libaio.h */
37#ifndef IOCB_RESFD
38# define IOCB_RESFD (1 << 0)
39#endif
40
Dmitry V. Levina0bd3742015-04-07 01:36:50 +000041SYS_FUNC(io_setup)
Dmitry V. Levin2b640342013-11-11 15:06:18 +000042{
43 if (entering(tcp))
Elvira Khabirovaafac9f02015-08-18 18:02:20 +030044 tprintf("%u, ", (unsigned int) tcp->u_arg[0]);
Dmitry V. Levin07eaf502015-07-20 18:40:46 +000045 else
Dmitry V. Levin2479ef02015-08-18 14:58:27 +000046 printnum_ulong(tcp, tcp->u_arg[1]);
Dmitry V. Levin2b640342013-11-11 15:06:18 +000047 return 0;
48}
49
Dmitry V. Levina0bd3742015-04-07 01:36:50 +000050SYS_FUNC(io_destroy)
Dmitry V. Levin2b640342013-11-11 15:06:18 +000051{
Dmitry V. Levin07eaf502015-07-20 18:40:46 +000052 tprintf("%lu", tcp->u_arg[0]);
53
54 return RVAL_DECODED;
Dmitry V. Levin2b640342013-11-11 15:06:18 +000055}
56
57#ifdef HAVE_LIBAIO_H
58
59enum iocb_sub {
60 SUB_NONE, SUB_COMMON, SUB_POLL, SUB_VECTOR
61};
62
63static enum iocb_sub
64tprint_lio_opcode(unsigned cmd)
65{
66 static const struct {
67 const char *name;
68 enum iocb_sub sub;
69 } cmds[] = {
70 { "pread", SUB_COMMON },
71 { "pwrite", SUB_COMMON },
72 { "fsync", SUB_NONE },
73 { "fdsync", SUB_NONE },
74 { "op4", SUB_NONE },
75 { "poll", SUB_POLL },
76 { "noop", SUB_NONE },
77 { "preadv", SUB_VECTOR },
78 { "pwritev", SUB_VECTOR },
79 };
80
81 if (cmd < ARRAY_SIZE(cmds)) {
82 tprints(cmds[cmd].name);
83 return cmds[cmd].sub;
84 }
85 tprintf("%u /* SUB_??? */", cmd);
86 return SUB_NONE;
87}
88
89static void
90print_common_flags(struct iocb *iocb)
91{
Dmitry V. Levind93c4e82015-06-17 20:09:13 +000092#ifdef HAVE_STRUCT_IOCB_U_C_FLAGS
Dmitry V. Levin2b640342013-11-11 15:06:18 +000093 if (iocb->u.c.flags & IOCB_RESFD)
94 tprintf(", resfd=%d", iocb->u.c.resfd);
95 if (iocb->u.c.flags & ~IOCB_RESFD)
96 tprintf(", flags=%x", iocb->u.c.flags);
Dmitry V. Levinb7dd5e62014-09-08 15:20:10 +000097#else
98# warning "libaio.h is too old => limited io_submit decoding"
99#endif
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000100}
101
102#endif /* HAVE_LIBAIO_H */
103
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000104SYS_FUNC(io_submit)
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000105{
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000106#ifdef HAVE_LIBAIO_H
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000107 long nr = tcp->u_arg[1];
108 /* if nr <= 0, we end up printing just "[]" */
109 tprintf("%lu, %ld, [", tcp->u_arg[0], tcp->u_arg[1]);
110 {
111 long i;
112 struct iocb **iocbs = (void *)tcp->u_arg[2];
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000113//FIXME: decoding of 32-bit call by 64-bit strace
114
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000115 for (i = 0; i < nr; i++, iocbs++) {
116 enum iocb_sub sub;
117 struct iocb *iocbp;
118 struct iocb iocb;
119 if (i)
120 tprints(", ");
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000121
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000122 if (umove_or_printaddr(tcp, (unsigned long)iocbs, &iocbp)) {
123 /* No point in trying to read iocbs+1 etc */
124 /* (nr can be ridiculously large): */
125 break;
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000126 }
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000127 tprints("{");
128 if (umove_or_printaddr(tcp, (unsigned long)iocbp, &iocb)) {
129 tprints("}");
130 continue;
131 }
132 if (iocb.data) {
133 tprints("data=");
134 printaddr((long) iocb.data);
135 tprints(", ");
136 }
137 if (iocb.key)
138 tprintf("key=%u, ", iocb.key);
139 sub = tprint_lio_opcode(iocb.aio_lio_opcode);
140 if (iocb.aio_reqprio)
141 tprintf(", reqprio=%d", iocb.aio_reqprio);
142 tprintf(", filedes=%d", iocb.aio_fildes);
143 switch (sub) {
144 case SUB_COMMON:
145#if HAVE_DECL_IO_CMD_PWRITE
146 if (iocb.aio_lio_opcode == IO_CMD_PWRITE) {
147 tprints(", str=");
148 printstr(tcp, (unsigned long)iocb.u.c.buf,
149 iocb.u.c.nbytes);
150 } else
151#endif
152 {
153 tprints(", buf=");
154 printaddr((long) iocb.u.c.buf);
155 }
156 tprintf(", nbytes=%lu, offset=%lld",
157 iocb.u.c.nbytes,
158 iocb.u.c.offset);
159 print_common_flags(&iocb);
160 break;
161 case SUB_VECTOR:
162 tprintf(", %lld", iocb.u.v.offset);
163 print_common_flags(&iocb);
164 tprints(", ");
165 tprint_iov(tcp, iocb.u.v.nr,
166 (unsigned long)iocb.u.v.vec,
167#if HAVE_DECL_IO_CMD_PWRITEV
168 iocb.aio_lio_opcode == IO_CMD_PWRITEV
169#else
170 0
171#endif
172 );
173 break;
174 case SUB_POLL:
175 tprintf(", %x", iocb.u.poll.events);
176 break;
177 case SUB_NONE:
178 break;
179 }
180 tprints("}");
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000181 }
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000182 }
183 tprints("]");
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000184#else
Dmitry V. Levinb7dd5e62014-09-08 15:20:10 +0000185# warning "libaio.h is not available => no io_submit decoding"
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000186 tprintf("%lu, %ld, %#lx", tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
187#endif
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000188 return RVAL_DECODED;
189}
190
191static int
192print_io_event(struct tcb *tcp, const long addr)
193{
194#ifdef HAVE_LIBAIO_H
195 struct io_event event;
196
197 if (umove_or_printaddr(tcp, addr, &event))
198 return -1;
199 tprints("{data=");
200 printaddr((long) event.data);
201 tprints(", obj=");
202 printaddr((long) event.obj);
203 tprintf(", res=%ld, res2=%ld}", event.res, event.res2);
204#else
205 printaddr(tcp->u_arg[2]);
206#endif
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000207 return 0;
208}
209
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000210SYS_FUNC(io_cancel)
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000211{
212 if (entering(tcp)) {
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000213 tprintf("%lu, ", tcp->u_arg[0]);
214#ifdef HAVE_LIBAIO_H
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000215 struct iocb iocb;
216
217 if (!umove_or_printaddr(tcp, tcp->u_arg[1], &iocb)) {
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000218 tprintf("{%p, %u, %u, %u, %d}, ",
219 iocb.data, iocb.key,
220 (unsigned)iocb.aio_lio_opcode,
221 (unsigned)iocb.aio_reqprio, iocb.aio_fildes);
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000222 }
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000223#else
224 printaddr(tcp->u_arg[1]);
225#endif
226 } else {
227 print_io_event(tcp, tcp->u_arg[2]);
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000228 }
229 return 0;
230}
231
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000232SYS_FUNC(io_getevents)
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000233{
234 if (entering(tcp)) {
235 tprintf("%ld, %ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1],
236 tcp->u_arg[2]);
237 } else {
238 if (tcp->u_rval == 0) {
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000239 tprints("[]");
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000240 } else {
241#ifdef HAVE_LIBAIO_H
242 struct io_event *events = (void *)tcp->u_arg[3];
243 long i, nr = tcp->u_rval;
244
245 for (i = 0; i < nr; i++, events++) {
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000246 if (i == 0)
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000247 tprints("[");
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000248 else
249 tprints(", ");
250
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000251 if (print_io_event(tcp, (long)events))
252 break;
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000253 }
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000254 tprints("], ");
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000255#else
Dmitry V. Levin07eaf502015-07-20 18:40:46 +0000256 printaddr(tcp->u_arg[3]);
Dmitry V. Levin2b640342013-11-11 15:06:18 +0000257#endif
258 }
259
260 print_timespec(tcp, tcp->u_arg[4]);
261 }
262 return 0;
263}