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