summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2012-02-22 20:11:57 +0100
committerJens Axboe <axboe@kernel.dk>2012-02-22 20:11:57 +0100
commitf65d1c2663ac6007eac1a2063fe25b4275d013e4 (patch)
tree87c254b56c1c0c45cbc3c4381cb3a32e67910064
parent8e8b225d177c8e824785a87a1116309049a27a7c (diff)
downloadfio-f65d1c2663ac6007eac1a2063fe25b4275d013e4.tar.gz
fio-f65d1c2663ac6007eac1a2063fe25b4275d013e4.tar.bz2
Add checksum to verify_header
Currently we don't know if the verify_header itself is valid when pulled off a disk. While it will fail verify if it is, fio might then confuse the 'expected' and 'received' data since it re-generates the corrupted crc with the seed stored. But if the seed is corrupt, then we fail. So checksum the verify header, so that we know for a fact whether the header is valid or not. Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--verify.c32
-rw-r--r--verify.h12
2 files changed, 37 insertions, 7 deletions
diff --git a/verify.c b/verify.c
index eb8eddc7..8bf14ae0 100644
--- a/verify.c
+++ b/verify.c
@@ -649,6 +649,19 @@ static int verify_trimmed_io_u(struct thread_data *td, struct io_u *io_u)
return ret;
}
+static int verify_hdr_crc(struct verify_header *hdr)
+{
+ void *p = hdr;
+ uint32_t crc;
+
+ crc = crc32(p, sizeof(*hdr) - sizeof(hdr->crc32));
+ if (crc == hdr->crc32)
+ return 1;
+
+ log_err("fio: verify header crc %x, calculated %x\n", hdr->crc32, crc);
+ return 0;
+}
+
int verify_io_u(struct thread_data *td, struct io_u *io_u)
{
struct verify_header *hdr;
@@ -682,9 +695,18 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u)
memswp(p, p + td->o.verify_offset, header_size);
hdr = p;
- if (hdr->fio_magic != FIO_HDR_MAGIC) {
+ if (hdr->fio_magic == FIO_HDR_MAGIC2) {
+ if (!verify_hdr_crc(hdr)) {
+ log_err("fio: bad crc on verify header.\n");
+ return EILSEQ;
+ }
+ } else if (hdr->fio_magic == FIO_HDR_MAGIC) {
+ log_err("fio: v1 headers no longer supported.\n");
+ log_err("fio: re-run the write workload.\n");
+ return EILSEQ;
+ } else {
log_err("verify: bad magic header %x, wanted %x at file %s offset %llu, length %u\n",
- hdr->fio_magic, FIO_HDR_MAGIC,
+ hdr->fio_magic, FIO_HDR_MAGIC2,
io_u->file->file_name,
io_u->offset + hdr_num * hdr->len, hdr->len);
return EILSEQ;
@@ -844,10 +866,14 @@ static void populate_hdr(struct thread_data *td, struct io_u *io_u,
p = (void *) hdr;
- hdr->fio_magic = FIO_HDR_MAGIC;
+ hdr->fio_magic = FIO_HDR_MAGIC2;
hdr->len = header_len;
hdr->verify_type = td->o.verify;
+ hdr->pad1 = 0;
hdr->rand_seed = io_u->rand_seed;
+ hdr->pad2 = 0;
+ hdr->crc32 = crc32(p, sizeof(*hdr) - sizeof(hdr->crc32));
+
data_len = header_len - hdr_size(hdr);
data = p + hdr_size(hdr);
diff --git a/verify.h b/verify.h
index 49ce417c..ec7365c6 100644
--- a/verify.h
+++ b/verify.h
@@ -4,6 +4,7 @@
#include <stdint.h>
#define FIO_HDR_MAGIC 0xf00baaef
+#define FIO_HDR_MAGIC2 0xf00dbeef
enum {
VERIFY_NONE = 0, /* no verification */
@@ -28,10 +29,13 @@ enum {
* data.
*/
struct verify_header {
- unsigned int fio_magic;
- unsigned int len;
- unsigned int verify_type;
- unsigned long rand_seed;
+ uint32_t fio_magic;
+ uint32_t len;
+ uint32_t verify_type;
+ uint32_t pad1;
+ uint64_t rand_seed;
+ uint32_t pad2;
+ uint32_t crc32;
};
struct vhdr_md5 {