blkparse: split off the timestamp correction code in to a separate function
[blktrace.git] / blkrawverify.c
index 51e7963b67ed2ab51eb2ca008c39c12a9dd5dae3..ed5d258da438dc1b3b9c5242ae7b404079563932 100644 (file)
@@ -39,14 +39,18 @@ int data_is_native = -1;
 static struct trace_info traces[] = {
        TRACE_TO_STRING( BLK_TC_READ ),
        TRACE_TO_STRING( BLK_TC_WRITE ),
-       TRACE_TO_STRING( BLK_TC_BARRIER ),
+       TRACE_TO_STRING( BLK_TC_FLUSH ),
        TRACE_TO_STRING( BLK_TC_SYNC ),
        TRACE_TO_STRING( BLK_TC_QUEUE ),
        TRACE_TO_STRING( BLK_TC_REQUEUE ),
        TRACE_TO_STRING( BLK_TC_ISSUE ),
        TRACE_TO_STRING( BLK_TC_COMPLETE ),
        TRACE_TO_STRING( BLK_TC_FS ),
-       TRACE_TO_STRING( BLK_TC_PC )
+       TRACE_TO_STRING( BLK_TC_PC ),
+       TRACE_TO_STRING( BLK_TC_AHEAD ),
+       TRACE_TO_STRING( BLK_TC_META ),
+       TRACE_TO_STRING( BLK_TC_DISCARD ),
+       TRACE_TO_STRING( BLK_TC_FUA ),
 };
 #define N_TRACES (sizeof(traces) / sizeof(struct trace_info))
 
@@ -83,7 +87,7 @@ static char *act_to_str(__u32 action)
        unsigned int act = action & 0xffff;
        unsigned int trace = (action >> BLK_TC_SHIFT) & 0xffff;
 
-       if (act <= N_ACTS) {
+       if (act < N_ACTS) {
                sprintf(buf, "%s ", acts[act].string);
                for (i = 0; i < N_TRACES; i++)
                        if (trace & (1 << i)) {
@@ -115,7 +119,7 @@ static void dump_trace(FILE *ofp, char *prefix, struct blk_io_trace *bit)
                                                           MINOR(bit->device));
 }
 
-static int process(FILE *ofp, char *file, unsigned int cpu)
+static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
 {
 #      define SWAP_BITS() do {                                         \
                if (bit_save) {                                         \
@@ -138,7 +142,7 @@ static int process(FILE *ofp, char *file, unsigned int cpu)
        } while (0)
 
        size_t n;
-       FILE *ifp;
+       FILE *ifp, *ofp;
        __u32 save_device = 0, save_sequence = 0;
        __u64 save_time = 0;
        struct blk_io_trace *bit_save = NULL;
@@ -147,15 +151,48 @@ static int process(FILE *ofp, char *file, unsigned int cpu)
        unsigned int nbad = 0;
        unsigned int nbad_trace = 0, nbad_pdu = 0, nbad_cpu = 0;
        unsigned int nbad_seq = 0, nbad_dev = 0, nbad_time = 0;
+       char ofname[1024];
 
        ifp = fopen(file, "r");
+       if (!ifp)
+               return 0;
+
+       sprintf(ofname, "%s.verify.out", devname);
+
+       if (!*fp) {
+               *fp = fopen(ofname, "w");
+               if (*fp == NULL) {
+                       fprintf(stderr,"Failed to open %s (%s), skipping\n",
+                               ofname, strerror(errno));
+                       fclose(ifp);
+                       return 0;
+               }
+               fprintf(*fp, "\n---------------\n" );
+               fprintf(*fp, "Verifying %s\n", devname);
+       }
+
+       ofp = *fp;
        while ((n = fread(bit, sizeof(struct blk_io_trace), 1, ifp)) == 1) {
+               if (ferror(ifp)) {
+                       clearerr(ifp);
+                       perror("fread");
+                       break;
+               }
+               if (data_is_native == -1)
+                       check_data_endianness(bit->magic);
+
                trace_to_cpu(bit);
-               if (verify_trace(bit)) {
+
+               if (!CHECK_MAGIC(bit)) {
                        INC_BAD("bad trace");
                        continue;
                }
 
+               if ((bit->magic & 0xff) != SUPPORTED_VERSION) {
+                       fprintf(stderr, "unsupported trace version\n");
+                       break;
+               }
+
                if (bit->pdu_len) {
                        char *pdu_buf;
 
@@ -164,6 +201,7 @@ static int process(FILE *ofp, char *file, unsigned int cpu)
                        if (n == 0) {
                                INC_BAD("bad pdu");
                                nbad_seq++;
+                               free(pdu_buf);
                                break;
                        }
                        free(pdu_buf);
@@ -175,6 +213,12 @@ static int process(FILE *ofp, char *file, unsigned int cpu)
                        continue;
                }
 
+               /*
+                * skip notify traces, they don't have valid sequences
+                */
+               if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY))
+                       continue;
+
                if (ngood) {
                        if (bit->sequence <= save_sequence) {
                                INC_BAD("bad seq");
@@ -235,7 +279,7 @@ int main(int argc, char *argv[])
 {
        char *devname;
        struct stat st;
-       int i, cpu, nbad;
+       int i, cpu, nbad, rval = 0;
        FILE *ofp;
        char *ofname = malloc(1024);
        char *fname = malloc(1024);
@@ -249,29 +293,32 @@ int main(int argc, char *argv[])
        for (i = 1; i < argc; i++) {
                devname = argv[i];
                sprintf(ofname, "%s.verify.out", devname);
-               ofp = fopen(ofname, "w");
-               if (ofp == NULL) {
-                       fprintf(stderr,"Failed to open %s (%s), skipping %s\n",
-                               ofname, strerror(errno), devname);
-                       continue;
-               }
+               ofp = NULL;
 
-               fprintf(ofp, "\n---------------\n" );
-               fprintf(ofp, "Verifying %s\n", devname);
                printf("Verifying %s\n", devname); fflush(stdout);
                for (cpu = 0; ; cpu++) {
                        sprintf(fname, "%s.blktrace.%d", devname, cpu);
-                       if (stat(fname, &st) < 0)
+                       if (stat(fname, &st) < 0) {
+                               if (cpu == 0) {
+                                       fprintf(stderr, "No tracefiles found for %s\n",
+                                               devname);
+                                       rval = 1;
+                               }
                                break;
+                       }
                        printf("    CPU %d ", cpu); fflush(stdout);
-                       nbad = process(ofp, fname, cpu);
-                       if (nbad)
+                       nbad = process(&ofp, devname, fname, cpu);
+                       if (nbad) {
                                printf("-- %d bad", nbad);
+                               rval = 1;
+                       }
                        printf("\n");
                }
-               fclose(ofp);
-               fprintf(stdout, "Wrote output to %s\n", ofname);
+               if (ofp) {
+                       fclose(ofp);
+                       fprintf(stdout, "Wrote output to %s\n", ofname);
+               }
        }
 
-       return 0;
+       return rval;
 }