From 36d2bf71fcc15160a3a257af70eb3ce43cf66b00 Mon Sep 17 00:00:00 2001 From: pmf Date: Thu, 27 Mar 2008 22:08:37 +0000 Subject: [PATCH] add blktrace_start tool used to enable blktrace on a block device git-svn-id: http://ltt.polymtl.ca/svn@2835 04897980-b3bd-0310-b5e0-8ef037075253 --- blk/Makefile | 2 + blk/blktrace_api.h | 128 +++++++++++++++++++++++++++++++++++++++++++ blk/blktrace_start.c | 59 ++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 blk/Makefile create mode 100644 blk/blktrace_api.h create mode 100644 blk/blktrace_start.c diff --git a/blk/Makefile b/blk/Makefile new file mode 100644 index 00000000..53363ffd --- /dev/null +++ b/blk/Makefile @@ -0,0 +1,2 @@ +blktrace_start: blktrace_start.c + gcc -o blktrace_start blktrace_start.c diff --git a/blk/blktrace_api.h b/blk/blktrace_api.h new file mode 100644 index 00000000..61b405a2 --- /dev/null +++ b/blk/blktrace_api.h @@ -0,0 +1,128 @@ +#ifndef BLKTRACEAPI_H +#define BLKTRACEAPI_H + +#include + +/* + * Trace categories + */ +enum { + BLK_TC_READ = 1 << 0, /* reads */ + BLK_TC_WRITE = 1 << 1, /* writes */ + BLK_TC_BARRIER = 1 << 2, /* barrier */ + BLK_TC_SYNC = 1 << 3, /* sync */ + BLK_TC_QUEUE = 1 << 4, /* queueing/merging */ + BLK_TC_REQUEUE = 1 << 5, /* requeueing */ + BLK_TC_ISSUE = 1 << 6, /* issue */ + BLK_TC_COMPLETE = 1 << 7, /* completions */ + BLK_TC_FS = 1 << 8, /* fs requests */ + BLK_TC_PC = 1 << 9, /* pc requests */ + BLK_TC_NOTIFY = 1 << 10, /* special message */ + BLK_TC_AHEAD = 1 << 11, /* readahead */ + BLK_TC_META = 1 << 12, /* metadata */ + + BLK_TC_END = 1 << 15, /* only 16-bits, reminder */ +}; + +#define BLK_TC_SHIFT (16) +#define BLK_TC_ACT(act) ((act) << BLK_TC_SHIFT) + +/* + * Basic trace actions + */ +enum { + __BLK_TA_QUEUE = 1, /* queued */ + __BLK_TA_BACKMERGE, /* back merged to existing rq */ + __BLK_TA_FRONTMERGE, /* front merge to existing rq */ + __BLK_TA_GETRQ, /* allocated new request */ + __BLK_TA_SLEEPRQ, /* sleeping on rq allocation */ + __BLK_TA_REQUEUE, /* request requeued */ + __BLK_TA_ISSUE, /* sent to driver */ + __BLK_TA_COMPLETE, /* completed by driver */ + __BLK_TA_PLUG, /* queue was plugged */ + __BLK_TA_UNPLUG_IO, /* queue was unplugged by io */ + __BLK_TA_UNPLUG_TIMER, /* queue was unplugged by timer */ + __BLK_TA_INSERT, /* insert request */ + __BLK_TA_SPLIT, /* bio was split */ + __BLK_TA_BOUNCE, /* bio was bounced */ + __BLK_TA_REMAP, /* bio was remapped */ +}; + +/* + * Notify events. + */ +enum blktrace_notify { + __BLK_TN_PROCESS = 0, /* establish pid/name mapping */ + __BLK_TN_TIMESTAMP, /* include system clock */ +}; + +/* + * Trace actions in full. Additionally, read or write is masked + */ +#define BLK_TA_QUEUE (__BLK_TA_QUEUE | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_BACKMERGE (__BLK_TA_BACKMERGE | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_FRONTMERGE (__BLK_TA_FRONTMERGE | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_GETRQ (__BLK_TA_GETRQ | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_SLEEPRQ (__BLK_TA_SLEEPRQ | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_REQUEUE (__BLK_TA_REQUEUE | BLK_TC_ACT(BLK_TC_REQUEUE)) +#define BLK_TA_ISSUE (__BLK_TA_ISSUE | BLK_TC_ACT(BLK_TC_ISSUE)) +#define BLK_TA_COMPLETE (__BLK_TA_COMPLETE| BLK_TC_ACT(BLK_TC_COMPLETE)) +#define BLK_TA_PLUG (__BLK_TA_PLUG | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_UNPLUG_IO (__BLK_TA_UNPLUG_IO | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_UNPLUG_TIMER (__BLK_TA_UNPLUG_TIMER | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_INSERT (__BLK_TA_INSERT | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_SPLIT (__BLK_TA_SPLIT) +#define BLK_TA_BOUNCE (__BLK_TA_BOUNCE) +#define BLK_TA_REMAP (__BLK_TA_REMAP | BLK_TC_ACT(BLK_TC_QUEUE)) + +#define BLK_TN_PROCESS (__BLK_TN_PROCESS | BLK_TC_ACT(BLK_TC_NOTIFY)) +#define BLK_TN_TIMESTAMP (__BLK_TN_TIMESTAMP | BLK_TC_ACT(BLK_TC_NOTIFY)) + +#define BLK_IO_TRACE_MAGIC 0x65617400 +#define BLK_IO_TRACE_VERSION 0x07 + +/* + * The trace itself + */ +struct blk_io_trace { + __u32 magic; /* MAGIC << 8 | version */ + __u32 sequence; /* event number */ + __u64 time; /* in nanoseconds */ + __u64 sector; /* disk offset */ + __u32 bytes; /* transfer length */ + __u32 action; /* what happened */ + __u32 pid; /* who did it */ + __u32 device; /* device identifier (dev_t) */ + __u32 cpu; /* on what cpu did it happen */ + __u16 error; /* completion error */ + __u16 pdu_len; /* length of data after this trace */ +}; + +/* + * The remap event + */ +struct blk_io_trace_remap { + __u32 device; + __u32 device_from; + __u64 sector; +}; + +/* + * User setup structure passed with BLKSTARTTRACE + */ +struct blk_user_trace_setup { + char name[32]; /* output */ + __u16 act_mask; /* input */ + __u32 buf_size; /* input */ + __u32 buf_nr; /* input */ + __u64 start_lba; + __u64 end_lba; + __u32 pid; +}; + +#define BLKTRACESETUP _IOWR(0x12,115,struct blk_user_trace_setup) +#define BLKTRACESTART _IO(0x12,116) +#define BLKTRACESTOP _IO(0x12,117) +#define BLKTRACETEARDOWN _IO(0x12,118) + +#endif diff --git a/blk/blktrace_start.c b/blk/blktrace_start.c new file mode 100644 index 00000000..97c15926 --- /dev/null +++ b/blk/blktrace_start.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include + +#include "blktrace_api.h" + +int start(int fd) +{ + struct blk_user_trace_setup buts; + + memset(&buts, 0, sizeof(buts)); + buts.buf_size = 512*1024; + buts.buf_nr = 4; + buts.act_mask = ~0; + + if (ioctl(fd, BLKTRACESETUP, &buts) < 0) { + perror("BLKTRACESETUP"); + return 1; + } + + return 0; +} + +int stop(int fd) +{ + ioctl(fd, BLKTRACESTOP); + if(ioctl(fd, BLKTRACETEARDOWN) < 0) + perror("BLKTRACETEARDOWN"); + + return 0; +} + +int main(int argc, char **argv) +{ + int fd; + + if(argc < 3) { + fprintf(stderr, "usage: --start|--stop %s BLKDEV\n", argv[0]); + return 1; + } + + fd = open(argv[2], O_RDONLY | O_NONBLOCK); + if (fd < 0) { + perror(argv[1]); + return 1; + } + + if(!strcmp("--start", argv[1])) + start(fd); + else if(!strcmp("--stop", argv[1])) + stop(fd); + + close(fd); + + return 0; +} -- 2.34.1