t/verify-state: add helper to inspect verify dump state files
authorJens Axboe <axboe@fb.com>
Thu, 7 Jan 2016 22:06:22 +0000 (15:06 -0700)
committerJens Axboe <axboe@fb.com>
Thu, 7 Jan 2016 22:06:22 +0000 (15:06 -0700)
Signed-off-by: Jens Axboe <axboe@fb.com>
Makefile
t/verify-state.c [new file with mode: 0644]

index bd5f1bbe352a77e962f993a8a612d5536c40c5b5..b6ebf2fef010e6545ffe81e28d8df5785da8c597 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -223,6 +223,9 @@ T_DEDUPE_OBJS += lib/rbtree.o t/log.o mutex.o smalloc.o gettime.o crc/md5.o \
                crc/murmur3.o crc/crc32c.o crc/crc32c-intel.o crc/fnv.o
 T_DEDUPE_PROGS = t/fio-dedupe
 
+T_VS_OBJS = t/verify-state.o t/log.o crc/crc32c.o crc/crc32c-intel.o t/debug.o
+T_VS_PROGS = t/fio-verify-state
+
 T_OBJS = $(T_SMALLOC_OBJS)
 T_OBJS += $(T_IEEE_OBJS)
 T_OBJS += $(T_ZIPF_OBJS)
@@ -230,6 +233,7 @@ T_OBJS += $(T_AXMAP_OBJS)
 T_OBJS += $(T_LFSR_TEST_OBJS)
 T_OBJS += $(T_BTRACE_FIO_OBJS)
 T_OBJS += $(T_DEDUPE_OBJS)
+T_OBJS += $(T_VS_OBJS)
 
 ifneq (,$(findstring CYGWIN,$(CONFIG_TARGET_OS)))
     T_DEDUPE_OBJS += os/windows/posix.o lib/hweight.o
@@ -245,6 +249,7 @@ T_TEST_PROGS += $(T_AXMAP_PROGS)
 T_TEST_PROGS += $(T_LFSR_TEST_PROGS)
 T_PROGS += $(T_BTRACE_FIO_PROGS)
 T_PROGS += $(T_DEDUPE_PROGS)
+T_PROGS += $(T_VS_PROGS)
 
 PROGS += $(T_PROGS)
 
@@ -390,6 +395,9 @@ endif
 t/fio-dedupe: $(T_DEDUPE_OBJS)
        $(QUIET_LINK)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_DEDUPE_OBJS) $(LIBS)
 
+t/fio-verify-state: $(T_VS_OBJS)
+       $(QUIET_LINK)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_VS_OBJS) $(LIBS)
+
 clean: FORCE
        @rm -f .depend $(FIO_OBJS) $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(PROGS) $(T_PROGS) $(T_TEST_PROGS) core.* core gfio FIO-VERSION-FILE *.d lib/*.d oslib/*.d crc/*.d engines/*.d profiles/*.d t/*.d config-host.mak config-host.h y.tab.[ch] lex.yy.c exp/*.[do] lexer.h
 
diff --git a/t/verify-state.c b/t/verify-state.c
new file mode 100644 (file)
index 0000000..cb5ef31
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Dump the contents of a verify state file in plain text
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include "../log.h"
+#include "../os/os.h"
+#include "../verify-state.h"
+#include "../crc/crc32c.h"
+#include "debug.h"
+
+static void show_s(struct thread_io_list *s, unsigned int no_s)
+{
+       int i;
+
+       printf("Thread %u, %s\n", no_s, s->name);
+       printf("Completions: %lu\n", s->no_comps);
+       printf("Depth: %lu\n", s->depth);
+       printf("Number IOs: %lu\n", s->numberio);
+       printf("Index: %lu\n", s->index);
+
+       printf("Completions:\n");
+       for (i = 0; i < s->no_comps; i++)
+               printf("\t%lu\n", s->offsets[i]);
+}
+
+static void show_verify_state(void *buf, size_t size)
+{
+       struct verify_state_hdr *hdr = buf;
+       struct thread_io_list *s;
+       uint32_t crc;
+       int no_s;
+
+       hdr->version = le64_to_cpu(hdr->version);
+       hdr->size = le64_to_cpu(hdr->size);
+       hdr->crc = le64_to_cpu(hdr->crc);
+
+       printf("Version: %x, Size %u, crc %x\n", (unsigned int) hdr->version,
+                                               (unsigned int) hdr->size,
+                                               (unsigned int) hdr->crc);
+
+       size -= sizeof(*hdr);
+       if (hdr->size != size) {
+               log_err("Size mismatch\n");
+               return;
+       }
+
+       s = buf + sizeof(*hdr);
+       crc = fio_crc32c((unsigned char *) s, hdr->size);
+       if (crc != hdr->crc) {
+               log_err("crc mismatch %x != %x\n", crc, (unsigned int) hdr->crc);
+               return;
+       }
+
+       if (hdr->version != 0x02) {
+               log_err("Can only handle version 2 headers\n");
+               return;
+       }
+
+       no_s = 0;
+       do {
+               int i;
+
+               s->no_comps = le64_to_cpu(s->no_comps);
+               s->depth = le64_to_cpu(s->depth);
+               s->numberio = le64_to_cpu(s->numberio);
+               s->index = le64_to_cpu(s->index);
+
+               for (i = 0; i < s->no_comps; i++)
+                       s->offsets[i] = le64_to_cpu(s->offsets[i]);
+
+               show_s(s, no_s);
+               no_s++;
+               size -= __thread_io_list_sz(s->depth);
+               s = (void *) s + __thread_io_list_sz(s->depth);
+       } while (size != 0);
+}
+
+int main(int argc, char *argv[])
+{
+       struct stat sb;
+       void *buf;
+       int ret, fd;
+
+       debug_init();
+
+       if (argc < 2) {
+               log_err("Usage: %s <state file>\n", argv[0]);
+               return 1;
+       }
+
+       fd = open(argv[1], O_RDONLY);
+       if (fd < 0) {
+               log_err("open %s: %s\n", argv[1], strerror(errno));
+               return 1;
+       }
+
+       if (fstat(fd, &sb) < 0) {
+               log_err("stat: %s\n", strerror(errno));
+               close(fd);
+               return 1;
+       }
+
+       buf = malloc(sb.st_size);
+       ret = read(fd, buf, sb.st_size);
+       if (ret < 0) {
+               log_err("read: %s\n", strerror(errno));
+               close(fd);
+               return 1;
+       } else if (ret != sb.st_size) {
+               log_err("Short read\n");
+               close(fd);
+               return 1;
+       }
+
+       close(fd);
+       show_verify_state(buf, sb.st_size);
+
+       free(buf);
+       return 0;
+}