Add support for redirection replay of blktrace traces to another device
authorDavid Nellans <dnellans@fusionio.com>
Tue, 31 Aug 2010 19:20:47 +0000 (21:20 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Tue, 31 Aug 2010 19:20:47 +0000 (21:20 +0200)
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
HOWTO
blktrace.c
fio.1
fio.h
options.c

diff --git a/HOWTO b/HOWTO
index 2bbaad0a5d574dfe21a80513027a603179deb7ef..452e288b0279b76f7fd82997554973b58a3b5284 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -994,6 +994,23 @@ replay_no_stall=int When replaying I/O with read_iolog the default behavior
         as possible while still respecting ordering.  The result is the same
         I/O pattern to a given device, but different timings.
 
+replay_redirect=str While replaying I/O patterns using read_iolog the
+               default behavior is to replay the IOPS onto the major/minor
+               device that each IOP was recorded from.  This is sometimes
+               undesireable because on a different machine those major/minor
+               numbers can map to a different device.  Changing hardware on
+               the same system can also result in a different major/minor
+               mapping.  Replay_redirect causes all IOPS to be replayed onto
+               the single specified device regardless of the device it was
+               recorded from. i.e. replay_redirect=/dev/sdc would cause all
+               IO in the blktrace to be replayed onto /dev/sdc.  This means
+               multiple devices will be replayed onto a single, if the trace
+               contains multiple devices.  If you want multiple devices to be
+               replayed concurrently to multiple redirected devices you must
+               blkparse your trace into separate traces and replay them with
+               independent fio invocations.  Unfortuantely this also breaks
+               the strict time ordering between multiple device accesses.
+
 write_bw_log=str If given, write a bandwidth log of the jobs in this job
                file. Can be used to store data of the bandwidth of the
                jobs in their lifetime. The included fio_generate_plots
index f22ab1b9f2bfb96ffe057884091c534c6848a12b..9ce4ae29c8cbe358c4ce0913e84d407721d13c17 100644 (file)
@@ -97,7 +97,8 @@ int is_blktrace(const char *filename)
        return 0;
 }
 
-static int lookup_device(char *path, unsigned int maj, unsigned int min)
+static int lookup_device(struct thread_data *td, char *path, unsigned int maj,
+                        unsigned int min)
 {
        struct dirent *dir;
        struct stat st;
@@ -121,7 +122,7 @@ static int lookup_device(char *path, unsigned int maj, unsigned int min)
                }
 
                if (S_ISDIR(st.st_mode)) {
-                       found = lookup_device(full_path, maj, min);
+                       found = lookup_device(td, full_path, maj, min);
                        if (found) {
                                strcpy(path, full_path);
                                break;
@@ -131,6 +132,20 @@ static int lookup_device(char *path, unsigned int maj, unsigned int min)
                if (!S_ISBLK(st.st_mode))
                        continue;
 
+               /*
+                * If replay_redirect is set then always return this device
+                * upon lookup which overrides the device lookup based on
+                * major minor in the actual blktrace
+                */
+               if (td->o.replay_redirect) {
+                       dprint(FD_BLKTRACE, "device lookup: %d/%d\n overridden"
+                                       " with: %s", maj, min,
+                                       td->o.replay_redirect);
+                       strcpy(path, td->o.replay_redirect);
+                       found = 1;
+                       break;
+               }
+
                if (maj == major(st.st_rdev) && min == minor(st.st_rdev)) {
                        dprint(FD_BLKTRACE, "device lookup: %d/%d\n", maj, min);
                        strcpy(path, full_path);
@@ -183,7 +198,7 @@ static void trace_add_file(struct thread_data *td, __u32 device)
                        return;
 
        strcpy(dev, "/dev");
-       if (lookup_device(dev, maj, min)) {
+       if (lookup_device(td, dev, maj, min)) {
                int fileno;
 
                dprint(FD_BLKTRACE, "add devices %s\n", dev);
diff --git a/fio.1 b/fio.1
index 1c0dc795c245120b6e6f3f9b681553db80753477..192e6a8cc97e00c367aeb480d708cb72a7e29bee 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -746,6 +746,12 @@ attempts to respect timing information between I/Os.  Enabling
 \fBreplay_no_stall\fR causes I/Os to be replayed as fast as possible while
 still respecting ordering.
 .TP
+.BI replay_redirect \fR=\fPstr
+While replaying I/O patterns using \fBread_iolog\fR the default behavior
+is to replay the IOPS onto the major/minor device that each IOP was recorded
+from.  Setting \fBreplay_redirect\fR causes all IOPS to be replayed onto the
+single specified device regardless of the device it was recorded from.
+.TP
 .B write_bw_log \fR=\fPstr
 If given, write a bandwidth log of the jobs in this job file. Can be used to
 store data of the bandwidth of the jobs in their lifetime. The included
diff --git a/fio.h b/fio.h
index ad47762675fe86281f479c0b11dc58f8ce35cb0a..729604d321bbf0911f6b40378d6ac3878dcb4f77 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -260,6 +260,7 @@ struct thread_options {
        char *write_iolog_file;
        char *bw_log_file;
        char *lat_log_file;
+       char *replay_redirect;
 
        /*
         * Pre-run and post-run shell
index 9718dc56cb0d42871be7c3cc1a52b4b73ff0af27..3d32c8e05fbd68504a80721b685283f13a47bd08 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1489,6 +1489,13 @@ static struct fio_option options[FIO_MAX_OPTS] = {
                .parent = "read_iolog",
                .help   = "Playback IO pattern file as fast as possible without stalls",
        },
+       {
+               .name   = "replay_redirect",
+               .type   = FIO_OPT_STR_STORE,
+               .off1   = td_var_offset(replay_redirect),
+               .parent = "read_iolog",
+               .help   = "Replay all I/O onto this device, regardless of trace device",
+       },
        {
                .name   = "exec_prerun",
                .type   = FIO_OPT_STR_STORE,