Fio 1.21-rc4
[fio.git] / verify.c
1 /*
2  * IO verification helpers
3  */
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <string.h>
7 #include <assert.h>
8
9 #include "fio.h"
10
11 #include "crc/md5.h"
12 #include "crc/crc64.h"
13 #include "crc/crc32.h"
14 #include "crc/crc16.h"
15 #include "crc/crc7.h"
16 #include "crc/sha256.h"
17 #include "crc/sha512.h"
18
19 static void fill_random_bytes(struct thread_data *td, void *p, unsigned int len)
20 {
21         unsigned int todo;
22         int r;
23
24         while (len) {
25                 r = os_random_long(&td->verify_state);
26
27                 /*
28                  * lrand48_r seems to be broken and only fill the bottom
29                  * 32-bits, even on 64-bit archs with 64-bit longs
30                  */
31                 todo = sizeof(r);
32                 if (todo > len)
33                         todo = len;
34
35                 memcpy(p, &r, todo);
36
37                 len -= todo;
38                 p += todo;
39         }
40 }
41
42 static void fill_pattern(struct thread_data *td, void *p, unsigned int len)
43 {
44         switch (td->o.verify_pattern_bytes) {
45         case 0:
46                 dprint(FD_VERIFY, "fill random bytes len=%u\n", len);
47                 fill_random_bytes(td, p, len);
48                 break;
49         case 1:
50                 dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len);
51                 memset(p, td->o.verify_pattern, len);
52                 break;
53         case 2:
54         case 3:
55         case 4: {
56                 unsigned int pattern = td->o.verify_pattern;
57                 unsigned int i = 0;
58                 unsigned char c1, c2, c3, c4;
59                 unsigned char *b = p;
60
61                 dprint(FD_VERIFY, "fill verify pattern b=%d len=%u\n",
62                                         td->o.verify_pattern_bytes, len);
63
64                 c1 = pattern & 0xff;
65                 pattern >>= 8;
66                 c2 = pattern & 0xff;
67                 pattern >>= 8;
68                 c3 = pattern & 0xff;
69                 pattern >>= 8;
70                 c4 = pattern & 0xff;
71
72                 while (i < len) {
73                         b[i++] = c1;
74                         if (i == len)
75                                 break;
76                         b[i++] = c2;
77                         if (td->o.verify_pattern_bytes == 2 || i == len)
78                                 continue;
79                         b[i++] = c3;
80                         if (td->o.verify_pattern_bytes == 3 || i == len)
81                                 continue;
82                         b[i++] = c4;
83                 }
84                 break;
85                 }
86         }
87 }
88
89 static void memswp(void *buf1, void *buf2, unsigned int len)
90 {
91         char swap[200];
92
93         assert(len <= sizeof(swap));
94
95         memcpy(&swap, buf1, len);
96         memcpy(buf1, buf2, len);
97         memcpy(buf2, &swap, len);
98 }
99
100 static void hexdump(void *buffer, int len)
101 {
102         unsigned char *p = buffer;
103         int i;
104
105         for (i = 0; i < len; i++)
106                 log_info("%02x", p[i]);
107         log_info("\n");
108 }
109
110 /*
111  * Prepare for seperation of verify_header and checksum header
112  */
113 static inline unsigned int __hdr_size(int verify_type)
114 {
115         unsigned int len = len;
116
117         switch (verify_type) {
118         case VERIFY_NONE:
119         case VERIFY_NULL:
120                 len = 0;
121                 break;
122         case VERIFY_MD5:
123                 len = sizeof(struct vhdr_md5);
124                 break;
125         case VERIFY_CRC64:
126                 len = sizeof(struct vhdr_crc64);
127                 break;
128         case VERIFY_CRC32:
129                 len = sizeof(struct vhdr_crc32);
130                 break;
131         case VERIFY_CRC16:
132                 len = sizeof(struct vhdr_crc16);
133                 break;
134         case VERIFY_CRC7:
135                 len = sizeof(struct vhdr_crc7);
136                 break;
137         case VERIFY_SHA256:
138                 len = sizeof(struct vhdr_sha256);
139                 break;
140         case VERIFY_SHA512:
141                 len = sizeof(struct vhdr_sha512);
142                 break;
143         case VERIFY_META:
144                 len = sizeof(struct vhdr_meta);
145                 break;
146         default:
147                 log_err("fio: unknown verify header!\n");
148                 assert(0);
149         }
150
151         return len + sizeof(struct verify_header);
152 }
153
154 static inline unsigned int hdr_size(struct verify_header *hdr)
155 {
156         return __hdr_size(hdr->verify_type);
157 }
158
159 static void *hdr_priv(struct verify_header *hdr)
160 {
161         void *priv = hdr;
162
163         return priv + sizeof(struct verify_header);
164 }
165
166 /*
167  * Return data area 'header_num'
168  */
169 static inline void *io_u_verify_off(struct verify_header *hdr,
170                                     struct io_u *io_u, unsigned char header_num)
171 {
172         return io_u->buf + header_num * hdr->len + hdr_size(hdr);
173 }
174
175 static int verify_io_u_meta(struct verify_header *hdr, struct thread_data *td,
176                             struct io_u *io_u, unsigned int header_num)
177 {
178         struct vhdr_meta *vh = hdr_priv(hdr);
179
180         dprint(FD_VERIFY, "meta verify io_u %p, len %u\n", io_u, hdr->len);
181
182         if (vh->offset != io_u->offset + header_num * td->o.verify_interval) {
183                 log_err("meta: verify failed at %llu/%u\n",
184                                 io_u->offset + header_num * hdr->len, hdr->len);
185                 return EIO;
186         }
187
188         return 0;
189 }
190
191 static int verify_io_u_sha512(struct verify_header *hdr, struct io_u *io_u,
192                               unsigned int header_num)
193 {
194         void *p = io_u_verify_off(hdr, io_u, header_num);
195         struct vhdr_sha512 *vh = hdr_priv(hdr);
196         uint8_t sha512[128];
197         struct sha512_ctx sha512_ctx = {
198                 .buf = sha512,
199         };
200
201         dprint(FD_VERIFY, "sha512 verify io_u %p, len %u\n", io_u, hdr->len);
202
203         sha512_init(&sha512_ctx);
204         sha512_update(&sha512_ctx, p, hdr->len - hdr_size(hdr));
205
206         if (memcmp(vh->sha512, sha512_ctx.buf, sizeof(sha512))) {
207                 log_err("sha512: verify failed at %llu/%u\n",
208                                 io_u->offset + header_num * hdr->len, hdr->len);
209                 hexdump(vh->sha512, sizeof(vh->sha512));
210                 hexdump(sha512_ctx.buf, sizeof(sha512));
211                 return EIO;
212         }
213
214         return 0;
215 }
216
217 static int verify_io_u_sha256(struct verify_header *hdr, struct io_u *io_u,
218                               unsigned int header_num)
219 {
220         void *p = io_u_verify_off(hdr, io_u, header_num);
221         struct vhdr_sha256 *vh = hdr_priv(hdr);
222         uint8_t sha256[128];
223         struct sha256_ctx sha256_ctx = {
224                 .buf = sha256,
225         };
226
227         dprint(FD_VERIFY, "sha256 verify io_u %p, len %u\n", io_u, hdr->len);
228
229         sha256_init(&sha256_ctx);
230         sha256_update(&sha256_ctx, p, hdr->len - hdr_size(hdr));
231
232         if (memcmp(vh->sha256, sha256_ctx.buf, sizeof(sha256))) {
233                 log_err("sha256: verify failed at %llu/%u\n",
234                                 io_u->offset + header_num * hdr->len, hdr->len);
235                 hexdump(vh->sha256, sizeof(vh->sha256));
236                 hexdump(sha256_ctx.buf, sizeof(sha256));
237                 return EIO;
238         }
239
240         return 0;
241 }
242
243 static int verify_io_u_crc7(struct verify_header *hdr, struct io_u *io_u,
244                             unsigned char header_num)
245 {
246         void *p = io_u_verify_off(hdr, io_u, header_num);
247         struct vhdr_crc7 *vh = hdr_priv(hdr);
248         unsigned char c;
249
250         dprint(FD_VERIFY, "crc7 verify io_u %p, len %u\n", io_u, hdr->len);
251
252         c = crc7(p, hdr->len - hdr_size(hdr));
253
254         if (c != vh->crc7) {
255                 log_err("crc7: verify failed at %llu/%u\n",
256                                 io_u->offset + header_num * hdr->len, hdr->len);
257                 log_err("crc7: wanted %x, got %x\n", vh->crc7, c);
258                 return EIO;
259         }
260
261         return 0;
262 }
263
264 static int verify_io_u_crc16(struct verify_header *hdr, struct io_u *io_u,
265                              unsigned int header_num)
266 {
267         void *p = io_u_verify_off(hdr, io_u, header_num);
268         struct vhdr_crc16 *vh = hdr_priv(hdr);
269         unsigned short c;
270
271         dprint(FD_VERIFY, "crc16 verify io_u %p, len %u\n", io_u, hdr->len);
272
273         c = crc16(p, hdr->len - hdr_size(hdr));
274
275         if (c != vh->crc16) {
276                 log_err("crc16: verify failed at %llu/%u\n",
277                                 io_u->offset + header_num * hdr->len, hdr->len);
278                 log_err("crc16: wanted %x, got %x\n", vh->crc16, c);
279                 return EIO;
280         }
281
282         return 0;
283 }
284
285 static int verify_io_u_crc64(struct verify_header *hdr, struct io_u *io_u,
286                              unsigned int header_num)
287 {
288         void *p = io_u_verify_off(hdr, io_u, header_num);
289         struct vhdr_crc64 *vh = hdr_priv(hdr);
290         unsigned long long c;
291
292         dprint(FD_VERIFY, "crc64 verify io_u %p, len %u\n", io_u, hdr->len);
293
294         c = crc64(p, hdr->len - hdr_size(hdr));
295
296         if (c != vh->crc64) {
297                 log_err("crc64: verify failed at %llu/%u\n",
298                                 io_u->offset + header_num * hdr->len,
299                                 hdr->len);
300                 log_err("crc64: wanted %llx, got %llx\n",
301                                         (unsigned long long) vh->crc64, c);
302                 return EIO;
303         }
304
305         return 0;
306 }
307
308 static int verify_io_u_crc32(struct verify_header *hdr, struct io_u *io_u,
309                              unsigned int header_num)
310 {
311         void *p = io_u_verify_off(hdr, io_u, header_num);
312         struct vhdr_crc32 *vh = hdr_priv(hdr);
313         uint32_t c;
314
315         dprint(FD_VERIFY, "crc32 verify io_u %p, len %u\n", io_u, hdr->len);
316
317         c = crc32(p, hdr->len - hdr_size(hdr));
318
319         if (c != vh->crc32) {
320                 log_err("crc32: verify failed at %llu/%u\n",
321                                 io_u->offset + header_num * hdr->len, hdr->len);
322                 log_err("crc32: wanted %x, got %x\n", vh->crc32, c);
323                 return EIO;
324         }
325
326         return 0;
327 }
328
329 static int verify_io_u_md5(struct verify_header *hdr, struct io_u *io_u,
330                            unsigned int header_num)
331 {
332         void *p = io_u_verify_off(hdr, io_u, header_num);
333         struct vhdr_md5 *vh = hdr_priv(hdr);
334         uint32_t hash[MD5_HASH_WORDS];
335         struct md5_ctx md5_ctx = {
336                 .hash = hash,
337         };
338
339         dprint(FD_VERIFY, "md5 verify io_u %p, len %u\n", io_u, hdr->len);
340
341         md5_init(&md5_ctx);
342         md5_update(&md5_ctx, p, hdr->len - hdr_size(hdr));
343
344         if (memcmp(vh->md5_digest, md5_ctx.hash, sizeof(hash))) {
345                 log_err("md5: verify failed at %llu/%u\n",
346                                 io_u->offset + header_num * hdr->len, hdr->len);
347                 hexdump(vh->md5_digest, sizeof(vh->md5_digest));
348                 hexdump(md5_ctx.hash, sizeof(hash));
349                 return EIO;
350         }
351
352         return 0;
353 }
354
355 static unsigned int hweight8(unsigned int w)
356 {
357         unsigned int res = w - ((w >> 1) & 0x55);
358
359         res = (res & 0x33) + ((res >> 2) & 0x33);
360         return (res + (res >> 4)) & 0x0F;
361 }
362
363 int verify_io_u_pattern(unsigned long pattern, unsigned long pattern_size,
364                         char *buf, unsigned int len, unsigned int mod)
365 {
366         unsigned int i;
367         char split_pattern[4];
368
369         for (i = 0; i < 4; i++) {
370                 split_pattern[i] = pattern & 0xff;
371                 pattern >>= 8;
372         }
373
374         for (i = 0; i < len; i++) {
375                 if (buf[i] != split_pattern[mod]) {
376                         unsigned int bits;
377
378                         bits = hweight8(buf[i] ^ split_pattern[mod]);
379                         log_err("fio: got pattern %x, wanted %x. Bad bits %d\n",
380                                 buf[i], split_pattern[mod], bits);
381                         log_err("fio: bad pattern block offset %u\n", i);
382                         return EIO;
383                 }
384                 mod++;
385                 if (mod == pattern_size)
386                         mod = 0;
387         }
388
389         return 0;
390 }
391
392 int verify_io_u(struct thread_data *td, struct io_u *io_u)
393 {
394         struct verify_header *hdr;
395         unsigned int hdr_size, hdr_inc, hdr_num = 0;
396         void *p;
397         int ret;
398
399         if (td->o.verify == VERIFY_NULL || io_u->ddir != DDIR_READ)
400                 return 0;
401
402         hdr_inc = io_u->buflen;
403         if (td->o.verify_interval)
404                 hdr_inc = td->o.verify_interval;
405
406         ret = 0;
407         for (p = io_u->buf; p < io_u->buf + io_u->buflen;
408              p += hdr_inc, hdr_num++) {
409                 if (ret && td->o.verify_fatal) {
410                         td->terminate = 1;
411                         break;
412                 }
413                 hdr_size = __hdr_size(td->o.verify);
414                 if (td->o.verify_offset)
415                         memswp(p, p + td->o.verify_offset, hdr_size);
416                 hdr = p;
417
418                 if (hdr->fio_magic != FIO_HDR_MAGIC) {
419                         log_err("Bad verify header %x\n", hdr->fio_magic);
420                         return EIO;
421                 }
422
423                 if (td->o.verify_pattern_bytes) {
424                         dprint(FD_VERIFY, "pattern verify io_u %p, len %u\n",
425                                                                 io_u, hdr->len);
426                         ret = verify_io_u_pattern(td->o.verify_pattern,
427                                                   td->o.verify_pattern_bytes,
428                                                   p + hdr_size,
429                                                   hdr_inc - hdr_size,
430                                                   hdr_size % 4);
431                         if (ret)
432                                 log_err("fio: verify failed at %llu/%u\n",
433                                         io_u->offset + hdr_num * hdr->len,
434                                         hdr->len);
435                         continue;
436                 }
437
438                 switch (hdr->verify_type) {
439                 case VERIFY_MD5:
440                         ret = verify_io_u_md5(hdr, io_u, hdr_num);
441                         break;
442                 case VERIFY_CRC64:
443                         ret = verify_io_u_crc64(hdr, io_u, hdr_num);
444                         break;
445                 case VERIFY_CRC32:
446                         ret = verify_io_u_crc32(hdr, io_u, hdr_num);
447                         break;
448                 case VERIFY_CRC16:
449                         ret = verify_io_u_crc16(hdr, io_u, hdr_num);
450                         break;
451                 case VERIFY_CRC7:
452                         ret = verify_io_u_crc7(hdr, io_u, hdr_num);
453                         break;
454                 case VERIFY_SHA256:
455                         ret = verify_io_u_sha256(hdr, io_u, hdr_num);
456                         break;
457                 case VERIFY_SHA512:
458                         ret = verify_io_u_sha512(hdr, io_u, hdr_num);
459                         break;
460                 case VERIFY_META:
461                         ret = verify_io_u_meta(hdr, td, io_u, hdr_num);
462                         break;
463                 default:
464                         log_err("Bad verify type %u\n", hdr->verify_type);
465                         ret = EINVAL;
466                 }
467         }
468
469         return ret;
470 }
471
472 static void fill_meta(struct verify_header *hdr, struct thread_data *td,
473                       struct io_u *io_u, unsigned int header_num)
474 {
475         struct vhdr_meta *vh = hdr_priv(hdr);
476
477         vh->thread = td->thread_number;
478
479         vh->time_sec = io_u->start_time.tv_sec;
480         vh->time_usec = io_u->start_time.tv_usec;
481
482         vh->numberio = td->io_issues[DDIR_WRITE];
483
484         vh->offset = io_u->offset + header_num * td->o.verify_interval;
485 }
486
487 static void fill_sha512(struct verify_header *hdr, void *p, unsigned int len)
488 {
489         struct vhdr_sha512 *vh = hdr_priv(hdr);
490         struct sha512_ctx sha512_ctx = {
491                 .buf = vh->sha512,
492         };
493
494         sha512_init(&sha512_ctx);
495         sha512_update(&sha512_ctx, p, len);
496 }
497
498 static void fill_sha256(struct verify_header *hdr, void *p, unsigned int len)
499 {
500         struct vhdr_sha256 *vh = hdr_priv(hdr);
501         struct sha256_ctx sha256_ctx = {
502                 .buf = vh->sha256,
503         };
504
505         sha256_init(&sha256_ctx);
506         sha256_update(&sha256_ctx, p, len);
507 }
508
509 static void fill_crc7(struct verify_header *hdr, void *p, unsigned int len)
510 {
511         struct vhdr_crc7 *vh = hdr_priv(hdr);
512
513         vh->crc7 = crc7(p, len);
514 }
515
516 static void fill_crc16(struct verify_header *hdr, void *p, unsigned int len)
517 {
518         struct vhdr_crc16 *vh = hdr_priv(hdr);
519
520         vh->crc16 = crc16(p, len);
521 }
522
523 static void fill_crc32(struct verify_header *hdr, void *p, unsigned int len)
524 {
525         struct vhdr_crc32 *vh = hdr_priv(hdr);
526
527         vh->crc32 = crc32(p, len);
528 }
529
530 static void fill_crc64(struct verify_header *hdr, void *p, unsigned int len)
531 {
532         struct vhdr_crc64 *vh = hdr_priv(hdr);
533
534         vh->crc64 = crc64(p, len);
535 }
536
537 static void fill_md5(struct verify_header *hdr, void *p, unsigned int len)
538 {
539         struct vhdr_md5 *vh = hdr_priv(hdr);
540         struct md5_ctx md5_ctx = {
541                 .hash = (uint32_t *) vh->md5_digest,
542         };
543
544         md5_init(&md5_ctx);
545         md5_update(&md5_ctx, p, len);
546 }
547
548 /*
549  * fill body of io_u->buf with random data and add a header with the
550  * crc32 or md5 sum of that data.
551  */
552 void populate_verify_io_u(struct thread_data *td, struct io_u *io_u)
553 {
554         struct verify_header *hdr;
555         void *p = io_u->buf, *data;
556         unsigned int hdr_inc, data_len, header_num = 0;
557
558         if (td->o.verify == VERIFY_NULL)
559                 return;
560
561         fill_pattern(td, p, io_u->buflen);
562
563         hdr_inc = io_u->buflen;
564         if (td->o.verify_interval)
565                 hdr_inc = td->o.verify_interval;
566
567         for (; p < io_u->buf + io_u->buflen; p += hdr_inc) {
568                 hdr = p;
569
570                 hdr->fio_magic = FIO_HDR_MAGIC;
571                 hdr->verify_type = td->o.verify;
572                 hdr->len = hdr_inc;
573                 data_len = hdr_inc - hdr_size(hdr);
574
575                 data = p + hdr_size(hdr);
576                 switch (td->o.verify) {
577                 case VERIFY_MD5:
578                         dprint(FD_VERIFY, "fill md5 io_u %p, len %u\n",
579                                                         io_u, hdr->len);
580                         fill_md5(hdr, data, data_len);
581                         break;
582                 case VERIFY_CRC64:
583                         dprint(FD_VERIFY, "fill crc64 io_u %p, len %u\n",
584                                                         io_u, hdr->len);
585                         fill_crc64(hdr, data, data_len);
586                         break;
587                 case VERIFY_CRC32:
588                         dprint(FD_VERIFY, "fill crc32 io_u %p, len %u\n",
589                                                         io_u, hdr->len);
590                         fill_crc32(hdr, data, data_len);
591                         break;
592                 case VERIFY_CRC16:
593                         dprint(FD_VERIFY, "fill crc16 io_u %p, len %u\n",
594                                                         io_u, hdr->len);
595                         fill_crc16(hdr, data, data_len);
596                         break;
597                 case VERIFY_CRC7:
598                         dprint(FD_VERIFY, "fill crc7 io_u %p, len %u\n",
599                                                         io_u, hdr->len);
600                         fill_crc7(hdr, data, data_len);
601                         break;
602                 case VERIFY_SHA256:
603                         dprint(FD_VERIFY, "fill sha256 io_u %p, len %u\n",
604                                                         io_u, hdr->len);
605                         fill_sha256(hdr, data, data_len);
606                         break;
607                 case VERIFY_SHA512:
608                         dprint(FD_VERIFY, "fill sha512 io_u %p, len %u\n",
609                                                         io_u, hdr->len);
610                         fill_sha512(hdr, data, data_len);
611                         break;
612                 case VERIFY_META:
613                         dprint(FD_VERIFY, "fill meta io_u %p, len %u\n",
614                                                         io_u, hdr->len);
615                         fill_meta(hdr, td, io_u, header_num);
616                         break;
617                 default:
618                         log_err("fio: bad verify type: %d\n", td->o.verify);
619                         assert(0);
620                 }
621                 if (td->o.verify_offset)
622                         memswp(p, p + td->o.verify_offset, hdr_size(hdr));
623                 header_num++;
624         }
625 }
626
627 int get_next_verify(struct thread_data *td, struct io_u *io_u)
628 {
629         struct io_piece *ipo = NULL;
630
631         /*
632          * this io_u is from a requeue, we already filled the offsets
633          */
634         if (io_u->file)
635                 return 0;
636
637         if (!RB_EMPTY_ROOT(&td->io_hist_tree)) {
638                 struct rb_node *n = rb_first(&td->io_hist_tree);
639
640                 ipo = rb_entry(n, struct io_piece, rb_node);
641                 rb_erase(n, &td->io_hist_tree);
642         } else if (!list_empty(&td->io_hist_list)) {
643                 ipo = list_entry(td->io_hist_list.next, struct io_piece, list);
644                 list_del(&ipo->list);
645         }
646
647         if (ipo) {
648                 io_u->offset = ipo->offset;
649                 io_u->buflen = ipo->len;
650                 io_u->file = ipo->file;
651
652                 if ((io_u->file->flags & FIO_FILE_OPEN) == 0) {
653                         int r = td_io_open_file(td, io_u->file);
654
655                         if (r) {
656                                 dprint(FD_VERIFY, "failed file %s open\n",
657                                                 io_u->file->file_name);
658                                 return 1;
659                         }
660                 }
661
662                 get_file(ipo->file);
663                 assert(io_u->file->flags & FIO_FILE_OPEN);
664                 io_u->ddir = DDIR_READ;
665                 io_u->xfer_buf = io_u->buf;
666                 io_u->xfer_buflen = io_u->buflen;
667                 free(ipo);
668                 dprint(FD_VERIFY, "get_next_verify: ret io_u %p\n", io_u);
669                 return 0;
670         }
671
672         dprint(FD_VERIFY, "get_next_verify: empty\n");
673         return 1;
674 }