backend: make it clear that we passed 'fd' to the new thread
[fio.git] / t / verify-state.c
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 = (struct thread_io_list *)((char *) s +
62                         __thread_io_list_sz(s->depth, s->nofiles));
63         } while (size != 0);
64 }
65
66 static void show_verify_state(void *buf, size_t size)
67 {
68         struct verify_state_hdr *hdr = buf;
69         struct thread_io_list *s;
70         uint32_t crc;
71
72         hdr->version = le64_to_cpu(hdr->version);
73         hdr->size = le64_to_cpu(hdr->size);
74         hdr->crc = le64_to_cpu(hdr->crc);
75
76         printf("Version:\t0x%x\n", (unsigned int) hdr->version);
77         printf("Size:\t\t%u\n", (unsigned int) hdr->size);
78         printf("CRC:\t\t0x%x\n", (unsigned int) hdr->crc);
79
80         size -= sizeof(*hdr);
81         if (hdr->size != size) {
82                 log_err("Size mismatch\n");
83                 return;
84         }
85
86         s = buf + sizeof(*hdr);
87         crc = fio_crc32c((unsigned char *) s, hdr->size);
88         if (crc != hdr->crc) {
89                 log_err("crc mismatch %x != %x\n", crc, (unsigned int) hdr->crc);
90                 return;
91         }
92
93         if (hdr->version == 0x03)
94                 show(s, size);
95         else
96                 log_err("Unsupported version %d\n", (int) hdr->version);
97 }
98
99 static int show_file(const char *file)
100 {
101         struct stat sb;
102         void *buf;
103         int ret, fd;
104
105         fd = open(file, O_RDONLY);
106         if (fd < 0) {
107                 log_err("open %s: %s\n", file, strerror(errno));
108                 return 1;
109         }
110
111         if (fstat(fd, &sb) < 0) {
112                 log_err("stat: %s\n", strerror(errno));
113                 close(fd);
114                 return 1;
115         }
116
117         buf = malloc(sb.st_size);
118         ret = read(fd, buf, sb.st_size);
119         if (ret < 0) {
120                 log_err("read: %s\n", strerror(errno));
121                 close(fd);
122                 return 1;
123         } else if (ret != sb.st_size) {
124                 log_err("Short read\n");
125                 close(fd);
126                 return 1;
127         }
128
129         close(fd);
130         show_verify_state(buf, sb.st_size);
131
132         free(buf);
133         return 0;
134 }
135
136 int main(int argc, char *argv[])
137 {
138         int i, ret;
139
140         debug_init();
141
142         if (argc < 2) {
143                 log_err("Usage: %s <state file>\n", argv[0]);
144                 return 1;
145         }
146
147         ret = 0;
148         for (i = 1; i < argc; i++) {
149                 ret = show_file(argv[i]);
150                 if (ret)
151                         break;
152         }
153
154         return ret;
155 }