fio: minor HOWTO fix
[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;
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,
171                                     unsigned char header_num)
172 {
173         return io_u->buf + header_num * hdr->len + hdr_size(hdr);
174 }
175
176 static int verify_io_u_meta(struct verify_header *hdr, struct thread_data *td,
177                             struct io_u *io_u, unsigned int header_num)
178 {
179         struct vhdr_meta *vh = hdr_priv(hdr);
180
181         dprint(FD_VERIFY, "meta verify io_u %p, len %u\n", io_u, hdr->len);
182
183         if (vh->offset != io_u->offset + header_num * td->o.verify_interval) {
184                 log_err("meta: verify failed at %llu/%u\n",
185                               io_u->offset + header_num * hdr->len,
186                               hdr->len);
187                 return EIO;
188         }
189
190         return 0;
191 }
192
193 static int verify_io_u_sha512(struct verify_header *hdr, struct io_u *io_u,
194                               unsigned int header_num)
195 {
196         void *p = io_u_verify_off(hdr, io_u, header_num);
197         struct vhdr_sha512 *vh = hdr_priv(hdr);
198         uint8_t sha512[128];
199         struct sha512_ctx sha512_ctx = {
200                 .buf = sha512,
201         };
202
203         dprint(FD_VERIFY, "sha512 verify io_u %p, len %u\n", io_u, hdr->len);
204
205         sha512_init(&sha512_ctx);
206         sha512_update(&sha512_ctx, p, hdr->len - hdr_size(hdr));
207
208         if (memcmp(vh->sha512, sha512_ctx.buf, sizeof(sha512))) {
209                 log_err("sha512: verify failed at %llu/%u\n",
210                               io_u->offset + header_num * hdr->len,
211                               hdr->len);
212                 hexdump(vh->sha512, sizeof(vh->sha512));
213                 hexdump(sha512_ctx.buf, sizeof(sha512));
214                 return EIO;
215         }
216
217         return 0;
218 }
219
220 static int verify_io_u_sha256(struct verify_header *hdr, struct io_u *io_u,
221                               unsigned int header_num)
222 {
223         void *p = io_u_verify_off(hdr, io_u, header_num);
224         struct vhdr_sha256 *vh = hdr_priv(hdr);
225         uint8_t sha256[128];
226         struct sha256_ctx sha256_ctx = {
227                 .buf = sha256,
228         };
229
230         dprint(FD_VERIFY, "sha256 verify io_u %p, len %u\n", io_u, hdr->len);
231
232         sha256_init(&sha256_ctx);
233         sha256_update(&sha256_ctx, p, hdr->len - hdr_size(hdr));
234
235         if (memcmp(vh->sha256, sha256_ctx.buf, sizeof(sha256))) {
236                 log_err("sha256: verify failed at %llu/%u\n",
237                               io_u->offset + header_num * hdr->len,
238                               hdr->len);
239                 hexdump(vh->sha256, sizeof(vh->sha256));
240                 hexdump(sha256_ctx.buf, sizeof(sha256));
241                 return EIO;
242         }
243
244         return 0;
245 }
246
247 static int verify_io_u_crc7(struct verify_header *hdr, struct io_u *io_u,
248                             unsigned char header_num)
249 {
250         void *p = io_u_verify_off(hdr, io_u, header_num);
251         struct vhdr_crc7 *vh = hdr_priv(hdr);
252         unsigned char c;
253
254         dprint(FD_VERIFY, "crc7 verify io_u %p, len %u\n", io_u, hdr->len);
255
256         c = crc7(p, hdr->len - hdr_size(hdr));
257
258         if (c != vh->crc7) {
259                 log_err("crc7: verify failed at %llu/%u\n",
260                                 io_u->offset + header_num * hdr->len,
261                                 hdr->len);
262                 log_err("crc7: wanted %x, got %x\n", vh->crc7, c);
263                 return EIO;
264         }
265
266         return 0;
267 }
268
269 static int verify_io_u_crc16(struct verify_header *hdr, struct io_u *io_u,
270                              unsigned int header_num)
271 {
272         void *p = io_u_verify_off(hdr, io_u, header_num);
273         struct vhdr_crc16 *vh = hdr_priv(hdr);
274         unsigned short c;
275
276         dprint(FD_VERIFY, "crc16 verify io_u %p, len %u\n", io_u, hdr->len);
277
278         c = crc16(p, hdr->len - hdr_size(hdr));
279
280         if (c != vh->crc16) {
281                 log_err("crc16: verify failed at %llu/%u\n",
282                                 io_u->offset + header_num * hdr->len,
283                                 hdr->len);
284                 log_err("crc16: wanted %x, got %x\n", vh->crc16, c);
285                 return EIO;
286         }
287
288         return 0;
289 }
290
291 static int verify_io_u_crc64(struct verify_header *hdr, struct io_u *io_u,
292                              unsigned int header_num)
293 {
294         void *p = io_u_verify_off(hdr, io_u, header_num);
295         struct vhdr_crc64 *vh = hdr_priv(hdr);
296         unsigned long long c;
297
298         dprint(FD_VERIFY, "crc64 verify io_u %p, len %u\n", io_u, hdr->len);
299
300         c = crc64(p, hdr->len - hdr_size(hdr));
301
302         if (c != vh->crc64) {
303                 log_err("crc64: verify failed at %llu/%u\n",
304                                 io_u->offset + header_num * hdr->len,
305                                 hdr->len);
306                 log_err("crc64: wanted %llx, got %llx\n", (unsigned long long) vh->crc64, c);
307                 return EIO;
308         }
309
310         return 0;
311 }
312
313 static int verify_io_u_crc32(struct verify_header *hdr, struct io_u *io_u,
314                              unsigned int header_num)
315 {
316         void *p = io_u_verify_off(hdr, io_u, header_num);
317         struct vhdr_crc32 *vh = hdr_priv(hdr);
318         uint32_t c;
319
320         dprint(FD_VERIFY, "crc32 verify io_u %p, len %u\n", io_u, hdr->len);
321
322         c = crc32(p, hdr->len - hdr_size(hdr));
323
324         if (c != vh->crc32) {
325                 log_err("crc32: verify failed at %llu/%u\n",
326                                 io_u->offset + header_num * hdr->len,
327                                 hdr->len);
328                 log_err("crc32: wanted %x, got %x\n", vh->crc32, c);
329                 return EIO;
330         }
331
332         return 0;
333 }
334
335 static int verify_io_u_md5(struct verify_header *hdr, struct io_u *io_u,
336                            unsigned int header_num)
337 {
338         void *p = io_u_verify_off(hdr, io_u, header_num);
339         struct vhdr_md5 *vh = hdr_priv(hdr);
340         uint32_t hash[MD5_HASH_WORDS];
341         struct md5_ctx md5_ctx = {
342                 .hash = hash,
343         };
344
345         dprint(FD_VERIFY, "md5 verify io_u %p, len %u\n", io_u, hdr->len);
346
347         md5_init(&md5_ctx);
348         md5_update(&md5_ctx, p, hdr->len - hdr_size(hdr));
349
350         if (memcmp(vh->md5_digest, md5_ctx.hash, sizeof(hash))) {
351                 log_err("md5: verify failed at %llu/%u\n",
352                               io_u->offset + header_num * hdr->len,
353                               hdr->len);
354                 hexdump(vh->md5_digest, sizeof(vh->md5_digest));
355                 hexdump(md5_ctx.hash, sizeof(hash));
356                 return EIO;
357         }
358
359         return 0;
360 }
361
362 static unsigned int hweight8(unsigned int w)
363 {
364         unsigned int res = w - ((w >> 1) & 0x55);
365
366         res = (res & 0x33) + ((res >> 2) & 0x33);
367         return (res + (res >> 4)) & 0x0F;
368 }
369
370 int verify_io_u_pattern(unsigned long pattern, unsigned long pattern_size,
371                         char *buf, unsigned int len, unsigned int mod)
372 {
373         unsigned int i;
374         char split_pattern[4];
375
376         for (i = 0; i < 4; i++) {
377                 split_pattern[i] = pattern & 0xff;
378                 pattern >>= 8;
379         }
380
381         for (i = 0; i < len; i++) {
382                 if (buf[i] != split_pattern[mod]) {
383                         unsigned int bits;
384
385                         bits = hweight8(buf[i] ^ split_pattern[mod]);
386                         log_err("fio: got pattern %x, wanted %x. Bad bits %d\n",
387                                 buf[i], split_pattern[mod], bits);
388                         log_err("fio: bad pattern block offset %u\n", i);
389                         return EIO;
390                 }
391                 mod++;
392                 if (mod == pattern_size)
393                         mod = 0;
394         }
395
396         return 0;
397 }
398
399 int verify_io_u(struct thread_data *td, struct io_u *io_u)
400 {
401         struct verify_header *hdr;
402         unsigned int hdr_size, hdr_inc, hdr_num = 0;
403         void *p;
404         int ret;
405
406         if (td->o.verify == VERIFY_NULL || io_u->ddir != DDIR_READ)
407                 return 0;
408
409         hdr_inc = io_u->buflen;
410         if (td->o.verify_interval)
411                 hdr_inc = td->o.verify_interval;
412
413         ret = 0;
414         for (p = io_u->buf; p < io_u->buf + io_u->buflen; p += hdr_inc, hdr_num++) {
415                 if (ret && td->o.verify_fatal) {
416                         td->terminate = 1;
417                         break;
418                 }
419                 hdr_size = __hdr_size(td->o.verify);
420                 if (td->o.verify_offset)
421                         memswp(p, p + td->o.verify_offset, hdr_size);
422                 hdr = p;
423
424                 if (hdr->fio_magic != FIO_HDR_MAGIC) {
425                         log_err("Bad verify header %x\n", hdr->fio_magic);
426                         return EIO;
427                 }
428
429                 if (td->o.verify_pattern_bytes) {
430                         dprint(FD_VERIFY, "pattern verify io_u %p, len %u\n",
431                                                                 io_u, hdr->len);
432                         ret = verify_io_u_pattern(td->o.verify_pattern,
433                                                   td->o.verify_pattern_bytes,
434                                                   p + hdr_size,
435                                                   hdr_inc - hdr_size,
436                                                   hdr_size % 4);
437                         if (ret)
438                                 log_err("fio: verify failed at %llu/%u\n",
439                                         io_u->offset + hdr_num * hdr->len,
440                                         hdr->len);
441                         continue;
442                 }
443
444                 switch (hdr->verify_type) {
445                 case VERIFY_MD5:
446                         ret = verify_io_u_md5(hdr, io_u, hdr_num);
447                         break;
448                 case VERIFY_CRC64:
449                         ret = verify_io_u_crc64(hdr, io_u, hdr_num);
450                         break;
451                 case VERIFY_CRC32:
452                         ret = verify_io_u_crc32(hdr, io_u, hdr_num);
453                         break;
454                 case VERIFY_CRC16:
455                         ret = verify_io_u_crc16(hdr, io_u, hdr_num);
456                         break;
457                 case VERIFY_CRC7:
458                         ret = verify_io_u_crc7(hdr, io_u, hdr_num);
459                         break;
460                 case VERIFY_SHA256:
461                         ret = verify_io_u_sha256(hdr, io_u, hdr_num);
462                         break;
463                 case VERIFY_SHA512:
464                         ret = verify_io_u_sha512(hdr, io_u, hdr_num);
465                         break;
466                 case VERIFY_META:
467                         ret = verify_io_u_meta(hdr, td, io_u, hdr_num);
468                         break;
469                 default:
470                         log_err("Bad verify type %u\n", hdr->verify_type);
471                         ret = EINVAL;
472                 }
473         }
474
475         return ret;
476 }
477
478 static void fill_meta(struct verify_header *hdr, struct thread_data *td,
479                       struct io_u *io_u, unsigned int header_num)
480 {
481         struct vhdr_meta *vh = hdr_priv(hdr);
482
483         vh->thread = td->thread_number;
484
485         vh->time_sec = io_u->start_time.tv_sec;
486         vh->time_usec = io_u->start_time.tv_usec;
487
488         vh->numberio = td->io_issues[DDIR_WRITE];
489
490         vh->offset = io_u->offset + header_num * td->o.verify_interval;
491 }
492
493 static void fill_sha512(struct verify_header *hdr, void *p, unsigned int len)
494 {
495         struct vhdr_sha512 *vh = hdr_priv(hdr);
496         struct sha512_ctx sha512_ctx = {
497                 .buf = vh->sha512,
498         };
499
500         sha512_init(&sha512_ctx);
501         sha512_update(&sha512_ctx, p, len);
502 }
503
504 static void fill_sha256(struct verify_header *hdr, void *p, unsigned int len)
505 {
506         struct vhdr_sha256 *vh = hdr_priv(hdr);
507         struct sha256_ctx sha256_ctx = {
508                 .buf = vh->sha256,
509         };
510
511         sha256_init(&sha256_ctx);
512         sha256_update(&sha256_ctx, p, len);
513 }
514
515 static void fill_crc7(struct verify_header *hdr, void *p, unsigned int len)
516 {
517         struct vhdr_crc7 *vh = hdr_priv(hdr);
518
519         vh->crc7 = crc7(p, len);
520 }
521
522 static void fill_crc16(struct verify_header *hdr, void *p, unsigned int len)
523 {
524         struct vhdr_crc16 *vh = hdr_priv(hdr);
525
526         vh->crc16 = crc16(p, len);
527 }
528
529 static void fill_crc32(struct verify_header *hdr, void *p, unsigned int len)
530 {
531         struct vhdr_crc32 *vh = hdr_priv(hdr);
532
533         vh->crc32 = crc32(p, len);
534 }
535
536 static void fill_crc64(struct verify_header *hdr, void *p, unsigned int len)
537 {
538         struct vhdr_crc64 *vh = hdr_priv(hdr);
539
540         vh->crc64 = crc64(p, len);
541 }
542
543 static void fill_md5(struct verify_header *hdr, void *p, unsigned int len)
544 {
545         struct vhdr_md5 *vh = hdr_priv(hdr);
546         struct md5_ctx md5_ctx = {
547                 .hash = (uint32_t *) vh->md5_digest,
548         };
549
550         md5_init(&md5_ctx);
551         md5_update(&md5_ctx, p, len);
552 }
553
554 /*
555  * fill body of io_u->buf with random data and add a header with the
556  * crc32 or md5 sum of that data.
557  */
558 void populate_verify_io_u(struct thread_data *td, struct io_u *io_u)
559 {
560         struct verify_header *hdr;
561         void *p = io_u->buf, *data;
562         unsigned int hdr_inc, data_len, header_num = 0;
563
564         if (td->o.verify == VERIFY_NULL)
565                 return;
566
567         fill_pattern(td, p, io_u->buflen);
568
569         hdr_inc = io_u->buflen;
570         if (td->o.verify_interval)
571                 hdr_inc = td->o.verify_interval;
572
573         for (;p < io_u->buf + io_u->buflen; p += hdr_inc) {
574                 hdr = p;
575
576                 hdr->fio_magic = FIO_HDR_MAGIC;
577                 hdr->verify_type = td->o.verify;
578                 hdr->len = hdr_inc;
579                 data_len = hdr_inc - hdr_size(hdr);
580
581                 data = p + hdr_size(hdr);
582                 switch (td->o.verify) {
583                 case VERIFY_MD5:
584                         dprint(FD_VERIFY, "fill md5 io_u %p, len %u\n",
585                                                         io_u, hdr->len);
586                         fill_md5(hdr, data, data_len);
587                         break;
588                 case VERIFY_CRC64:
589                         dprint(FD_VERIFY, "fill crc64 io_u %p, len %u\n",
590                                                         io_u, hdr->len);
591                         fill_crc64(hdr, data, data_len);
592                         break;
593                 case VERIFY_CRC32:
594                         dprint(FD_VERIFY, "fill crc32 io_u %p, len %u\n",
595                                                         io_u, hdr->len);
596                         fill_crc32(hdr, data, data_len);
597                         break;
598                 case VERIFY_CRC16:
599                         dprint(FD_VERIFY, "fill crc16 io_u %p, len %u\n",
600                                                         io_u, hdr->len);
601                         fill_crc16(hdr, data, data_len);
602                         break;
603                 case VERIFY_CRC7:
604                         dprint(FD_VERIFY, "fill crc7 io_u %p, len %u\n",
605                                                         io_u, hdr->len);
606                         fill_crc7(hdr, data, data_len);
607                         break;
608                 case VERIFY_SHA256:
609                         dprint(FD_VERIFY, "fill sha256 io_u %p, len %u\n",
610                                                         io_u, hdr->len);
611                         fill_sha256(hdr, data, data_len);
612                         break;
613                 case VERIFY_SHA512:
614                         dprint(FD_VERIFY, "fill sha512 io_u %p, len %u\n",
615                                                         io_u, hdr->len);
616                         fill_sha512(hdr, data, data_len);
617                         break;
618                 case VERIFY_META:
619                         dprint(FD_VERIFY, "fill meta io_u %p, len %u\n",
620                                                         io_u, hdr->len);
621                         fill_meta(hdr, td, io_u, header_num);
622                         break;
623                 default:
624                         log_err("fio: bad verify type: %d\n", td->o.verify);
625                         assert(0);
626                 }
627                 if (td->o.verify_offset)
628                         memswp(p, p + td->o.verify_offset, hdr_size(hdr));
629                 header_num++;
630         }
631 }
632
633 int get_next_verify(struct thread_data *td, struct io_u *io_u)
634 {
635         struct io_piece *ipo = NULL;
636
637         /*
638          * this io_u is from a requeue, we already filled the offsets
639          */
640         if (io_u->file)
641                 return 0;
642
643         if (!RB_EMPTY_ROOT(&td->io_hist_tree)) {
644                 struct rb_node *n = rb_first(&td->io_hist_tree);
645
646                 ipo = rb_entry(n, struct io_piece, rb_node);
647                 rb_erase(n, &td->io_hist_tree);
648         } else if (!list_empty(&td->io_hist_list)) {
649                 ipo = list_entry(td->io_hist_list.next, struct io_piece, list);
650                 list_del(&ipo->list);
651         }
652
653         if (ipo) {
654                 io_u->offset = ipo->offset;
655                 io_u->buflen = ipo->len;
656                 io_u->file = ipo->file;
657
658                 if ((io_u->file->flags & FIO_FILE_OPEN) == 0) {
659                         int r = td_io_open_file(td, io_u->file);
660
661                         if (r) {
662                                 dprint(FD_VERIFY, "failed file %s open\n",
663                                                 io_u->file->file_name);
664                                 return 1;
665                         }
666                 }
667
668                 get_file(ipo->file);
669                 assert(io_u->file->flags & FIO_FILE_OPEN);
670                 io_u->ddir = DDIR_READ;
671                 io_u->xfer_buf = io_u->buf;
672                 io_u->xfer_buflen = io_u->buflen;
673                 free(ipo);
674                 dprint(FD_VERIFY, "get_next_verify: ret io_u %p\n", io_u);
675                 return 0;
676         }
677
678         dprint(FD_VERIFY, "get_next_verify: empty\n");
679         return 1;
680 }