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