1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) 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" 32 #ifdef HAVE_LIBAIO_H 33 # include <libaio.h> 34 #endif 35 36 /* Not defined in libaio.h */ 37 #ifndef IOCB_RESFD 38 # define IOCB_RESFD (1 << 0) 39 #endif 40 41 SYS_FUNC(io_setup) 42 { 43 if (entering(tcp)) 44 tprintf("%ld, ", tcp->u_arg[0]); 45 else { 46 if (syserror(tcp)) 47 tprintf("0x%0lx", tcp->u_arg[1]); 48 else { 49 unsigned long user_id; 50 if (umove(tcp, tcp->u_arg[1], &user_id) == 0) 51 tprintf("{%lu}", user_id); 52 else 53 tprints("{...}"); 54 } 55 } 56 return 0; 57 } 58 59 SYS_FUNC(io_destroy) 60 { 61 if (entering(tcp)) 62 tprintf("%lu", tcp->u_arg[0]); 63 return 0; 64 } 65 66 #ifdef HAVE_LIBAIO_H 67 68 enum iocb_sub { 69 SUB_NONE, SUB_COMMON, SUB_POLL, SUB_VECTOR 70 }; 71 72 static enum iocb_sub 73 tprint_lio_opcode(unsigned cmd) 74 { 75 static const struct { 76 const char *name; 77 enum iocb_sub sub; 78 } cmds[] = { 79 { "pread", SUB_COMMON }, 80 { "pwrite", SUB_COMMON }, 81 { "fsync", SUB_NONE }, 82 { "fdsync", SUB_NONE }, 83 { "op4", SUB_NONE }, 84 { "poll", SUB_POLL }, 85 { "noop", SUB_NONE }, 86 { "preadv", SUB_VECTOR }, 87 { "pwritev", SUB_VECTOR }, 88 }; 89 90 if (cmd < ARRAY_SIZE(cmds)) { 91 tprints(cmds[cmd].name); 92 return cmds[cmd].sub; 93 } 94 tprintf("%u /* SUB_??? */", cmd); 95 return SUB_NONE; 96 } 97 98 static void 99 print_common_flags(struct iocb *iocb) 100 { 101 #if HAVE_STRUCT_IOCB_U_C_FLAGS 102 if (iocb->u.c.flags & IOCB_RESFD) 103 tprintf(", resfd=%d", iocb->u.c.resfd); 104 if (iocb->u.c.flags & ~IOCB_RESFD) 105 tprintf(", flags=%x", iocb->u.c.flags); 106 #else 107 # warning "libaio.h is too old => limited io_submit decoding" 108 #endif 109 } 110 111 #endif /* HAVE_LIBAIO_H */ 112 113 SYS_FUNC(io_submit) 114 { 115 if (entering(tcp)) { 116 #ifdef HAVE_LIBAIO_H 117 long nr = tcp->u_arg[1]; 118 /* if nr <= 0, we end up printing just "{}" */ 119 tprintf("%lu, %ld, {", tcp->u_arg[0], tcp->u_arg[1]); 120 { 121 long i; 122 struct iocb **iocbs = (void *)tcp->u_arg[2]; 123 //FIXME: decoding of 32-bit call by 64-bit strace 124 125 for (i = 0; i < nr; i++, iocbs++) { 126 enum iocb_sub sub; 127 struct iocb *iocbp; 128 struct iocb iocb; 129 if (i) 130 tprints(", "); 131 132 if (umove(tcp, (unsigned long)iocbs, &iocbp)) { 133 tprintf("%#lx", (unsigned long)iocbs); 134 /* No point in trying to read iocbs+1 etc */ 135 /* (nr can be ridiculously large): */ 136 break; 137 } 138 if (umove(tcp, (unsigned long)iocbp, &iocb)) { 139 tprintf("{%#lx}", (unsigned long)iocbp); 140 continue; 141 } 142 tprints("{"); 143 if (iocb.data) 144 tprintf("data:%p, ", iocb.data); 145 if (iocb.key) 146 tprintf("key:%u, ", iocb.key); 147 sub = tprint_lio_opcode(iocb.aio_lio_opcode); 148 if (iocb.aio_reqprio) 149 tprintf(", reqprio:%d", iocb.aio_reqprio); 150 tprintf(", filedes:%d", iocb.aio_fildes); 151 switch (sub) { 152 case SUB_COMMON: 153 #if HAVE_DECL_IO_CMD_PWRITE 154 if (iocb.aio_lio_opcode == IO_CMD_PWRITE) { 155 tprints(", str:"); 156 printstr(tcp, (unsigned long)iocb.u.c.buf, 157 iocb.u.c.nbytes); 158 } else 159 #endif 160 tprintf(", buf:%p", iocb.u.c.buf); 161 tprintf(", nbytes:%lu, offset:%lld", 162 iocb.u.c.nbytes, 163 iocb.u.c.offset); 164 print_common_flags(&iocb); 165 break; 166 case SUB_VECTOR: 167 tprintf(", %lld", iocb.u.v.offset); 168 print_common_flags(&iocb); 169 tprints(", "); 170 tprint_iov(tcp, iocb.u.v.nr, 171 (unsigned long)iocb.u.v.vec, 172 #if HAVE_DECL_IO_CMD_PWRITEV 173 iocb.aio_lio_opcode == IO_CMD_PWRITEV 174 #else 175 0 176 #endif 177 ); 178 break; 179 case SUB_POLL: 180 tprintf(", %x", iocb.u.poll.events); 181 break; 182 case SUB_NONE: 183 break; 184 } 185 tprints("}"); 186 } 187 } 188 tprints("}"); 189 #else 190 # warning "libaio.h is not available => no io_submit decoding" 191 tprintf("%lu, %ld, %#lx", tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]); 192 #endif 193 } 194 return 0; 195 } 196 197 SYS_FUNC(io_cancel) 198 { 199 if (entering(tcp)) { 200 #ifdef HAVE_LIBAIO_H 201 struct iocb iocb; 202 #endif 203 tprintf("%lu, ", tcp->u_arg[0]); 204 #ifdef HAVE_LIBAIO_H 205 if (umove(tcp, tcp->u_arg[1], &iocb) == 0) { 206 tprintf("{%p, %u, %u, %u, %d}, ", 207 iocb.data, iocb.key, 208 (unsigned)iocb.aio_lio_opcode, 209 (unsigned)iocb.aio_reqprio, iocb.aio_fildes); 210 } else 211 #endif 212 tprints("{...}, "); 213 } else { 214 if (tcp->u_rval < 0) 215 tprints("{...}"); 216 else { 217 #ifdef HAVE_LIBAIO_H 218 struct io_event event; 219 if (umove(tcp, tcp->u_arg[2], &event) == 0) 220 tprintf("{%p, %p, %ld, %ld}", 221 event.data, event.obj, 222 event.res, event.res2); 223 else 224 #endif 225 tprints("{...}"); 226 } 227 } 228 return 0; 229 } 230 231 SYS_FUNC(io_getevents) 232 { 233 if (entering(tcp)) { 234 tprintf("%ld, %ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1], 235 tcp->u_arg[2]); 236 } else { 237 if (tcp->u_rval == 0) { 238 tprints("{}"); 239 } else { 240 #ifdef HAVE_LIBAIO_H 241 struct io_event *events = (void *)tcp->u_arg[3]; 242 long i, nr = tcp->u_rval; 243 244 for (i = 0; i < nr; i++, events++) { 245 struct io_event event; 246 247 if (i == 0) 248 tprints("{"); 249 else 250 tprints(", "); 251 252 if (umove(tcp, (unsigned long)events, &event) != 0) { 253 tprints("{...}"); 254 continue; 255 } 256 tprintf("{%p, %p, %ld, %ld}", event.data, 257 event.obj, event.res, event.res2); 258 } 259 tprints("}, "); 260 #else 261 tprints("{...}"); 262 #endif 263 } 264 265 print_timespec(tcp, tcp->u_arg[4]); 266 } 267 return 0; 268 } 269