- Improved error handling
authorJens Axboe <axboe@wiggum>
Mon, 29 Aug 2005 06:45:19 +0000 (08:45 +0200)
committerJens Axboe <axboe@wiggum>
Mon, 29 Aug 2005 06:45:19 +0000 (08:45 +0200)
- Remove _dat files, include the payload in _out
- Support for payload > 64 bytes
- Add install target
- Fix RELAYFS Kconfig selection (kernel patch)

CHANGELOG
Makefile
blkparse.c
blktrace.c
kernel/blk-trace-2.6.13-rc6-mm2-B1

index dd74307176cf74ba4576dc893bb47459f09ef01f..2202b6a249779a2f8001c8012335cbb0cf47b87b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+20050828:
+       - Improved error handling
+       - Remove _dat files, include the payload in _out
+       - Support for payload > 64 bytes
+       - Add install target
 20050827:
        - Various cleanups and killing unused variables
 20050826:
index 6d00befcb795cfe81e7a218b3147f57a9e82e886..ae05de6f4509c77aa1599e4bd83a7a7e5c8729da 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,21 @@
 CC     = gcc
-CFLAGS = -Wall -O2 -D_GNU_SOURCE
+CFLAGS = -Wall -g -D_GNU_SOURCE
 PROG   = blkparse blktrace
-TRACE_LIBS = -lpthread
+LIBS   = -lpthread
 
 all: $(PROG)
 
 blkparse: blkparse.o rbtree.o
-blktrace: blktrace.o $(TRACE_LIBS)
+blktrace: blktrace.o $(LIBS)
 
 clean:
        -rm -f *.o $(PROG)
+
+INSTALL = install
+prefix = /usr/local
+bindir = $(prefix)/bin
+
+install: $(PROG)
+       $(INSTALL) -m755 -d $(DESTDIR)$(bindir)
+       $(INSTALL) $(PROG) $(DESTDIR)$(bindir)
+
index 68164cb6aba7a7278aa8b9be8dce10708592f91c..342f5f61e9130f60ab1e399ef5acf754703c7895 100644 (file)
 struct per_file_info {
        int cpu;
        int nelems;
-       struct stat stat;
 
        int fd;
-       char *fname;
-       FILE *ofp;
-       char *ofname;
-       int dfd;
-       char *dname;
+       char fname[128];
 
-       void *trace_buf;
+       FILE *ofp;
+       char ofname[128];
 
        unsigned long long start_time;
 };
@@ -35,12 +31,14 @@ struct trace {
        struct rb_node rb_node;
 };
 
-struct per_file_info per_file_info[MAX_CPUS];
-struct per_file_info *cur_file;
+static struct per_file_info per_file_info[MAX_CPUS];
+static struct per_file_info *cur_file;
 
 static unsigned long qreads, qwrites, creads, cwrites, mreads, mwrites;
 static unsigned long long qread_kb, qwrite_kb, cread_kb, cwrite_kb;
-static unsigned long long events, missed_events;
+static unsigned long long events;
+
+static int max_cpus;
 
 static inline void account_m(int rw, unsigned int bytes)
 {
@@ -145,26 +143,15 @@ static void log_generic(struct blk_io_trace *t, char act)
        output(tstring);
 }
 
-static void log_pc(struct blk_io_trace *t, char act)
+static int log_pc(struct blk_io_trace *t, char act)
 {
-       int i, ret;
-       unsigned char buf[64];
+       unsigned char *buf;
+       int i;
 
-       sprintf(tstring,"%s\n", setup_header(t, act));
+       sprintf(tstring,"%s ", setup_header(t, act));
        output(tstring);
 
-       if (t->pdu_len > sizeof(buf)) {
-               fprintf(stderr, "Payload too large %d\n", t->pdu_len);
-               return;
-       }
-
-       ret = read(cur_file->dfd, buf, t->pdu_len);
-       if (ret != t->pdu_len) {
-               fprintf(stderr,"read(%d) failed on %s - %d\n", t->pdu_len, 
-                       cur_file->dname, ret);
-               exit(1);
-       }
-
+       buf = (unsigned char *) t + sizeof(*t);
        for (i = 0; i < t->pdu_len; i++) {
                sprintf(tstring,"%02x ", buf[i]);
                output(tstring);
@@ -176,10 +163,13 @@ static void log_pc(struct blk_io_trace *t, char act)
        }
 
        printf("\n");
+       return 0;
 }
 
-static void dump_trace_pc(struct blk_io_trace *t)
+static int dump_trace_pc(struct blk_io_trace *t)
 {
+       int ret = 0;
+
        switch (t->action & 0xffff) {
                case __BLK_TA_QUEUE:
                        log_generic(t, 'Q');
@@ -194,17 +184,18 @@ static void dump_trace_pc(struct blk_io_trace *t)
                        log_generic(t, 'R');
                        break;
                case __BLK_TA_ISSUE:
-                       log_pc(t, 'D');
+                       ret = log_pc(t, 'D');
                        break;
                case __BLK_TA_COMPLETE:
                        log_pc(t, 'C');
                        break;
                default:
                        fprintf(stderr, "Bad pc action %x\n", t->action);
-                       return;
+                       ret = 1;
+                       break;
        }
        
-       events++;
+       return ret;
 }
 
 static void dump_trace_fs(struct blk_io_trace *t)
@@ -244,16 +235,19 @@ static void dump_trace_fs(struct blk_io_trace *t)
                        fprintf(stderr, "Bad fs action %x\n", t->action);
                        return;
        }
-       
-       events++;
 }
 
-static void dump_trace(struct blk_io_trace *t)
+static int dump_trace(struct blk_io_trace *t)
 {
+       int ret = 0;
+
        if (t->action & BLK_TC_ACT(BLK_TC_PC))
-               dump_trace_pc(t);
+               ret = dump_trace_pc(t);
        else
                dump_trace_fs(t);
+
+       events++;
+       return ret;
 }
 
 static void show_stats(void)
@@ -269,7 +263,6 @@ static void show_stats(void)
        printf("\tMerges:    %'8lu\n", mwrites);
 
        printf("Events: %'Lu\n", events);
-       printf("Missed events: %'Lu\n", missed_events);
 }
 
 static inline int trace_rb_insert(struct trace *t)
@@ -287,7 +280,7 @@ static inline int trace_rb_insert(struct trace *t)
                else if (t->bit->sequence > __t->bit->sequence)
                        p = &(*p)->rb_right;
                else {
-                       fprintf(stderr, "sequence alias %u!\n", t->bit->sequence);
+                       fprintf(stderr, "sequence alias!\n");
                        return 1;
                }
        }
@@ -317,7 +310,7 @@ static int sort_entries(void *traces, unsigned long offset)
 
                traces += sizeof(*bit) + bit->pdu_len;
                nelems++;
-       } while (traces < start + offset);
+       } while (traces < start + offset + sizeof(*bit));
 
        return nelems;
 }
@@ -338,9 +331,9 @@ static void show_entries(void)
                bit = t->bit;
 
                cpu = bit->magic;
-               if (cpu >= MAX_CPUS) {
+               if (cpu > max_cpus) {
                        fprintf(stderr, "CPU number too large (%d)\n", cpu);
-                       return;
+                       break;
                }
 
                cur_file = &per_file_info[cpu];
@@ -356,43 +349,37 @@ static void show_entries(void)
 
                bit->time -= cur_file->start_time;
 
-               dump_trace(bit);
+               if (dump_trace(bit))
+                       break;
+
        } while ((n = rb_next(n)) != NULL);
 }
 
 int main(int argc, char *argv[])
 {
-       struct per_file_info *pfi;
        int i, nfiles, ret;
        char *dev;
 
        if (argc != 2) {
-               fprintf(stderr, "Usage %s <dev>\n", argv[0]);
+               fprintf(stderr, "Usage: %s <dev>\n", argv[0]);
                return 1;
        }
 
        dev = argv[1];
 
-       nfiles = 0;
-       for (i = 0, pfi = &per_file_info[0]; i < MAX_CPUS; i++, pfi++) {
+       for (max_cpus = 0, i = 0, nfiles = 0; i < MAX_CPUS; i++) {
+               struct per_file_info *pfi = &per_file_info[i];
+               struct stat st;
+               void *tb;
+
                pfi->cpu = i;
                pfi->start_time = 0;
 
-               pfi->fname = malloc(128);
-               sprintf(pfi->fname, "%s_out.%d", dev, i);
-               if (stat(pfi->fname, &pfi->stat) < 0)
+               snprintf(pfi->fname, sizeof(pfi->fname)-1,"%s_out.%d", dev, i);
+               if (stat(pfi->fname, &st) < 0)
                        break;
 
-               pfi->dname = malloc(128);
-               snprintf(pfi->dname, 127, "%s_dat.%d", dev, i);
-               pfi->dfd = open(pfi->dname, O_RDONLY);
-               if (pfi->dfd < 0) {
-                       perror(pfi->dname);
-                       break;
-               }
-
-               pfi->ofname = malloc(128);
-               snprintf(pfi->ofname, 127, "%s_log.%d", dev, i);
+               snprintf(pfi->ofname, sizeof(pfi->ofname)-1, "%s_log.%d", dev, i);
                pfi->ofp = fopen(pfi->ofname, "w");
                if (pfi->ofp == NULL) {
                        perror(pfi->ofname);
@@ -401,24 +388,25 @@ int main(int argc, char *argv[])
 
                printf("Processing %s\n", pfi->fname);
 
-               pfi->trace_buf = malloc(pfi->stat.st_size);
+               tb = malloc(st.st_size);
 
                pfi->fd = open(pfi->fname, O_RDONLY);
                if (pfi->fd < 0) {
                        perror(pfi->fname);
                        break;
                }
-               if (read(pfi->fd, pfi->trace_buf, pfi->stat.st_size) != pfi->stat.st_size) {
+               if (read(pfi->fd, tb, st.st_size) != st.st_size) {
                        fprintf(stderr, "error reading\n");
                        break;
                }
 
-               ret = sort_entries(pfi->trace_buf, pfi->stat.st_size);
+               ret = sort_entries(tb, st.st_size);
                if (ret == -1)
                        break;
 
                close(pfi->fd);
                nfiles++;
+               max_cpus++;
                pfi->nelems = ret;
                printf("\t%2d %10s %15d\n", i, pfi->fname, pfi->nelems);
 
index d0837453e03933715f25a608caa013ea7d534265..58ae2222d22b3de8ed0d643ad9a5dbd82b748fef 100644 (file)
@@ -90,8 +90,9 @@ static void extract_data(int cpu, char *ifn, int ifd, char *ofn, int ofd,
                         int nb)
 {
        int ret, bytes_left;
-       unsigned char buf[nb], *p;
+       unsigned char *buf, *p;
 
+       buf = malloc(nb);
        p = buf;
        bytes_left = nb;
        while (bytes_left > 0) {
@@ -102,6 +103,7 @@ static void extract_data(int cpu, char *ifn, int ifd, char *ofn, int ofd,
                        perror(ifn);
                        fprintf(stderr, "Thread %d extract_data %s failed\n",
                                cpu, ifn);
+                       free(buf);
                        exit(1);
                } else {
                        p += ret;
@@ -113,14 +115,17 @@ static void extract_data(int cpu, char *ifn, int ifd, char *ofn, int ofd,
        if (ret != nb) {
                perror(ofn);
                fprintf(stderr,"Thread %d extract_data %s failed\n", cpu, ofn);
+               free(buf);
                exit(1);
        }
+
+       free(buf);
 }
 
 static void *extract(void *arg)
 {
        struct thread_information *tip = arg;
-       int tracefd, ret, ofd, dfd;
+       int tracefd, ret, ofd;
        char ip[64], op[64], dp[64];
        struct blk_io_trace t;
        pid_t pid = getpid();
@@ -142,14 +147,6 @@ static void *extract(void *arg)
                exit(1);
        }
 
-       sprintf(dp, "%s_dat.%d", buts_name_p, tip->cpu);
-       dfd = open(dp, O_CREAT|O_TRUNC|O_WRONLY, 0644);
-       if (dfd < 0) {
-               perror(dp);
-               fprintf(stderr,"Thread %d failed creat of %s\n", tip->cpu, dp);
-               exit(1);
-       }
-
        sprintf(ip, "%s%s%d", relay_path, buts_name_p, tip->cpu);
        tracefd = open(ip, O_RDONLY);
        if (tracefd < 0) {
@@ -179,21 +176,6 @@ static void *extract(void *arg)
                if (verify_trace(&t))
                        exit(1);
 
-               switch (t.action & 0xffff) {
-               case __BLK_TA_ISSUE:
-               case __BLK_TA_COMPLETE:
-                       if (!t.pdu_len)
-                               break;
-                       else if (t.pdu_len > 64) {
-                               fprintf(stderr, 
-                                       "Thread %d Payload too large %d\n", 
-                                       tip->cpu, t.pdu_len);
-                               exit(1);
-                       }
-                       extract_data(tip->cpu, ip, tracefd, dp, dfd, t.pdu_len);
-                       break;
-               }
-
                /* version is verified, stuff with CPU number now */
                t.magic = tip->cpu;
                ret = write(ofd, &t, sizeof(t));
@@ -204,6 +186,9 @@ static void *extract(void *arg)
                        exit(1);
                }
 
+               if (t.pdu_len)
+                       extract_data(tip->cpu, ip, tracefd, dp, ofd, t.pdu_len);
+
                tip->events_processed++;
        }
 
index 0ea9936daaec7a570f04a6bee763228e45c0d8e7..9a58fbb7ec6ead2b2be1cd09193990ef4eb266b3 100644 (file)
@@ -7,7 +7,7 @@ diff -urpN -X linux-2.6.13-rc6-mm2/Documentation/dontdiff /opt/kernel/linux-2.6.
  
 +config BLK_DEV_IO_TRACE
 +      bool "Support for tracing block io actions"
-+      select RELAYFS
++      select RELAYFS_FS
 +      help
 +        Say Y here, if you want to be able to trace the block layer actions
 +        on a given queue.