From: Jens Axboe Date: Wed, 18 Oct 2006 13:43:15 +0000 (+0200) Subject: [PATCH] Split out the verify io parts X-Git-Tag: fio-1.7~21 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=e29d1b70a21e29801fb35dfbc1b236b7c8514055;hp=263e529f7d90892a610a5b26a519116fe3a675a6 [PATCH] Split out the verify io parts Signed-off-by: Jens Axboe --- diff --git a/Makefile b/Makefile index 80a03975..b9a72811 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ CFLAGS += '-D_INST_PREFIX="$(FIO_INST_DIR)"' all: depend $(PROGS) $(SCRIPTS) $(MAKE) -C engines -fio: fio.o ioengines.o init.o stat.o log.o time.o md5.o crc32.o filesetup.o eta.o +fio: fio.o ioengines.o init.o stat.o log.o time.o md5.o crc32.o filesetup.o eta.o verify.o $(CC) $(CFLAGS) -o $@ $(filter %.o,$^) -lpthread -laio -lm -lrt -ldl clean: diff --git a/fio.c b/fio.c index a146f035..cf85765e 100644 --- a/fio.c +++ b/fio.c @@ -259,110 +259,6 @@ static inline int runtime_exceeded(struct thread_data *td, struct timeval *t) return 0; } -static void fill_random_bytes(struct thread_data *td, - unsigned char *p, unsigned int len) -{ - unsigned int todo; - double r; - - while (len) { - r = os_random_double(&td->verify_state); - - /* - * lrand48_r seems to be broken and only fill the bottom - * 32-bits, even on 64-bit archs with 64-bit longs - */ - todo = sizeof(r); - if (todo > len) - todo = len; - - memcpy(p, &r, todo); - - len -= todo; - p += todo; - } -} - -static void hexdump(void *buffer, int len) -{ - unsigned char *p = buffer; - int i; - - for (i = 0; i < len; i++) - fprintf(f_out, "%02x", p[i]); - fprintf(f_out, "\n"); -} - -static int verify_io_u_crc32(struct verify_header *hdr, struct io_u *io_u) -{ - unsigned char *p = (unsigned char *) io_u->buf; - unsigned long c; - - p += sizeof(*hdr); - c = crc32(p, hdr->len - sizeof(*hdr)); - - if (c != hdr->crc32) { - log_err("crc32: verify failed at %llu/%u\n", io_u->offset, io_u->buflen); - log_err("crc32: wanted %lx, got %lx\n", hdr->crc32, c); - return 1; - } - - return 0; -} - -static int verify_io_u_md5(struct verify_header *hdr, struct io_u *io_u) -{ - unsigned char *p = (unsigned char *) io_u->buf; - struct md5_ctx md5_ctx; - - memset(&md5_ctx, 0, sizeof(md5_ctx)); - p += sizeof(*hdr); - md5_update(&md5_ctx, p, hdr->len - sizeof(*hdr)); - - if (memcmp(hdr->md5_digest, md5_ctx.hash, sizeof(md5_ctx.hash))) { - log_err("md5: verify failed at %llu/%u\n", io_u->offset, io_u->buflen); - hexdump(hdr->md5_digest, sizeof(hdr->md5_digest)); - hexdump(md5_ctx.hash, sizeof(md5_ctx.hash)); - return 1; - } - - return 0; -} - -static int verify_io_u(struct io_u *io_u) -{ - struct verify_header *hdr = (struct verify_header *) io_u->buf; - int ret; - - if (hdr->fio_magic != FIO_HDR_MAGIC) - return 1; - - if (hdr->verify_type == VERIFY_MD5) - ret = verify_io_u_md5(hdr, io_u); - else if (hdr->verify_type == VERIFY_CRC32) - ret = verify_io_u_crc32(hdr, io_u); - else { - log_err("Bad verify type %d\n", hdr->verify_type); - ret = 1; - } - - return ret; -} - -static void fill_crc32(struct verify_header *hdr, void *p, unsigned int len) -{ - hdr->crc32 = crc32(p, len); -} - -static void fill_md5(struct verify_header *hdr, void *p, unsigned int len) -{ - struct md5_ctx md5_ctx; - - memset(&md5_ctx, 0, sizeof(md5_ctx)); - md5_update(&md5_ctx, p, len); - memcpy(hdr->md5_digest, md5_ctx.hash, sizeof(md5_ctx.hash)); -} - /* * Return the data direction for the next io_u. If the job is a * mixed read/write workload, check the rwmix cycle and switch if @@ -399,31 +295,6 @@ static int get_rw_ddir(struct thread_data *td) return DDIR_WRITE; } -/* - * fill body of io_u->buf with random data and add a header with the - * crc32 or md5 sum of that data. - */ -static void populate_io_u(struct thread_data *td, struct io_u *io_u) -{ - unsigned char *p = (unsigned char *) io_u->buf; - struct verify_header hdr; - - hdr.fio_magic = FIO_HDR_MAGIC; - hdr.len = io_u->buflen; - p += sizeof(hdr); - fill_random_bytes(td, p, io_u->buflen - sizeof(hdr)); - - if (td->verify == VERIFY_MD5) { - fill_md5(&hdr, p, io_u->buflen - sizeof(hdr)); - hdr.verify_type = VERIFY_MD5; - } else { - fill_crc32(&hdr, p, io_u->buflen - sizeof(hdr)); - hdr.verify_type = VERIFY_CRC32; - } - - memcpy(io_u->buf, &hdr, sizeof(hdr)); -} - static int td_io_prep(struct thread_data *td, struct io_u *io_u) { if (td->io_ops->prep && td->io_ops->prep(td, io_u)) @@ -533,7 +404,7 @@ static struct io_u *get_io_u(struct thread_data *td, struct fio_file *f) f->last_pos += io_u->buflen; if (td->verify != VERIFY_NONE) - populate_io_u(td, io_u); + populate_verify_io_u(td, io_u); if (td_io_prep(td, io_u)) { put_io_u(td, io_u); @@ -549,25 +420,6 @@ static inline void td_set_runstate(struct thread_data *td, int runstate) td->runstate = runstate; } -static int get_next_verify(struct thread_data *td, struct io_u *io_u) -{ - struct io_piece *ipo; - - if (!list_empty(&td->io_hist_list)) { - ipo = list_entry(td->io_hist_list.next, struct io_piece, list); - - list_del(&ipo->list); - - io_u->offset = ipo->offset; - io_u->buflen = ipo->len; - io_u->ddir = DDIR_READ; - free(ipo); - return 0; - } - - return 1; -} - static struct fio_file *get_next_file(struct thread_data *td) { int old_next_file = td->next_file; diff --git a/fio.h b/fio.h index 9471666b..9a8184b9 100644 --- a/fio.h +++ b/fio.h @@ -472,6 +472,13 @@ enum { TD_REAPED, }; +/* + * Verify helpers + */ +extern void populate_verify_io_u(struct thread_data *, struct io_u *); +extern int get_next_verify(struct thread_data *td, struct io_u *); +extern int verify_io_u(struct io_u *); + /* * This is a pretty crappy semaphore implementation, but with the use that fio * has (just signalling start/go conditions), it doesn't have to be better. diff --git a/verify.c b/verify.c new file mode 100644 index 00000000..12eb7c98 --- /dev/null +++ b/verify.c @@ -0,0 +1,157 @@ +/* + * IO verification helpers + */ +#include +#include +#include + +#include "fio.h" +#include "os.h" + +static void fill_random_bytes(struct thread_data *td, + unsigned char *p, unsigned int len) +{ + unsigned int todo; + double r; + + while (len) { + r = os_random_double(&td->verify_state); + + /* + * lrand48_r seems to be broken and only fill the bottom + * 32-bits, even on 64-bit archs with 64-bit longs + */ + todo = sizeof(r); + if (todo > len) + todo = len; + + memcpy(p, &r, todo); + + len -= todo; + p += todo; + } +} + +static void hexdump(void *buffer, int len) +{ + unsigned char *p = buffer; + int i; + + for (i = 0; i < len; i++) + fprintf(f_out, "%02x", p[i]); + fprintf(f_out, "\n"); +} + +static int verify_io_u_crc32(struct verify_header *hdr, struct io_u *io_u) +{ + unsigned char *p = (unsigned char *) io_u->buf; + unsigned long c; + + p += sizeof(*hdr); + c = crc32(p, hdr->len - sizeof(*hdr)); + + if (c != hdr->crc32) { + log_err("crc32: verify failed at %llu/%u\n", io_u->offset, io_u->buflen); + log_err("crc32: wanted %lx, got %lx\n", hdr->crc32, c); + return 1; + } + + return 0; +} + +static int verify_io_u_md5(struct verify_header *hdr, struct io_u *io_u) +{ + unsigned char *p = (unsigned char *) io_u->buf; + struct md5_ctx md5_ctx; + + memset(&md5_ctx, 0, sizeof(md5_ctx)); + p += sizeof(*hdr); + md5_update(&md5_ctx, p, hdr->len - sizeof(*hdr)); + + if (memcmp(hdr->md5_digest, md5_ctx.hash, sizeof(md5_ctx.hash))) { + log_err("md5: verify failed at %llu/%u\n", io_u->offset, io_u->buflen); + hexdump(hdr->md5_digest, sizeof(hdr->md5_digest)); + hexdump(md5_ctx.hash, sizeof(md5_ctx.hash)); + return 1; + } + + return 0; +} + +int verify_io_u(struct io_u *io_u) +{ + struct verify_header *hdr = (struct verify_header *) io_u->buf; + int ret; + + if (hdr->fio_magic != FIO_HDR_MAGIC) + return 1; + + if (hdr->verify_type == VERIFY_MD5) + ret = verify_io_u_md5(hdr, io_u); + else if (hdr->verify_type == VERIFY_CRC32) + ret = verify_io_u_crc32(hdr, io_u); + else { + log_err("Bad verify type %d\n", hdr->verify_type); + ret = 1; + } + + return ret; +} + +static void fill_crc32(struct verify_header *hdr, void *p, unsigned int len) +{ + hdr->crc32 = crc32(p, len); +} + +static void fill_md5(struct verify_header *hdr, void *p, unsigned int len) +{ + struct md5_ctx md5_ctx; + + memset(&md5_ctx, 0, sizeof(md5_ctx)); + md5_update(&md5_ctx, p, len); + memcpy(hdr->md5_digest, md5_ctx.hash, sizeof(md5_ctx.hash)); +} + +/* + * fill body of io_u->buf with random data and add a header with the + * crc32 or md5 sum of that data. + */ +void populate_verify_io_u(struct thread_data *td, struct io_u *io_u) +{ + unsigned char *p = (unsigned char *) io_u->buf; + struct verify_header hdr; + + hdr.fio_magic = FIO_HDR_MAGIC; + hdr.len = io_u->buflen; + p += sizeof(hdr); + fill_random_bytes(td, p, io_u->buflen - sizeof(hdr)); + + if (td->verify == VERIFY_MD5) { + fill_md5(&hdr, p, io_u->buflen - sizeof(hdr)); + hdr.verify_type = VERIFY_MD5; + } else { + fill_crc32(&hdr, p, io_u->buflen - sizeof(hdr)); + hdr.verify_type = VERIFY_CRC32; + } + + memcpy(io_u->buf, &hdr, sizeof(hdr)); +} + +int get_next_verify(struct thread_data *td, struct io_u *io_u) +{ + struct io_piece *ipo; + + if (!list_empty(&td->io_hist_list)) { + ipo = list_entry(td->io_hist_list.next, struct io_piece, list); + + list_del(&ipo->list); + + io_u->offset = ipo->offset; + io_u->buflen = ipo->len; + io_u->ddir = DDIR_READ; + free(ipo); + return 0; + } + + return 1; +}