From: Jeff M. <je...@su...> - 2009-11-30 21:01:06
|
This patch adds support for blkdev_ioctl()-handled ioctls. Signed-off-by: Jeff Mahoney <je...@su...> --- Makefile.am | 2 block.c | 221 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ defs.h | 1 ioctl.c | 3 linux/ioctlent.sh | 3 5 files changed, 229 insertions(+), 1 deletion(-) --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,7 @@ INCLUDES = -I$(OS)/$(ARCH) -I$(srcdir)/$ 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 scsi.c stream.c + proc.c scsi.c stream.c block.c noinst_HEADERS = defs.h EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \ --- /dev/null +++ b/block.c @@ -0,0 +1,221 @@ +#include "defs.h" +#ifdef LINUX +#include <stdint.h> +#include <linux/blkpg.h> +#include <linux/fs.h> +#include <linux/hdreg.h> +#include <linux/blktrace_api.h> + +#ifndef BLKALIGNOFF +#define BLKALIGNOFF _IO(0x12,122) +#endif +#ifndef BLKPBSZGET +#define BLKPBSZGET _IO(0x12,123) +#endif +#ifndef BLKIOMIN +#define BLKIOMIN _IO(0x12,120) +#endif +#ifndef BLKIOOPT +#define BLKIOOPT _IO(0x12,121) +#endif + + +static void +print_blkpg_req(struct tcb *tcp, struct blkpg_ioctl_arg *blkpg) +{ + struct blkpg_partition p; + if (!(blkpg->op == BLKPG_ADD_PARTITION || + blkpg->op == BLKPG_DEL_PARTITION)) { + tprintf("{%d, <invalid>", blkpg->op); + return; + } + + tprintf("{%s, ", blkpg->op == BLKPG_ADD_PARTITION ? + "BLKPG_ADD_PARTITION" : "BLKPG_DEL_PARTITION"); + tprintf("flags=%d, datalen=%d, ", blkpg->flags, blkpg->datalen); + + if (umove(tcp, (unsigned long)blkpg->data, &p) < 0) { + tprintf("%#lx", (unsigned long)blkpg->data); + return; + } + + tprintf("{start=%lld, length=%lld, pno=%d, ", + p.start, p.length, p.pno); + + tprintf("devname=\"%s\", volname=\"%s\"}", + p.devname, p.volname); +} + +int +block_ioctl(struct tcb *tcp, long code, long arg) +{ + switch (code) { + + /* These pass arg as a value, not a pointer */ + case BLKRASET: + case BLKFRASET: + if (entering(tcp)) + tprintf(", %ld", arg); + break; + + /* Just pass in a signed int */ + case BLKROSET: + case BLKBSZSET: + if (entering(tcp)) { + int int_val; + if (umove(tcp, arg, &int_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %d", int_val); + } + break; + + /* Just return an unsigned short */ + case BLKSECTGET: + if (exiting(tcp)) { + unsigned short ushort_val; + if (umove(tcp, arg, &ushort_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %hu", ushort_val); + } + break; + + /* Just return a signed int */ + case BLKROGET: + case BLKBSZGET: + case BLKSSZGET: + case BLKALIGNOFF: + if (exiting(tcp)) { + int int_val; + if (umove(tcp, arg, &int_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %d", int_val); + } + break; + + /* Just return an unsigned int */ + case BLKPBSZGET: + case BLKIOMIN: + case BLKIOOPT: + if (exiting(tcp)) { + unsigned int uint_val; + if (umove(tcp, arg, &uint_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %u", uint_val); + } + break; + + /* Just return a signed long */ + case BLKRAGET: + case BLKFRAGET: + if (exiting(tcp)) { + long size; + if (umove(tcp, arg, &size) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %ld", size); + } + break; + + /* Just return an unsigned long */ + case BLKGETSIZE: + if (exiting(tcp)) { + unsigned long ulong_val; + if (umove(tcp, arg, &ulong_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %lu", ulong_val); + } + break; + + /* Just return a quad */ + case BLKGETSIZE64: + if (exiting(tcp)) { + uint64_t uint64_val; + if (umove(tcp, arg, &uint64_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %llu", (unsigned long long)uint64_val); + } + break; + + /* More complex types */ + case BLKDISCARD: + if (entering(tcp)) { + uint64_t range[2]; + if (umove(tcp, arg, range) < 0) + tprintf(", %#lx", arg); + else + tprintf(", {%llx, %llx}", + (unsigned long long)range[0], + (unsigned long long)range[1]); + } + break; + + case HDIO_GETGEO: + if (exiting(tcp)) { + struct hd_geometry geo; + if (umove(tcp, arg, &geo) < 0) + tprintf(", %#lx", arg); + else + tprintf(", {heads=%hhu, sectors=%hhu, " + "cylinders=%hu, start=%lu}", + geo.heads, geo.sectors, + geo.cylinders, geo.start); + } + break; + case BLKPG: + if (entering(tcp)) { + struct blkpg_ioctl_arg blkpg; + if (umove(tcp, arg, &blkpg) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", "); + print_blkpg_req(tcp, &blkpg); + } + } + if (exiting(tcp)) { + tprintf("}"); + } + break; + case BLKTRACESETUP: + if (entering(tcp)) { + struct blk_user_trace_setup buts; + if (umove(tcp, arg, &buts) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", {act_mask=%hu, buf_size=%u, ", + buts.act_mask, buts.buf_size); + tprintf("buf_nr=%u, start_lba=%llu, ", + buts.buf_nr, buts.start_lba); + tprintf("end_lba=%llu, pid=%u}", + buts.end_lba, buts.pid); + } + } + if (exiting(tcp)) { + struct blk_user_trace_setup buts; + if (umove(tcp, arg, &buts) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", {name=\"%s\"}", buts.name); + } + } + break; + /* No arguments or unhandled */ + case BLKFLSBUF: /* Requires driver knowlege */ + case BLKRRPART: /* No args */ + case BLKTRACESTART: + case BLKTRACESTOP: + case BLKTRACETEARDOWN: + default: + if (entering(tcp)) + tprintf(", %#lx", arg); + break; + + }; + return 1; +} +#endif /* LINUX */ --- a/defs.h +++ b/defs.h @@ -526,6 +526,7 @@ extern int stream_ioctl P((struct tcb *, #ifdef LINUX extern int rtc_ioctl P((struct tcb *, long, long)); extern int scsi_ioctl P((struct tcb *, long, long)); +extern int block_ioctl P((struct tcb *, long, long)); #endif extern void tv_tv P((struct timeval *, int, int)); --- a/ioctl.c +++ b/ioctl.c @@ -152,6 +152,9 @@ long code, arg; #ifdef LINUX case 'p': return rtc_ioctl(tcp, code, arg); + case 0x03: + case 0x12: + return block_ioctl(tcp, code, arg); case 0x22: return scsi_ioctl(tcp, code, arg); #endif --- a/linux/ioctlent.sh +++ b/linux/ioctlent.sh @@ -67,6 +67,9 @@ lookup_ioctls 56 linux/vt.h lookup_ioctls '7[12]' linux/videotext.h lookup_ioctls 89 $asm/sockios.h linux/sockios.h lookup_ioctls 8B linux/wireless.h +lookup_ioctls 03 linux/hdreg.h +lookup_ioctls fd dm-ioctl.h +lookup_ioctls 52 linux/rfkill.h files="linux/* $asm/* scsi/* sound/*" -- Jeff Mahoney SUSE Labs |
From: Jeff M. <je...@su...> - 2009-11-30 21:01:03
|
Apologies, the previous version built fine with rpmbuild but only because it applied the patch with --fuzz=2. This one is --fuzz=0 safe. This patch adds support for blkdev_ioctl()-handled ioctls. Signed-off-by: Jeff Mahoney <je...@su...> --- Makefile.am | 2 block.c | 221 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ defs.h | 1 ioctl.c | 3 linux/ioctlent.sh | 3 5 files changed, 229 insertions(+), 1 deletion(-) --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,7 @@ INCLUDES = -I$(OS)/$(ARCH) -I$(srcdir)/$ 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 scsi.c stream.c + proc.c scsi.c stream.c block.c noinst_HEADERS = defs.h EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \ --- /dev/null +++ b/block.c @@ -0,0 +1,221 @@ +#include "defs.h" +#ifdef LINUX +#include <stdint.h> +#include <linux/blkpg.h> +#include <linux/fs.h> +#include <linux/hdreg.h> +#include <linux/blktrace_api.h> + +#ifndef BLKALIGNOFF +#define BLKALIGNOFF _IO(0x12,122) +#endif +#ifndef BLKPBSZGET +#define BLKPBSZGET _IO(0x12,123) +#endif +#ifndef BLKIOMIN +#define BLKIOMIN _IO(0x12,120) +#endif +#ifndef BLKIOOPT +#define BLKIOOPT _IO(0x12,121) +#endif + + +static void +print_blkpg_req(struct tcb *tcp, struct blkpg_ioctl_arg *blkpg) +{ + struct blkpg_partition p; + if (!(blkpg->op == BLKPG_ADD_PARTITION || + blkpg->op == BLKPG_DEL_PARTITION)) { + tprintf("{%d, <invalid>", blkpg->op); + return; + } + + tprintf("{%s, ", blkpg->op == BLKPG_ADD_PARTITION ? + "BLKPG_ADD_PARTITION" : "BLKPG_DEL_PARTITION"); + tprintf("flags=%d, datalen=%d, ", blkpg->flags, blkpg->datalen); + + if (umove(tcp, (unsigned long)blkpg->data, &p) < 0) { + tprintf("%#lx", (unsigned long)blkpg->data); + return; + } + + tprintf("{start=%lld, length=%lld, pno=%d, ", + p.start, p.length, p.pno); + + tprintf("devname=\"%s\", volname=\"%s\"}", + p.devname, p.volname); +} + +int +block_ioctl(struct tcb *tcp, long code, long arg) +{ + switch (code) { + + /* These pass arg as a value, not a pointer */ + case BLKRASET: + case BLKFRASET: + if (entering(tcp)) + tprintf(", %ld", arg); + break; + + /* Just pass in a signed int */ + case BLKROSET: + case BLKBSZSET: + if (entering(tcp)) { + int int_val; + if (umove(tcp, arg, &int_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %d", int_val); + } + break; + + /* Just return an unsigned short */ + case BLKSECTGET: + if (exiting(tcp)) { + unsigned short ushort_val; + if (umove(tcp, arg, &ushort_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %hu", ushort_val); + } + break; + + /* Just return a signed int */ + case BLKROGET: + case BLKBSZGET: + case BLKSSZGET: + case BLKALIGNOFF: + if (exiting(tcp)) { + int int_val; + if (umove(tcp, arg, &int_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %d", int_val); + } + break; + + /* Just return an unsigned int */ + case BLKPBSZGET: + case BLKIOMIN: + case BLKIOOPT: + if (exiting(tcp)) { + unsigned int uint_val; + if (umove(tcp, arg, &uint_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %u", uint_val); + } + break; + + /* Just return a signed long */ + case BLKRAGET: + case BLKFRAGET: + if (exiting(tcp)) { + long size; + if (umove(tcp, arg, &size) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %ld", size); + } + break; + + /* Just return an unsigned long */ + case BLKGETSIZE: + if (exiting(tcp)) { + unsigned long ulong_val; + if (umove(tcp, arg, &ulong_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %lu", ulong_val); + } + break; + + /* Just return a quad */ + case BLKGETSIZE64: + if (exiting(tcp)) { + uint64_t uint64_val; + if (umove(tcp, arg, &uint64_val) < 0) + tprintf(", %#lx", arg); + else + tprintf(", %llu", (unsigned long long)uint64_val); + } + break; + + /* More complex types */ + case BLKDISCARD: + if (entering(tcp)) { + uint64_t range[2]; + if (umove(tcp, arg, range) < 0) + tprintf(", %#lx", arg); + else + tprintf(", {%llx, %llx}", + (unsigned long long)range[0], + (unsigned long long)range[1]); + } + break; + + case HDIO_GETGEO: + if (exiting(tcp)) { + struct hd_geometry geo; + if (umove(tcp, arg, &geo) < 0) + tprintf(", %#lx", arg); + else + tprintf(", {heads=%hhu, sectors=%hhu, " + "cylinders=%hu, start=%lu}", + geo.heads, geo.sectors, + geo.cylinders, geo.start); + } + break; + case BLKPG: + if (entering(tcp)) { + struct blkpg_ioctl_arg blkpg; + if (umove(tcp, arg, &blkpg) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", "); + print_blkpg_req(tcp, &blkpg); + } + } + if (exiting(tcp)) { + tprintf("}"); + } + break; + case BLKTRACESETUP: + if (entering(tcp)) { + struct blk_user_trace_setup buts; + if (umove(tcp, arg, &buts) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", {act_mask=%hu, buf_size=%u, ", + buts.act_mask, buts.buf_size); + tprintf("buf_nr=%u, start_lba=%llu, ", + buts.buf_nr, buts.start_lba); + tprintf("end_lba=%llu, pid=%u}", + buts.end_lba, buts.pid); + } + } + if (exiting(tcp)) { + struct blk_user_trace_setup buts; + if (umove(tcp, arg, &buts) < 0) + tprintf(", %#lx", arg); + else { + tprintf(", {name=\"%s\"}", buts.name); + } + } + break; + /* No arguments or unhandled */ + case BLKFLSBUF: /* Requires driver knowlege */ + case BLKRRPART: /* No args */ + case BLKTRACESTART: + case BLKTRACESTOP: + case BLKTRACETEARDOWN: + default: + if (entering(tcp)) + tprintf(", %#lx", arg); + break; + + }; + return 1; +} +#endif /* LINUX */ --- a/defs.h +++ b/defs.h @@ -555,6 +555,7 @@ extern int stream_ioctl P((struct tcb *, #ifdef LINUX extern int rtc_ioctl P((struct tcb *, long, long)); extern int scsi_ioctl P((struct tcb *, long, long)); +extern int block_ioctl P((struct tcb *, long, long)); #endif extern void tv_tv P((struct timeval *, int, int)); --- a/ioctl.c +++ b/ioctl.c @@ -152,6 +152,9 @@ long code, arg; #ifdef LINUX case 'p': return rtc_ioctl(tcp, code, arg); + case 0x03: + case 0x12: + return block_ioctl(tcp, code, arg); case 0x22: return scsi_ioctl(tcp, code, arg); #endif --- a/linux/ioctlent.sh +++ b/linux/ioctlent.sh @@ -69,6 +69,9 @@ lookup_ioctls 56 linux/vt.h lookup_ioctls '7[12]' linux/videotext.h lookup_ioctls 89 $asm/sockios.h linux/sockios.h lookup_ioctls 8B linux/wireless.h +lookup_ioctls 03 linux/hdreg.h +lookup_ioctls fd dm-ioctl.h +lookup_ioctls 52 linux/rfkill.h if [ -e $dir/Kbuild ]; then # kernel has exported user space headers, so query only them -- Jeff Mahoney SUSE Labs |
From: Dmitry V. L. <ld...@al...> - 2009-11-30 21:32:50
|
On Mon, Nov 30, 2009 at 03:50:19PM -0500, Jeff Mahoney wrote: > This patch adds support for blkdev_ioctl()-handled ioctls. I have a couple of questions about your patch. > [...] > --- /dev/null > +++ b/block.c > @@ -0,0 +1,221 @@ > +#include "defs.h" > +#ifdef LINUX > +#include <stdint.h> > +#include <linux/blkpg.h> > +#include <linux/fs.h> > +#include <linux/hdreg.h> > +#include <linux/blktrace_api.h> Are you sure that every linux system provides these header files? > [...] > +static void > +print_blkpg_req(struct tcb *tcp, struct blkpg_ioctl_arg *blkpg) > +{ > + struct blkpg_partition p; > + if (!(blkpg->op == BLKPG_ADD_PARTITION || > + blkpg->op == BLKPG_DEL_PARTITION)) { > + tprintf("{%d, <invalid>", blkpg->op); > + return; > + } > + > + tprintf("{%s, ", blkpg->op == BLKPG_ADD_PARTITION ? > + "BLKPG_ADD_PARTITION" : "BLKPG_DEL_PARTITION"); > + tprintf("flags=%d, datalen=%d, ", blkpg->flags, blkpg->datalen); Please define an xlat structure and use xlookup() instead of these comparisons. -- ldv |
From: Mike F. <va...@ge...> - 2009-11-30 23:58:44
|
On Monday 30 November 2009 15:50:19 Jeff Mahoney wrote: > +++ b/block.c > @@ -0,0 +1,221 @@ > +#include "defs.h" shouldnt there be a comment block here with short desc/copyright/license -mike |
From: Jeff M. <je...@su...> - 2009-12-01 01:05:18
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 11/30/2009 07:03 PM, Mike Frysinger wrote: > On Monday 30 November 2009 15:50:19 Jeff Mahoney wrote: >> +++ b/block.c >> @@ -0,0 +1,221 @@ >> +#include "defs.h" > > shouldnt there be a comment block here with short desc/copyright/license Yep, of course. I'll get to that and cleaning up the includes that may not be there tomorrow. - -Jeff - -- Jeff Mahoney SUSE Labs -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.12 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org/ iEYEARECAAYFAksUa7AACgkQLPWxlyuTD7IrNgCffhga8IrncelAnlYzvN0Tkcrr szIAnRHZJcF+roFBjL6wBPVuyyo6NrOY =lrLI -----END PGP SIGNATURE----- |