f5ed51a5354c35486c727ed18c7591886fef3bde
[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         for (p = io_u->buf; p < io_u->buf + io_u->buflen; p += hdr_inc, hdr_num++) {
393                 hdr_size = __hdr_size(td->o.verify);
394                 if (td->o.verify_offset)
395                         memswp(p, p + td->o.verify_offset, hdr_size);
396                 hdr = p;
397
398                 if (hdr->fio_magic != FIO_HDR_MAGIC) {
399                         log_err("Bad verify header %x\n", hdr->fio_magic);
400                         return EIO;
401                 }
402
403                 if (td->o.verify_pattern_bytes) {
404                         ret = verify_io_u_pattern(td->o.verify_pattern,
405                                                   td->o.verify_pattern_bytes,
406                                                   p + hdr_size,
407                                                   hdr_inc - hdr_size,
408                                                   hdr_size % 4);
409                         if (ret)
410                                 log_err("fio: verify failed at %llu/%u\n",
411                                         io_u->offset + hdr_num * hdr->len,
412                                         hdr->len);
413                         continue;
414                 }
415
416                 switch (hdr->verify_type) {
417                 case VERIFY_MD5:
418                         ret = verify_io_u_md5(hdr, io_u, hdr_num);
419                         break;
420                 case VERIFY_CRC64:
421                         ret = verify_io_u_crc64(hdr, io_u, hdr_num);
422                         break;
423                 case VERIFY_CRC32:
424                         ret = verify_io_u_crc32(hdr, io_u, hdr_num);
425                         break;
426                 case VERIFY_CRC16:
427                         ret = verify_io_u_crc16(hdr, io_u, hdr_num);
428                         break;
429                 case VERIFY_CRC7:
430                         ret = verify_io_u_crc7(hdr, io_u, hdr_num);
431                         break;
432                 case VERIFY_SHA256:
433                         ret = verify_io_u_sha256(hdr, io_u, hdr_num);
434                         break;
435                 case VERIFY_SHA512:
436                         ret = verify_io_u_sha512(hdr, io_u, hdr_num);
437                         break;
438                 case VERIFY_META:
439                         ret = verify_io_u_meta(hdr, td, io_u, hdr_num);
440                         break;
441                 default:
442                         log_err("Bad verify type %u\n", hdr->verify_type);
443                         ret = 1;
444                 }
445         }
446
447         return 0;
448 }
449
450 static void fill_meta(struct verify_header *hdr, struct thread_data *td,
451                       struct io_u *io_u, unsigned int header_num)
452 {
453         struct vhdr_meta *vh = hdr_priv(hdr);
454
455         vh->thread = td->thread_number;
456
457         vh->time_sec = io_u->start_time.tv_sec;
458         vh->time_usec = io_u->start_time.tv_usec;
459
460         vh->numberio = td->io_issues[DDIR_WRITE];
461
462         vh->offset = io_u->offset + header_num * td->o.verify_interval;
463 }
464
465 static void fill_sha512(struct verify_header *hdr, void *p, unsigned int len)
466 {
467         struct vhdr_sha512 *vh = hdr_priv(hdr);
468         struct sha512_ctx sha512_ctx = {
469                 .buf = vh->sha512,
470         };
471
472         sha512_init(&sha512_ctx);
473         sha512_update(&sha512_ctx, p, len);
474 }
475
476 static void fill_sha256(struct verify_header *hdr, void *p, unsigned int len)
477 {
478         struct vhdr_sha256 *vh = hdr_priv(hdr);
479         struct sha256_ctx sha256_ctx = {
480                 .buf = vh->sha256,
481         };
482
483         sha256_init(&sha256_ctx);
484         sha256_update(&sha256_ctx, p, len);
485 }
486
487 static void fill_crc7(struct verify_header *hdr, void *p, unsigned int len)
488 {
489         struct vhdr_crc7 *vh = hdr_priv(hdr);
490
491         vh->crc7 = crc7(p, len);
492 }
493
494 static void fill_crc16(struct verify_header *hdr, void *p, unsigned int len)
495 {
496         struct vhdr_crc16 *vh = hdr_priv(hdr);
497
498         vh->crc16 = crc16(p, len);
499 }
500
501 static void fill_crc32(struct verify_header *hdr, void *p, unsigned int len)
502 {
503         struct vhdr_crc32 *vh = hdr_priv(hdr);
504
505         vh->crc32 = crc32(p, len);
506 }
507
508 static void fill_crc64(struct verify_header *hdr, void *p, unsigned int len)
509 {
510         struct vhdr_crc64 *vh = hdr_priv(hdr);
511
512         vh->crc64 = crc64(p, len);
513 }
514
515 static void fill_md5(struct verify_header *hdr, void *p, unsigned int len)
516 {
517         struct vhdr_md5 *vh = hdr_priv(hdr);
518         struct md5_ctx md5_ctx = {
519                 .hash = (uint32_t *) vh->md5_digest,
520         };
521
522         md5_init(&md5_ctx);
523         md5_update(&md5_ctx, p, len);
524 }
525
526 /*
527  * fill body of io_u->buf with random data and add a header with the
528  * crc32 or md5 sum of that data.
529  */
530 void populate_verify_io_u(struct thread_data *td, struct io_u *io_u)
531 {
532         struct verify_header *hdr;
533         void *p = io_u->buf, *data;
534         unsigned int hdr_inc, data_len, header_num = 0;
535
536         if (td->o.verify == VERIFY_NULL)
537                 return;
538
539         fill_pattern(td, p, io_u->buflen);
540
541         hdr_inc = io_u->buflen;
542         if (td->o.verify_interval)
543                 hdr_inc = td->o.verify_interval;
544
545         for (;p < io_u->buf + io_u->buflen; p += hdr_inc) {
546                 hdr = p;
547
548                 hdr->fio_magic = FIO_HDR_MAGIC;
549                 hdr->verify_type = td->o.verify;
550                 hdr->len = hdr_inc;
551                 data_len = hdr_inc - hdr_size(hdr);
552
553                 data = p + hdr_size(hdr);
554                 switch (td->o.verify) {
555                 case VERIFY_MD5:
556                         fill_md5(hdr, data, data_len);
557                         break;
558                 case VERIFY_CRC64:
559                         fill_crc64(hdr, data, data_len);
560                         break;
561                 case VERIFY_CRC32:
562                         fill_crc32(hdr, data, data_len);
563                         break;
564                 case VERIFY_CRC16:
565                         fill_crc16(hdr, data, data_len);
566                         break;
567                 case VERIFY_CRC7:
568                         fill_crc7(hdr, data, data_len);
569                         break;
570                 case VERIFY_SHA256:
571                         fill_sha256(hdr, data, data_len);
572                         break;
573                 case VERIFY_SHA512:
574                         fill_sha512(hdr, data, data_len);
575                         break;
576                 case VERIFY_META:
577                         fill_meta(hdr, td, io_u, header_num);
578                         break;
579                 default:
580                         log_err("fio: bad verify type: %d\n", td->o.verify);
581                         assert(0);
582                 }
583                 if (td->o.verify_offset)
584                         memswp(p, p + td->o.verify_offset, hdr_size(hdr));
585                 header_num++;
586         }
587 }
588
589 int get_next_verify(struct thread_data *td, struct io_u *io_u)
590 {
591         struct io_piece *ipo = NULL;
592
593         /*
594          * this io_u is from a requeue, we already filled the offsets
595          */
596         if (io_u->file)
597                 return 0;
598
599         if (!RB_EMPTY_ROOT(&td->io_hist_tree)) {
600                 struct rb_node *n = rb_first(&td->io_hist_tree);
601
602                 ipo = rb_entry(n, struct io_piece, rb_node);
603                 rb_erase(n, &td->io_hist_tree);
604         } else if (!list_empty(&td->io_hist_list)) {
605                 ipo = list_entry(td->io_hist_list.next, struct io_piece, list);
606                 list_del(&ipo->list);
607         }
608
609         if (ipo) {
610                 io_u->offset = ipo->offset;
611                 io_u->buflen = ipo->len;
612                 io_u->file = ipo->file;
613
614                 if ((io_u->file->flags & FIO_FILE_OPEN) == 0) {
615                         int r = td_io_open_file(td, io_u->file);
616
617                         if (r)
618                                 return 1;
619                 }
620
621                 get_file(ipo->file);
622                 assert(io_u->file->flags & FIO_FILE_OPEN);
623                 io_u->ddir = DDIR_READ;
624                 io_u->xfer_buf = io_u->buf;
625                 io_u->xfer_buflen = io_u->buflen;
626                 free(ipo);
627                 return 0;
628         }
629
630         return 1;
631 }