>From Alan D. Brunelle <[EMAIL PROTECTED]>

Added per-IO block number dump (issued)

Signed-off-by: Alan D. Brunelle <[EMAIL PROTECTED]>
---

 btt/Makefile      |    2 +
 btt/args.c        |   12 +++++++-
 btt/bno_dump.c    |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 btt/bt_timeline.c |    3 +-
 btt/devs.c        |    1 +
 btt/doc/btt.tex   |   18 ++++++++++++
 btt/globals.h     |   10 +++++--
 btt/trace_issue.c |    1 +
 8 files changed, 121 insertions(+), 5 deletions(-)

diff --git a/btt/Makefile b/btt/Makefile
index c406ed3..17fb8c0 100644
--- a/btt/Makefile
+++ b/btt/Makefile
@@ -9,7 +9,7 @@ LIBS    = $(PLIBS) $(ELIBS)
 OBJS   = args.o bt_timeline.o devmap.o devs.o dip_rb.o iostat.o latency.o \
          misc.o output.o proc.o seek.o trace.o trace_complete.o trace_im.o \
          trace_issue.o trace_queue.o trace_remap.o trace_requeue.o rbtree.o \
-         mmap.o trace_plug.o
+         mmap.o trace_plug.o bno_dump.o
 
 all: depend $(PROGS)
 
diff --git a/btt/args.c b/btt/args.c
index 7fa087e..4bbcf76 100644
--- a/btt/args.c
+++ b/btt/args.c
@@ -27,7 +27,7 @@
 #include <fcntl.h>
 #include "globals.h"
 
-#define S_OPTS "Ad:D:e:hi:I:l:M:o:p:q:s:S:t:T:Vv"
+#define S_OPTS "AB:d:D:e:hi:I:l:M:o:p:q:s:S:t:T:Vv"
 static struct option l_opts[] = {
        {
                .name = "all-data",
@@ -36,6 +36,12 @@ static struct option l_opts[] = {
                .val = 'A'
        },
        {
+               .name = "dump-blocknos",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'B'
+       },
+       {
                .name = "range-delta",
                .has_arg = required_argument,
                .flag = NULL,
@@ -144,6 +150,7 @@ static struct option l_opts[] = {
 
 static char usage_str[] = \
        "\n[ -A               | --all-data ]\n" \
+       "[ -B <output name> | --dump-blocknos=<output name> ]\n" \
        "[ -d <seconds>     | --range-delta=<seconds> ]\n" \
        "[ -D <dev;...>     | --devices=<dev;...> ]\n" \
        "[ -e <exe,...>     | --exes=<exe,...>  ]\n" \
@@ -177,6 +184,9 @@ void handle_args(int argc, char *argv[])
                case 'A':
                        output_all_data = 1;
                        break;
+               case 'B':
+                       bno_dump_name = strdup(optarg);
+                       break;
                case 'd':
                        sscanf(optarg, "%lf", &range_delta);
                        break;
diff --git a/btt/bno_dump.c b/btt/bno_dump.c
new file mode 100644
index 0000000..f0f16f6
--- /dev/null
+++ b/btt/bno_dump.c
@@ -0,0 +1,79 @@
+/*
+ * blktrace output analysis: generate a timeline & gather statistics
+ *
+ * Copyright (C) 2006 Alan D. Brunelle <[EMAIL PROTECTED]>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#include "globals.h"
+
+struct bno_dump {
+       FILE *rfp, *wfp, *cfp;
+};
+
+static struct file_info *bno_dump_files = NULL;
+
+static FILE *bno_dump_open(__u32 device, char rwc)
+{
+       FILE *fp;
+       char *oname;
+       int mjr, mnr;
+
+       mjr = device >> MINORBITS;
+       mnr = device & ((1 << MINORBITS) - 1);
+
+       oname = malloc(strlen(bno_dump_name) + 32);
+       sprintf(oname, "%s_%03d,%03d_%c.dat", bno_dump_name, mjr, mnr, rwc);
+       if ((fp = fopen(oname, "w")) == NULL)
+               perror(oname);
+       else
+               add_file(&bno_dump_files, fp, oname);
+       return fp;
+}
+
+void *bno_dump_init(__u32 device)
+{
+       struct bno_dump *bdp;
+
+       if (bno_dump_name == NULL) return NULL;
+
+       bdp = malloc(sizeof(*bdp));
+       bdp->rfp = bno_dump_open(device, 'r');
+       bdp->wfp = bno_dump_open(device, 'w');
+       bdp->cfp = bno_dump_open(device, 'c');
+
+       return bdp;
+}
+
+void bno_dump_add(void *handle, struct io *iop)
+{
+#      define RW_FP(bdp, iop)  (IOP_READ(iop) ? bdp->rfp : bdp->wfp)
+       struct bno_dump *bdp = handle;
+
+       if (bdp) {
+               if (RW_FP(bdp, iop))
+                       fprintf(RW_FP(bdp, iop), "%15.9lf %lld\n", 
+                               BIT_TIME(iop->t.time), (long 
long)BIT_START(iop));
+               if (bdp->cfp)
+                       fprintf(bdp->cfp, "%15.9lf %lld\n", 
+                               BIT_TIME(iop->t.time), (long 
long)BIT_START(iop));
+       }
+}
+
+void bno_dump_clean(void)
+{
+       clean_files(&bno_dump_files);
+}
diff --git a/btt/bt_timeline.c b/btt/bt_timeline.c
index c2a4abf..8ae046b 100644
--- a/btt/bt_timeline.c
+++ b/btt/bt_timeline.c
@@ -27,7 +27,7 @@
 
 char bt_timeline_version[] = "0.99.1";
 
-char *devices, *exes, *input_name, *output_name, *seek_name;
+char *devices, *exes, *input_name, *output_name, *seek_name, *bno_dump_name;
 char *d2c_name, *q2c_name, *per_io_name;
 FILE *ranges_ofp, *avgs_ofp, *per_io_ofp;
 int verbose, done, time_bounded, output_all_data;
@@ -100,6 +100,7 @@ int process(void)
 
        seek_clean();
        latency_clean();
+       bno_dump_clean();
        gettimeofday(&tve, NULL);
 
        if (verbose) {
diff --git a/btt/devs.c b/btt/devs.c
index a458a77..545d5c5 100644
--- a/btt/devs.c
+++ b/btt/devs.c
@@ -108,6 +108,7 @@ struct d_info *dip_add(__u32 device, struct io *iop)
                dip->last_q = (__u64)-1;
                dip->map = dev_map_find(device);
                dip->seek_handle = seeki_init(device);
+               dip->bno_dump_handle = bno_dump_init(device);
                latency_init(dip);
                list_add_tail(&dip->hash_head, &dev_heads[DEV_HASH(device)]);
                list_add_tail(&dip->all_head, &all_devs);
diff --git a/btt/doc/btt.tex b/btt/doc/btt.tex
index af585c5..88b772e 100644
--- a/btt/doc/btt.tex
+++ b/btt/doc/btt.tex
@@ -597,6 +597,7 @@ Device:       rrqm/s   wrqm/s     r/s     w/s    rsec/s    
wsec/s
 \begin{verbatim}
 Usage: \texttt{btt} 0.99.1 
 [ -A               | --all-data ]
+[ -B <output name> | --dump-blocknos=<output name> ]
 [ -d <seconds>     | --range-delta=<seconds> ]
 [ -D <dev;...>     | --devices=<dev;...> ]
 [ -e <exe,...>     | --exes=<exe,...>  ]
@@ -623,6 +624,23 @@ Usage: \texttt{btt} 0.99.1
   section~\ref{sec:detailed-data}). If you desire that level of 
   detail you can specify this option.
 
+\subsection{\label{sec:o-B}\texttt{--dump-blocknos}/\texttt{-B}}
+
+  This option will output absolute block numbers to three files prefixed
+  by the specified output name:
+
+  \begin{description}
+    \item[\emph{prefix}\_\emph{device}\_r.dat] All read block numbers are
+    output, first column is time (seconds), second is the block number.
+
+    \item[\emph{prefix}\_\emph{device}\_w.dat] All write block numbers are
+    output, first column is time (seconds), second is the block number.
+
+    \item[\emph{prefix}\_\emph{device}\_c.dat] All block numbers (read
+    and write) are output, first column is time (seconds), second is
+    the block number.
+  \end{description}
+
 \subsection{\label{sec:o-d}\texttt{--range-delta}/\texttt{-d}}
 
   Section~\ref{sec:activity} discussed how \texttt{btt} outputs a file
diff --git a/btt/globals.h b/btt/globals.h
index b4e9894..e8b8e7e 100644
--- a/btt/globals.h
+++ b/btt/globals.h
@@ -159,7 +159,7 @@ struct d_info {
        void *heads;
        struct region_info regions;
        struct devmap *map;
-       void *seek_handle;
+       void *seek_handle, *bno_dump_handle;
        FILE *d2c_ofp, *q2c_ofp;
        struct avgs_info avgs;
        struct stats stats, all_stats;
@@ -193,8 +193,9 @@ struct bilink {
 
 extern char bt_timeline_version[], *devices, *exes, *input_name, *output_name;
 extern char *seek_name, *iostat_name, *d2c_name, *q2c_name, *per_io_name;
+extern char *bno_dump_name;
 extern double range_delta;
-extern FILE *ranges_ofp, *avgs_ofp, *iostat_ofp, *per_io_ofp;;
+extern FILE *ranges_ofp, *avgs_ofp, *iostat_ofp, *per_io_ofp;
 extern int verbose, done, time_bounded, output_all_data;
 extern unsigned int n_devs;
 extern unsigned long n_traces;
@@ -279,6 +280,11 @@ struct p_info *find_process(__u32 pid, char *name);
 void pip_update_q(struct io *iop);
 void pip_foreach_out(void (*f)(struct p_info *, void *), void *arg);
 
+/* bno_dump.c */
+void *bno_dump_init(__u32 device);
+void bno_dump_add(void *handle, struct io *iop);
+void bno_dump_clean(void);
+
 /* seek.c */
 void *seeki_init(__u32 device);
 void seek_clean(void);
diff --git a/btt/trace_issue.c b/btt/trace_issue.c
index 780a133..52aa8b1 100644
--- a/btt/trace_issue.c
+++ b/btt/trace_issue.c
@@ -91,6 +91,7 @@ void trace_issue(struct io *d_iop)
 {
        if (io_setup(d_iop, IOP_D)) {
                seeki_add(d_iop->dip->seek_handle, d_iop);
+               bno_dump_add(d_iop->dip->bno_dump_handle, d_iop);
                iostat_issue(d_iop);
                d_iop->dip->n_ds++;
                if (!remapper_dev(d_iop->t.device))

Reply via email to