Merge branch 'client-hostfile' of git://github.com/bengland2/fio
authorJens Axboe <axboe@fb.com>
Thu, 7 May 2015 19:46:24 +0000 (13:46 -0600)
committerJens Axboe <axboe@fb.com>
Thu, 7 May 2015 19:46:24 +0000 (13:46 -0600)
22 files changed:
HOWTO
blktrace.c
cconv.c
engines/libaio.c
engines/posixaio.c
eta.c
filesetup.c
fio.1
fio.h
gclient.c
io_u.c
lib/pow2.h [new file with mode: 0644]
options.c
options.h
os/windows/posix.c
os/windows/posix/include/sys/ioctl.h [new file with mode: 0644]
parse.c
parse.h
server.c
server.h
stat.c
thread_options.h

diff --git a/HOWTO b/HOWTO
index bb29826428574a77f0352e279155c4b6adb2cea0..0808cc3a07e0f53a62c3476b6789f47426917829 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -1433,6 +1433,12 @@ replay_redirect=str While replaying I/O patterns using read_iolog the
                independent fio invocations.  Unfortuantely this also breaks
                the strict time ordering between multiple device accesses.
 
+replay_align=int       Force alignment of IO offsets and lengths in a trace
+               to this power of 2 value.
+
+replay_scale=int       Scale sector offsets down by this factor when
+               replaying traces.
+
 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 2d4dc1b9fbca3724e47c7285e7fcdab277b82bc3..562e126b428389af6db707b5fffde18cc922efb9 100644 (file)
@@ -208,6 +208,23 @@ out:
        return last_fileno;
 }
 
+static void t_bytes_align(struct thread_options *o, struct blk_io_trace *t)
+{
+       if (!o->replay_align)
+               return;
+
+       t->bytes = (t->bytes + o->replay_align - 1) & ~(o->replay_align - 1);
+}
+
+static void ipo_bytes_align(struct thread_options *o, struct io_piece *ipo)
+{
+       if (!o->replay_align)
+               return;
+
+       ipo->offset &= ~(o->replay_align - 1);
+}
+
+
 /*
  * Store blk_io_trace data in an ipo for later retrieval.
  */
@@ -220,6 +237,9 @@ static void store_ipo(struct thread_data *td, unsigned long long offset,
        init_ipo(ipo);
 
        ipo->offset = offset * bs;
+       if (td->o.replay_scale)
+               ipo->offset = ipo->offset / td->o.replay_scale;
+       ipo_bytes_align(&td->o, ipo);
        ipo->len = bytes;
        ipo->delay = ttime / 1000;
        if (rw)
@@ -275,6 +295,9 @@ static void handle_trace_discard(struct thread_data *td,
        INIT_FLIST_HEAD(&ipo->list);
 
        ipo->offset = t->sector * bs;
+       if (td->o.replay_scale)
+               ipo->offset = ipo->offset / td->o.replay_scale;
+       ipo_bytes_align(&td->o, ipo);
        ipo->len = t->bytes;
        ipo->delay = ttime / 1000;
        ipo->ddir = DDIR_TRIM;
@@ -314,7 +337,7 @@ static void handle_trace(struct thread_data *td, struct blk_io_trace *t,
                         unsigned long *ios, unsigned int *bs)
 {
        static unsigned long long last_ttime;
-       unsigned long long delay;
+       unsigned long long delay = 0;
 
        if ((t->action & 0xffff) != __BLK_TA_QUEUE)
                return;
@@ -329,6 +352,8 @@ static void handle_trace(struct thread_data *td, struct blk_io_trace *t,
                }
        }
 
+       t_bytes_align(&td->o, t);
+
        if (t->action & BLK_TC_ACT(BLK_TC_NOTIFY))
                handle_trace_notify(t);
        else if (t->action & BLK_TC_ACT(BLK_TC_DISCARD))
diff --git a/cconv.c b/cconv.c
index 976059cde61ab1c298f6ca41949b054c686c2d5f..1e095afdc7ccc8960adba0ce311054b0c7f4e407 100644 (file)
--- a/cconv.c
+++ b/cconv.c
@@ -244,6 +244,10 @@ void convert_thread_options_to_cpu(struct thread_options *o,
        o->compress_percentage = le32_to_cpu(top->compress_percentage);
        o->compress_chunk = le32_to_cpu(top->compress_chunk);
        o->dedupe_percentage = le32_to_cpu(top->dedupe_percentage);
+       o->skip_bad = le32_to_cpu(top->skip_bad);
+       o->block_error_hist = le32_to_cpu(top->block_error_hist);
+       o->replay_align = le32_to_cpu(top->replay_align);
+       o->replay_scale = le32_to_cpu(top->replay_scale);
 
        o->trim_backlog = le64_to_cpu(top->trim_backlog);
 
@@ -407,6 +411,10 @@ void convert_thread_options_to_net(struct thread_options_pack *top,
        top->compress_percentage = cpu_to_le32(o->compress_percentage);
        top->compress_chunk = cpu_to_le32(o->compress_chunk);
        top->dedupe_percentage = cpu_to_le32(o->dedupe_percentage);
+       top->block_error_hist = cpu_to_le32(o->block_error_hist);
+       top->skip_bad = cpu_to_le32(o->skip_bad);
+       top->replay_align = cpu_to_le32(o->replay_align);
+       top->replay_scale = cpu_to_le32(o->replay_scale);
 
        for (i = 0; i < DDIR_RWDIR_CNT; i++) {
                top->bs[i] = cpu_to_le32(o->bs[i]);
index 8ba21f8959b318939786aaa21b96e21f7485d8c5..9685c99d84ec9d1705f4f8515ec3906dd4a1c2e3 100644 (file)
@@ -12,6 +12,7 @@
 #include <libaio.h>
 
 #include "../fio.h"
+#include "../lib/pow2.h"
 
 static int fio_libaio_commit(struct thread_data *td);
 
index 8ab88fbb1faf2821c442015f85f78e24cb1d244d..29bcc5acc809f63fc7c46972564a5e696543ef78 100644 (file)
@@ -198,7 +198,7 @@ static int fio_posixaio_queue(struct thread_data *td,
        }
 
        if (ret) {
-               int aio_err = aio_error(aiocb);
+               int aio_err = errno;
 
                /*
                 * At least OSX has a very low limit on the number of pending
diff --git a/eta.c b/eta.c
index 167bf5f62b215d470e1f41d1ee95ba75968589cd..e458457a902f4df3fc3e6642c402abf6148c7016 100644 (file)
--- a/eta.c
+++ b/eta.c
@@ -6,6 +6,7 @@
 #include <string.h>
 
 #include "fio.h"
+#include "lib/pow2.h"
 
 static char __run_str[REAL_MAX_JOBS + 1];
 static char run_str[__THREAD_RUNSTR_SZ(REAL_MAX_JOBS)];
index 10fc4150804b8fadce1a4af7cb856828796ca1f8..aee7ece9da3a8829fedc0884dfff3f0bb00ca182 100644 (file)
@@ -1262,7 +1262,7 @@ int add_file(struct thread_data *td, const char *fname, int numjob, int inc)
        dprint(FD_FILE, "add file %s\n", fname);
 
        if (td->o.directory)
-               len = set_name_idx(file_name, td->o.directory, numjob);
+               len = set_name_idx(file_name, PATH_MAX, td->o.directory, numjob);
 
        sprintf(file_name + len, "%s", fname);
 
diff --git a/fio.1 b/fio.1
index 78f060590c6005187c4bea528f745a0b7b04e28a..e5451b1696f7a6b16754bf576a3531a8f81fd321 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -1265,6 +1265,12 @@ 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
+.BI replay_align \fR=\fPint
+Force alignment of IO offsets and lengths in a trace to this power of 2 value.
+.TP
+.BI replay_scale \fR=\fPint
+Scale sector offsets down by this factor when replaying traces.
+.TP
 .BI 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 a4637bb9101ca5cdaaf905687006a714804c29f9..0d5a0efb5882cbcef8fd11739667686ea6363a8c 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -631,11 +631,6 @@ static inline unsigned int td_min_bs(struct thread_data *td)
        return min(td->o.min_bs[DDIR_TRIM], min_bs);
 }
 
-static inline int is_power_of_2(uint64_t val)
-{
-       return (val != 0 && ((val & (val - 1)) == 0));
-}
-
 static inline int td_async_processing(struct thread_data *td)
 {
        return (td->flags & TD_F_NEED_LOCK) != 0;
index 42bc7614c5dba730f9a5c8dc0a997c765e63f9f0..d7d9616e4ef00d297055032fa6e600c3f28247d2 100644 (file)
--- a/gclient.c
+++ b/gclient.c
@@ -13,6 +13,7 @@
 #include "graph.h"
 #include "gclient.h"
 #include "printing.h"
+#include "lib/pow2.h"
 
 static void gfio_display_ts(struct fio_client *client, struct thread_stat *ts,
                            struct group_run_stats *rs);
diff --git a/io_u.c b/io_u.c
index d00e6e3fe44a593033670cd5f226fa07395a5698..e67149d8cd2463e3bb8b06d18a70be9476b7b6d5 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -12,6 +12,7 @@
 #include "lib/rand.h"
 #include "lib/axmap.h"
 #include "err.h"
+#include "lib/pow2.h"
 
 struct io_completion_data {
        int nr;                         /* input */
diff --git a/lib/pow2.h b/lib/pow2.h
new file mode 100644 (file)
index 0000000..f3ca4d7
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef FIO_POW2_H
+#define FIO_POW2_H
+
+#include <inttypes.h>
+
+static inline int is_power_of_2(uint64_t val)
+{
+       return (val != 0 && ((val & (val - 1)) == 0));
+}
+
+#endif
index 3de1248cce9ef44da252ec41b4578a09b6e39da8..cb8182de93c259a8ef2f3bc9141aa9795b2bbda4 100644 (file)
--- a/options.c
+++ b/options.c
@@ -8,6 +8,7 @@
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <netinet/in.h>
 
 #include "fio.h"
 #include "verify.h"
@@ -17,6 +18,8 @@
 
 #include "crc/crc32c.h"
 
+char client_sockaddr_str[INET6_ADDRSTRLEN] = { 0 };
+
 /*
  * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
  */
@@ -820,7 +823,7 @@ static int get_max_name_idx(char *input)
  * Returns the directory at the index, indexes > entires will be
  * assigned via modulo division of the index
  */
-int set_name_idx(char *target, char *input, int index)
+int set_name_idx(char *target, size_t tlen, char *input, int index)
 {
        unsigned int cur_idx;
        int len;
@@ -832,7 +835,13 @@ int set_name_idx(char *target, char *input, int index)
        for (cur_idx = 0; cur_idx <= index; cur_idx++)
                fname = get_next_name(&str);
 
-       len = sprintf(target, "%s/", fname);
+       if (client_sockaddr_str[0]) {
+               len = snprintf(target, tlen, "%s/%s.", fname,
+                               client_sockaddr_str);
+       } else
+               len = snprintf(target, tlen, "%s/", fname);
+
+       target[tlen - 1] = '\0';
        free(p);
 
        return len;
@@ -2661,6 +2670,28 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_IOLOG,
        },
+       {
+               .name   = "replay_scale",
+               .lname  = "Replace offset scale factor",
+               .type   = FIO_OPT_INT,
+               .off1   = td_var_offset(replay_scale),
+               .parent = "read_iolog",
+               .def    = "1",
+               .help   = "Align offsets to this blocksize",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IOLOG,
+       },
+       {
+               .name   = "replay_align",
+               .lname  = "Replace alignment",
+               .type   = FIO_OPT_INT,
+               .off1   = td_var_offset(replay_align),
+               .parent = "read_iolog",
+               .help   = "Scale offset down by this factor",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IOLOG,
+               .pow2   = 1,
+       },
        {
                .name   = "exec_prerun",
                .lname  = "Pre-execute runnable",
index 2cf435a06e2868ab8ba84bee60bd9a53116bf7a7..6805b314125a96778e44e8d222720b1346ff651b 100644 (file)
--- a/options.h
+++ b/options.h
@@ -18,7 +18,9 @@ void del_opt_posval(const char *, const char *);
 struct thread_data;
 void fio_options_free(struct thread_data *);
 char *get_name_idx(char *, int);
-int set_name_idx(char *, char *, int);
+int set_name_idx(char *, size_t, char *, int);
+
+extern char client_sockaddr_str[];  /* used with --client option */
 
 extern struct fio_option fio_options[FIO_MAX_OPTS];
 
index d238c64a16219607ced8eb7dd4807552361046e6..41fc480df9f14f92a75ff07a5fda30fa098deb06 100755 (executable)
@@ -229,6 +229,30 @@ char *dlerror(void)
        return dl_error;
 }
 
+/* Copied from http://blogs.msdn.com/b/joshpoley/archive/2007/12/19/date-time-formats-and-conversions.aspx */
+void Time_tToSystemTime(time_t dosTime, SYSTEMTIME *systemTime)
+{
+    LARGE_INTEGER jan1970FT;
+    LARGE_INTEGER utcFT;
+    jan1970FT.QuadPart = 116444736000000000LL; // january 1st 1970
+    utcFT.QuadPart = ((unsigned __int64)dosTime) * 10000000 + jan1970FT.QuadPart;
+
+    FileTimeToSystemTime((FILETIME*)&utcFT, systemTime);
+}
+
+char* ctime_r(const time_t *t, char *buf)
+{
+    SYSTEMTIME systime;
+    const char * const dayOfWeek[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+    const char * const monthOfYear[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+    Time_tToSystemTime(*t, &systime);
+    /* We don't know how long `buf` is, but assume it's rounded up from the minimum of 25 to 32 */
+    StringCchPrintfA(buf, 32, "%s %s %d %02d:%02d:%02d %04d", dayOfWeek[systime.wDayOfWeek - 1], monthOfYear[systime.wMonth - 1],
+                                                                                systime.wDay, systime.wHour, systime.wMinute, systime.wSecond, systime.wYear);
+    return buf;
+}
+
 int gettimeofday(struct timeval *restrict tp, void *restrict tzp)
 {
        FILETIME fileTime;
diff --git a/os/windows/posix/include/sys/ioctl.h b/os/windows/posix/include/sys/ioctl.h
new file mode 100644 (file)
index 0000000..a42247d
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef IOCTL_H
+#define IOCTL_H
+
+/* This file is empty since it only needs to exist on Windows
+   but isn't otherwise used */
+
+#endif /* IOCTL_H */
\ No newline at end of file
diff --git a/parse.c b/parse.c
index 7912212ecda47594bac999e8abbecdacaf81aeb1..745056bdc8186e54743d2fb688df926084c91853 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -17,6 +17,7 @@
 #include "options.h"
 #include "minmax.h"
 #include "lib/ieee754.h"
+#include "lib/pow2.h"
 
 #ifdef CONFIG_ARITHMETIC
 #include "y.tab.h"
@@ -521,6 +522,10 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 
                if (ret)
                        break;
+               if (o->pow2 && !is_power_of_2(ull)) {
+                       log_err("%s: must be a power-of-2\n", o->name);
+                       return 1;
+               }
 
                if (o->maxval && ull > o->maxval) {
                        log_err("max value out of range: %llu"
diff --git a/parse.h b/parse.h
index 15f2e06e62926a9b2353ad14353827577318be72..264243b22904f68a6181a99dd85ece446a997251 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -75,6 +75,7 @@ struct fio_option {
        int is_seconds;                 /* time value with seconds base */
        int is_time;                    /* time based value */
        int no_warn_def;
+       int pow2;                       /* must be a power-of-2 */
 };
 
 typedef int (str_cb_fn)(void *, char *);
index 93c0987febaf486c3d08f92f3797782300b2acff..7a9b0a447d306b0e1be0928d2635c4e19a14b96a 100644 (file)
--- a/server.c
+++ b/server.c
@@ -1007,6 +1007,7 @@ static int accept_loop(int listen_sk)
                }
 
                /* exits */
+               strncpy(client_sockaddr_str, from, INET6_ADDRSTRLEN);
                handle_connection(sk);
        }
 
index da12ae0d10cb8fdee00933d279c8e3720db66214..b0cea150233e98e8f0838c24510b74e35db459a5 100644 (file)
--- a/server.h
+++ b/server.h
@@ -38,7 +38,7 @@ struct fio_net_cmd_reply {
 };
 
 enum {
-       FIO_SERVER_VER                  = 43,
+       FIO_SERVER_VER                  = 44,
 
        FIO_SERVER_MAX_FRAGMENT_PDU     = 1024,
        FIO_SERVER_MAX_CMD_MB           = 2048,
diff --git a/stat.c b/stat.c
index d143d36c0c60ed1d5d6c1bca6b1aa27bd86c9212..9a30bea4d01cf57a710ed8277b23ec336ea3c0d8 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -13,6 +13,7 @@
 #include "json.h"
 #include "lib/getrusage.h"
 #include "idletime.h"
+#include "lib/pow2.h"
 
 struct fio_mutex *stat_mutex;
 
index aa7f3f2657c8c985e94ec1449e01a34b5fed1ce5..1c48bd83d394577b463ecb9ec5b4572b05123747 100644 (file)
@@ -265,6 +265,9 @@ struct thread_options {
 
        unsigned block_error_hist;
        unsigned int skip_bad;
+
+       unsigned int replay_align;
+       unsigned int replay_scale;
 };
 
 #define FIO_TOP_STR_MAX                256
@@ -495,6 +498,9 @@ struct thread_options_pack {
 
        uint32_t block_error_hist;
        uint32_t skip_bad;
+
+       uint32_t replay_align;
+       uint32_t replay_scale;
 } __attribute__((packed));
 
 extern void convert_thread_options_to_cpu(struct thread_options *o, struct thread_options_pack *top);