1 /* 2 * Dump the contents of a verify state file in plain text 3 */ 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <unistd.h> 9 #include <errno.h> 10 #include <fcntl.h> 11 #include <string.h> 12 #include "../log.h" 13 #include "../os/os.h" 14 #include "../verify-state.h" 15 #include "../crc/crc32c.h" 16 #include "debug.h" 17 18 static void show_s(struct thread_io_list *s, unsigned int no_s) 19 { 20 int i; 21 22 printf("Thread:\t\t%u\n", no_s); 23 printf("Name:\t\t%s\n", s->name); 24 printf("Completions:\t%llu\n", (unsigned long long) s->no_comps); 25 printf("Depth:\t\t%llu\n", (unsigned long long) s->depth); 26 printf("Number IOs:\t%llu\n", (unsigned long long) s->numberio); 27 printf("Index:\t\t%llu\n", (unsigned long long) s->index); 28 29 printf("Completions:\n"); 30 if (!s->no_comps) 31 return; 32 for (i = s->no_comps - 1; i >= 0; i--) { 33 printf("\t(file=%2llu) %llu\n", 34 (unsigned long long) s->comps[i].fileno, 35 (unsigned long long) s->comps[i].offset); 36 } 37 } 38 39 static void show(struct thread_io_list *s, size_t size) 40 { 41 int no_s; 42 43 no_s = 0; 44 do { 45 int i; 46 47 s->no_comps = le64_to_cpu(s->no_comps); 48 s->depth = le32_to_cpu(s->depth); 49 s->nofiles = le32_to_cpu(s->nofiles); 50 s->numberio = le64_to_cpu(s->numberio); 51 s->index = le64_to_cpu(s->index); 52 53 for (i = 0; i < s->no_comps; i++) { 54 s->comps[i].fileno = le64_to_cpu(s->comps[i].fileno); 55 s->comps[i].offset = le64_to_cpu(s->comps[i].offset); 56 } 57 58 show_s(s, no_s); 59 no_s++; 60 size -= __thread_io_list_sz(s->depth, s->nofiles); 61 s = (void *) s + __thread_io_list_sz(s->depth, s->nofiles); 62 } while (size != 0); 63 } 64 65 static void show_verify_state(void *buf, size_t size) 66 { 67 struct verify_state_hdr *hdr = buf; 68 struct thread_io_list *s; 69 uint32_t crc; 70 71 hdr->version = le64_to_cpu(hdr->version); 72 hdr->size = le64_to_cpu(hdr->size); 73 hdr->crc = le64_to_cpu(hdr->crc); 74 75 printf("Version:\t0x%x\n", (unsigned int) hdr->version); 76 printf("Size:\t\t%u\n", (unsigned int) hdr->size); 77 printf("CRC:\t\t0x%x\n", (unsigned int) hdr->crc); 78 79 size -= sizeof(*hdr); 80 if (hdr->size != size) { 81 log_err("Size mismatch\n"); 82 return; 83 } 84 85 s = buf + sizeof(*hdr); 86 crc = fio_crc32c((unsigned char *) s, hdr->size); 87 if (crc != hdr->crc) { 88 log_err("crc mismatch %x != %x\n", crc, (unsigned int) hdr->crc); 89 return; 90 } 91 92 if (hdr->version == 0x03) 93 show(s, size); 94 else 95 log_err("Unsupported version %d\n", (int) hdr->version); 96 } 97 98 static int show_file(const char *file) 99 { 100 struct stat sb; 101 void *buf; 102 int ret, fd; 103 104 fd = open(file, O_RDONLY); 105 if (fd < 0) { 106 log_err("open %s: %s\n", file, strerror(errno)); 107 return 1; 108 } 109 110 if (fstat(fd, &sb) < 0) { 111 log_err("stat: %s\n", strerror(errno)); 112 close(fd); 113 return 1; 114 } 115 116 buf = malloc(sb.st_size); 117 ret = read(fd, buf, sb.st_size); 118 if (ret < 0) { 119 log_err("read: %s\n", strerror(errno)); 120 close(fd); 121 return 1; 122 } else if (ret != sb.st_size) { 123 log_err("Short read\n"); 124 close(fd); 125 return 1; 126 } 127 128 close(fd); 129 show_verify_state(buf, sb.st_size); 130 131 free(buf); 132 return 0; 133 } 134 135 int main(int argc, char *argv[]) 136 { 137 int i, ret; 138 139 debug_init(); 140 141 if (argc < 2) { 142 log_err("Usage: %s <state file>\n", argv[0]); 143 return 1; 144 } 145 146 ret = 0; 147 for (i = 1; i < argc; i++) { 148 ret = show_file(argv[i]); 149 if (ret) 150 break; 151 } 152 153 return ret; 154 } 155