verify.c revision e29d1b70a21e29801fb35dfbc1b236b7c8514055
1e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe/* 2e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe * IO verification helpers 3e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe */ 4e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe#include <unistd.h> 5e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe#include <fcntl.h> 6e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe#include <string.h> 7e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 8e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe#include "fio.h" 9e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe#include "os.h" 10e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 11e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboestatic void fill_random_bytes(struct thread_data *td, 12e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe unsigned char *p, unsigned int len) 13e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe{ 14e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe unsigned int todo; 15e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe double r; 16e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 17e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe while (len) { 18e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe r = os_random_double(&td->verify_state); 19e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 20e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe /* 21e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe * lrand48_r seems to be broken and only fill the bottom 22e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe * 32-bits, even on 64-bit archs with 64-bit longs 23e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe */ 24e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe todo = sizeof(r); 25e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe if (todo > len) 26e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe todo = len; 27e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 28e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe memcpy(p, &r, todo); 29e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 30e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe len -= todo; 31e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe p += todo; 32e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe } 33e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe} 34e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 35e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboestatic void hexdump(void *buffer, int len) 36e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe{ 37e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe unsigned char *p = buffer; 38e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe int i; 39e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 40e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe for (i = 0; i < len; i++) 41e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe fprintf(f_out, "%02x", p[i]); 42e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe fprintf(f_out, "\n"); 43e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe} 44e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 45e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboestatic int verify_io_u_crc32(struct verify_header *hdr, struct io_u *io_u) 46e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe{ 47e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe unsigned char *p = (unsigned char *) io_u->buf; 48e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe unsigned long c; 49e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 50e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe p += sizeof(*hdr); 51e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe c = crc32(p, hdr->len - sizeof(*hdr)); 52e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 53e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe if (c != hdr->crc32) { 54e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe log_err("crc32: verify failed at %llu/%u\n", io_u->offset, io_u->buflen); 55e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe log_err("crc32: wanted %lx, got %lx\n", hdr->crc32, c); 56e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe return 1; 57e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe } 58e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 59e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe return 0; 60e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe} 61e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 62e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboestatic int verify_io_u_md5(struct verify_header *hdr, struct io_u *io_u) 63e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe{ 64e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe unsigned char *p = (unsigned char *) io_u->buf; 65e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe struct md5_ctx md5_ctx; 66e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 67e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe memset(&md5_ctx, 0, sizeof(md5_ctx)); 68e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe p += sizeof(*hdr); 69e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe md5_update(&md5_ctx, p, hdr->len - sizeof(*hdr)); 70e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 71e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe if (memcmp(hdr->md5_digest, md5_ctx.hash, sizeof(md5_ctx.hash))) { 72e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe log_err("md5: verify failed at %llu/%u\n", io_u->offset, io_u->buflen); 73e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe hexdump(hdr->md5_digest, sizeof(hdr->md5_digest)); 74e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe hexdump(md5_ctx.hash, sizeof(md5_ctx.hash)); 75e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe return 1; 76e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe } 77e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 78e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe return 0; 79e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe} 80e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 81e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboeint verify_io_u(struct io_u *io_u) 82e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe{ 83e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe struct verify_header *hdr = (struct verify_header *) io_u->buf; 84e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe int ret; 85e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 86e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe if (hdr->fio_magic != FIO_HDR_MAGIC) 87e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe return 1; 88e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 89e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe if (hdr->verify_type == VERIFY_MD5) 90e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe ret = verify_io_u_md5(hdr, io_u); 91e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe else if (hdr->verify_type == VERIFY_CRC32) 92e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe ret = verify_io_u_crc32(hdr, io_u); 93e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe else { 94e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe log_err("Bad verify type %d\n", hdr->verify_type); 95e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe ret = 1; 96e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe } 97e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 98e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe return ret; 99e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe} 100e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 101e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboestatic void fill_crc32(struct verify_header *hdr, void *p, unsigned int len) 102e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe{ 103e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe hdr->crc32 = crc32(p, len); 104e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe} 105e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 106e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboestatic void fill_md5(struct verify_header *hdr, void *p, unsigned int len) 107e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe{ 108e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe struct md5_ctx md5_ctx; 109e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 110e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe memset(&md5_ctx, 0, sizeof(md5_ctx)); 111e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe md5_update(&md5_ctx, p, len); 112e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe memcpy(hdr->md5_digest, md5_ctx.hash, sizeof(md5_ctx.hash)); 113e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe} 114e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 115e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe/* 116e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe * fill body of io_u->buf with random data and add a header with the 117e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe * crc32 or md5 sum of that data. 118e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe */ 119e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboevoid populate_verify_io_u(struct thread_data *td, struct io_u *io_u) 120e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe{ 121e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe unsigned char *p = (unsigned char *) io_u->buf; 122e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe struct verify_header hdr; 123e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 124e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe hdr.fio_magic = FIO_HDR_MAGIC; 125e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe hdr.len = io_u->buflen; 126e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe p += sizeof(hdr); 127e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe fill_random_bytes(td, p, io_u->buflen - sizeof(hdr)); 128e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 129e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe if (td->verify == VERIFY_MD5) { 130e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe fill_md5(&hdr, p, io_u->buflen - sizeof(hdr)); 131e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe hdr.verify_type = VERIFY_MD5; 132e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe } else { 133e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe fill_crc32(&hdr, p, io_u->buflen - sizeof(hdr)); 134e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe hdr.verify_type = VERIFY_CRC32; 135e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe } 136e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 137e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe memcpy(io_u->buf, &hdr, sizeof(hdr)); 138e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe} 139e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 140e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboeint get_next_verify(struct thread_data *td, struct io_u *io_u) 141e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe{ 142e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe struct io_piece *ipo; 143e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 144e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe if (!list_empty(&td->io_hist_list)) { 145e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe ipo = list_entry(td->io_hist_list.next, struct io_piece, list); 146e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 147e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe list_del(&ipo->list); 148e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 149e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe io_u->offset = ipo->offset; 150e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe io_u->buflen = ipo->len; 151e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe io_u->ddir = DDIR_READ; 152e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe free(ipo); 153e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe return 0; 154e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe } 155e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe 156e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe return 1; 157e29d1b70a21e29801fb35dfbc1b236b7c8514055Jens Axboe} 158