Add checksum to verify_header
authorJens Axboe <axboe@kernel.dk>
Wed, 22 Feb 2012 19:11:57 +0000 (20:11 +0100)
committerJens Axboe <axboe@kernel.dk>
Wed, 22 Feb 2012 19:11:57 +0000 (20:11 +0100)
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>
verify.c
verify.h

index eb8eddc78906f4b0dcaa13a9899495e5a8670dca..8bf14ae05fb08ecb4b960051c8444635219d933c 100644 (file)
--- 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);
index 49ce417cff8c200bbc252b266867db857781d471..ec7365c63bed7e167a86f2ec2c5015107864489f 100644 (file)
--- 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 {