[PATCH] Improve io_submit decoding
Andi Kleen
ak at linux.intel.com
Fri Apr 8 05:07:15 UTC 2011
The io_submit handler didn't show a lot of the important information
in iocb passed to io_submit, like how much This patch improves this.
Also I prefixed the fields with names to make it easier to read. Otherwise
-- since there are so many of them -- it's hard to figure out which
numbers are which.
And it now only shows some fields if they have a != 0 value.
This still doesn't dump the actual data in IO like read/write, just the
pointer to it and the size. But that could be added on top of this patch
easily.
Also I was wondering if configure should error out when libaio-devel
is not installed. Right now when it's not there the code is just
silently stubbed out. At least the SUSE rpm has exactly this problem.
-Andi
diff --git a/desc.c b/desc.c
index 2b9f30a..57dc755 100644
--- a/desc.c
+++ b/desc.c
@@ -806,6 +806,51 @@ sys_io_destroy(struct tcb *tcp)
return 0;
}
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*(x)))
+
+enum iocb_sub {
+ SUB_NONE, SUB_COMMON, SUB_POLL, SUB_VECTOR
+};
+
+static const char *
+iocb_cmd_lookup(unsigned cmd, enum iocb_sub *sub)
+{
+ static char buf[20];
+ static struct {
+ const char *name;
+ enum iocb_sub sub;
+ } cmds[] = {
+ { "pread", SUB_COMMON },
+ { "pwrite", SUB_COMMON },
+ { "fsync", SUB_NONE },
+ { "fdsync", SUB_NONE },
+ { "op4", SUB_NONE },
+ { "poll", SUB_POLL },
+ { "noop", SUB_NONE },
+ { "preadv", SUB_VECTOR },
+ { "pwritev", SUB_VECTOR },
+ };
+
+ if (cmd < ARRAY_SIZE(cmds)) {
+ *sub = cmds[cmd].sub;
+ return cmds[cmd].name;
+ }
+ *sub = SUB_NONE;
+ snprintf(buf, sizeof buf, "?%u?", cmd);
+ return buf;
+}
+
+/* Not defined in libaio.h */
+#define IOCB_RESFD (1 << 0)
+
+static void
+print_common_flags(struct iocb *iocb)
+{
+ if (iocb->u.c.flags & IOCB_RESFD)
+ tprintf("resfd=%d, ", iocb->u.c.resfd);
+ if (iocb->u.c.flags & ~IOCB_RESFD)
+ tprintf("flags=%x, ", iocb->u.c.flags);
+}
int
sys_io_submit(struct tcb *tcp)
{
@@ -822,7 +867,9 @@ sys_io_submit(struct tcb *tcp)
struct iocb *iocbp, **iocbs = (void *)tcp->u_arg[2];
for (i = 0; i < nr; i++, iocbs++) {
+ enum iocb_sub sub;
struct iocb iocb;
+ int k;
if (i == 0)
tprintf("{");
else
@@ -833,10 +880,45 @@ sys_io_submit(struct tcb *tcp)
tprintf("{...}");
continue;
}
- tprintf("{%p, %u, %hu, %hu, %d}",
- iocb.data, iocb.key,
- iocb.aio_lio_opcode,
- iocb.aio_reqprio, iocb.aio_fildes);
+ tprintf("{");
+ if (iocb.data)
+ tprintf("data:%p, ", iocb.data);
+ if (iocb.key)
+ tprintf("key:%u, ", iocb.key);
+ tprintf("%s, ", iocb_cmd_lookup(iocb.aio_lio_opcode, &sub));
+ if (iocb.aio_reqprio)
+ tprintf("reqprio:%d, ", iocb.aio_reqprio);
+ tprintf("filedes:%d", iocb.aio_fildes);
+ switch (sub) {
+ case SUB_COMMON:
+ tprintf(", buf:%p, nbytes:%lu, offset:%llx",
+ iocb.u.c.buf,
+ iocb.u.c.nbytes,
+ iocb.u.c.offset);
+ print_common_flags(&iocb);
+ break;
+ case SUB_VECTOR:
+ tprintf(", %llx, ", iocb.u.v.offset);
+ print_common_flags(&iocb);
+ for (k = 0; k < iocb.u.v.nr; k++) {
+ struct iovec iov;
+ tprintf("%s", k == 0 ? "" : ", ");
+ if (umove(tcp, (unsigned long)iocb.u.v.vec +
+ sizeof(struct iovec)*k, &iov))
+ tprintf("{...}");
+ else
+ tprintf("{ %p, %lu }",
+ iov.iov_base,
+ iov.iov_len);
+ }
+ break;
+ case SUB_POLL:
+ tprintf(", %x", iocb.u.poll.events);
+ break;
+ case SUB_NONE:
+ break;
+ }
+ tprintf("}");
}
if (i)
tprintf("}");
--
ak at linux.intel.com -- Speaking for myself only
More information about the Strace-devel
mailing list