[patch] SG_IO ioctl

Dmitry V. Levin ldv at altlinux.org
Thu Mar 22 23:09:15 UTC 2007


Hi,

On Mon, Mar 19, 2007 at 06:00:17PM +0100, Vladimir Nadvornik wrote:
> On Thursday 15 March 2007 02:11, Dmitry V. Levin wrote:
[...]
> Thank you for feedback. Please see the updated patch.

Thank you for the patch.

I attached my edition of this patch.  Besides of whitespace difference,
there are 5 changes:
+ scsi_ioctl() prototype is added to defs.h;
+ buffer address is printed not only when umoven() fails but also when
malloc() fails, for consistency;
+ malloc/umoven/free code is incapsulated into print_sg_io_buffer()
function;
+ in print_sg_io_buffer(), max_strlen limit is applied;
+ format string for flags, host_status, driver_status, and info fields is
changed from %0Nx to more general %#x.

Please have a look.

> > > +		if (exiting(tcp)) {
> > > +			struct sg_io_hdr sg_io;
> > > +			if (umove(tcp, arg, &sg_io) >= 0) {
> > > +				print_sg_io_res(tcp, &sg_io);
> > > +			}
> > > +		}
> >
> > Looks like syserror(tcp) check is missing here.
> 
> If there is an error, it prints the content of the structure as it was 
> passed in. I think that it is acceptable behavior and special handling
> is not necessary.

I still not sure this is right way to do.
It depends whether kernel fills "output" part of struct sg_io_hdr in case
of an error.  If it does, then it should be parsed, otherwise there are no
reason to output it.


-- 
ldv
-------------- next part --------------
diff --git a/strace/Makefile.am b/strace/Makefile.am
index a9972fe..04a9acf 100644
--- a/strace/Makefile.am
+++ b/strace/Makefile.am
@@ -15,7 +15,7 @@ INCLUDES = -I$(OS)/$(ARCH) -I$(srcdir)/$(OS)/$(ARCH) -I$(OS) -I$(srcdir)/$(OS)
 strace_SOURCES = strace.c syscall.c count.c util.c desc.c file.c ipc.c \
 		 io.c ioctl.c mem.c net.c process.c bjm.c quota.c \
 		 resource.c signal.c sock.c system.c term.c time.c \
-		 proc.c stream.c
+		 proc.c scsi.c stream.c
 noinst_HEADERS = defs.h
 
 EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \
diff --git a/strace/defs.h b/strace/defs.h
index c25fde8..7f9af82 100644
--- a/strace/defs.h
+++ b/strace/defs.h
@@ -493,6 +493,7 @@ extern int proc_ioctl P((struct tcb *, int, int));
 extern int stream_ioctl P((struct tcb *, int, int));
 #ifdef LINUX
 extern int rtc_ioctl P((struct tcb *, long, long));
+extern int scsi_ioctl P((struct tcb *, long, long));
 #endif
 
 extern void tv_tv P((struct timeval *, int, int));
diff --git a/strace/ioctl.c b/strace/ioctl.c
index d99b669..906c71e 100644
--- a/strace/ioctl.c
+++ b/strace/ioctl.c
@@ -152,6 +152,8 @@ long code, arg;
 #ifdef LINUX
 	case 'p':
 		return rtc_ioctl(tcp, code, arg);
+	case 0x22:
+		return scsi_ioctl(tcp, code, arg);
 #endif
 	default:
 		break;
diff --git a/strace/scsi.c b/strace/scsi.c
new file mode 100644
index 0000000..ac53248
--- /dev/null
+++ b/strace/scsi.c
@@ -0,0 +1,112 @@
+#include "defs.h"
+
+#ifdef LINUX
+#include <sys/ioctl.h>
+#include <scsi/sg.h>
+
+static const struct xlat sg_io_dxfer_direction[] = {
+	{SG_DXFER_NONE,        "SG_DXFER_NONE"},
+	{SG_DXFER_TO_DEV,      "SG_DXFER_TO_DEV"},
+	{SG_DXFER_FROM_DEV,    "SG_DXFER_FROM_DEV"},
+	{SG_DXFER_TO_FROM_DEV, "SG_DXFER_TO_FROM_DEV"},
+	{0, NULL}
+};
+
+static void
+print_sg_io_buffer(struct tcb *tcp, unsigned char *addr, int len)
+{
+	unsigned char *buf = NULL;
+	int     allocated, i;
+
+	if (len == 0)
+		return;
+	allocated = (len > max_strlen) ? max_strlen : len;
+	if (len < 0 ||
+	    (buf = malloc(allocated)) == NULL ||
+	    umoven(tcp, (unsigned long) addr, allocated, (char *) buf) < 0) {
+		tprintf("%p", addr);
+		free(buf);
+		return;
+	}
+	tprintf("%02x", buf[0]);
+	for (i = 1; i < allocated; ++i)
+		tprintf(", %02x", buf[i]);
+	free(buf);
+	if (allocated != len)
+		tprintf(", ...");
+}
+
+static void
+print_sg_io_req(struct tcb *tcp, struct sg_io_hdr *sg_io)
+{
+	tprintf("{'%c', ", sg_io->interface_id);
+	printxval(sg_io_dxfer_direction, sg_io->dxfer_direction,
+		  "SG_DXFER_???");
+	tprintf(", cmd[%u]=[", sg_io->cmd_len);
+	print_sg_io_buffer(tcp, sg_io->cmdp, sg_io->cmd_len);
+	tprintf("], mx_sb_len=%d, ", sg_io->mx_sb_len);
+	tprintf("iovec_count=%d, ", sg_io->iovec_count);
+	tprintf("dxfer_len=%u, ", sg_io->dxfer_len);
+	tprintf("timeout=%u, ", sg_io->timeout);
+	tprintf("flags=%#x, ", sg_io->flags);
+
+	if (sg_io->dxfer_direction == SG_DXFER_TO_DEV ||
+	    sg_io->dxfer_direction == SG_DXFER_TO_FROM_DEV) {
+		tprintf("data[%u]=[", sg_io->dxfer_len);
+		printstr(tcp, (unsigned long) sg_io->dxferp,
+			 sg_io->dxfer_len);
+		tprintf("], ");
+	}
+}
+
+static void
+print_sg_io_res(struct tcb *tcp, struct sg_io_hdr *sg_io)
+{
+	if (sg_io->dxfer_direction == SG_DXFER_FROM_DEV ||
+	    sg_io->dxfer_direction == SG_DXFER_TO_FROM_DEV) {
+		tprintf("data[%u]=[", sg_io->dxfer_len);
+		printstr(tcp, (unsigned long) sg_io->dxferp,
+			 sg_io->dxfer_len);
+		tprintf("], ");
+	}
+	tprintf("status=%02x, ", sg_io->status);
+	tprintf("masked_status=%02x, ", sg_io->masked_status);
+	tprintf("sb[%u]=[", sg_io->sb_len_wr);
+	print_sg_io_buffer(tcp, sg_io->sbp, sg_io->sb_len_wr);
+	tprintf("], host_status=%#x, ", sg_io->host_status);
+	tprintf("driver_status=%#x, ", sg_io->driver_status);
+	tprintf("resid=%d, ", sg_io->resid);
+	tprintf("duration=%d, ", sg_io->duration);
+	tprintf("info=%#x}", sg_io->info);
+}
+
+int
+scsi_ioctl(struct tcb *tcp, long code, long arg)
+{
+	switch (code) {
+	case SG_IO:
+		if (entering(tcp)) {
+			struct sg_io_hdr sg_io;
+
+			if (umove(tcp, arg, &sg_io) < 0)
+				tprintf(", %#lx", arg);
+			else {
+				tprintf(", ");
+				print_sg_io_req(tcp, &sg_io);
+			}
+		}
+		if (exiting(tcp)) {
+			struct sg_io_hdr sg_io;
+
+			if (umove(tcp, arg, &sg_io) >= 0)
+				print_sg_io_res(tcp, &sg_io);
+		}
+		break;
+	default:
+		if (entering(tcp))
+			tprintf(", %#lx", arg);
+		break;
+	}
+	return 1;
+}
+#endif /* LINUX */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20070323/c5c5c5e0/attachment.bin>


More information about the Strace-devel mailing list