From d7235efbc3a4b6f8c2794fc71d544066e4110eff Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 26 Apr 2018 15:27:05 -0600 Subject: [PATCH] blktrace: add 'reply_skip' option Allows the user to skip certain IO types. Useful for replaying workloads with trim on a device that doesn't support it, for instance. Or just replaying parts of a workload (eg just writes, or just reads). Signed-off-by: Jens Axboe --- blktrace.c | 14 ++++++++++++++ cconv.c | 2 ++ options.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ server.h | 2 +- thread_options.h | 2 ++ 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/blktrace.c b/blktrace.c index e256d633..3c66c5af 100644 --- a/blktrace.c +++ b/blktrace.c @@ -273,6 +273,9 @@ static void handle_trace_discard(struct thread_data *td, unsigned int bs; int fileno; + if (td->o.replay_skip & (1u << DDIR_TRIM)) + return; + ipo = calloc(1, sizeof(*ipo)); init_ipo(ipo); fileno = trace_add_file(td, t->device, &bs); @@ -312,6 +315,14 @@ static void handle_trace_fs(struct thread_data *td, struct blk_io_trace *t, rw = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0; + if (rw) { + if (td->o.replay_skip & (1u << DDIR_WRITE)) + return; + } else { + if (td->o.replay_skip & (1u << DDIR_READ)) + return; + } + assert(t->bytes); if (t->bytes > rw_bs[rw]) @@ -329,6 +340,9 @@ static void handle_trace_flush(struct thread_data *td, struct blk_io_trace *t, unsigned int bs; int fileno; + if (td->o.replay_skip & (1u << DDIR_SYNC)) + return; + ipo = calloc(1, sizeof(*ipo)); init_ipo(ipo); fileno = trace_add_file(td, t->device, &bs); diff --git a/cconv.c b/cconv.c index 9e163b35..bfd699da 100644 --- a/cconv.c +++ b/cconv.c @@ -290,6 +290,7 @@ void convert_thread_options_to_cpu(struct thread_options *o, o->replay_align = le32_to_cpu(top->replay_align); o->replay_scale = le32_to_cpu(top->replay_scale); o->replay_time_scale = le32_to_cpu(top->replay_time_scale); + o->replay_skip = le32_to_cpu(top->replay_skip); o->per_job_logs = le32_to_cpu(top->per_job_logs); o->write_bw_log = le32_to_cpu(top->write_bw_log); o->write_lat_log = le32_to_cpu(top->write_lat_log); @@ -479,6 +480,7 @@ void convert_thread_options_to_net(struct thread_options_pack *top, top->replay_align = cpu_to_le32(o->replay_align); top->replay_scale = cpu_to_le32(o->replay_scale); top->replay_time_scale = cpu_to_le32(o->replay_time_scale); + top->replay_skip = cpu_to_le32(o->replay_skip); top->per_job_logs = cpu_to_le32(o->per_job_logs); top->write_bw_log = cpu_to_le32(o->write_bw_log); top->write_lat_log = cpu_to_le32(o->write_lat_log); diff --git a/options.c b/options.c index 0b3a895d..047e493d 100644 --- a/options.c +++ b/options.c @@ -342,6 +342,43 @@ static int ignore_error_type(struct thread_data *td, enum error_type_bit etype, } +static int str_replay_skip_cb(void *data, const char *input) +{ + struct thread_data *td = cb_data_to_td(data); + char *str, *p, *n; + int ret = 0; + + if (parse_dryrun()) + return 0; + + p = str = strdup(input); + + strip_blank_front(&str); + strip_blank_end(str); + + while (p) { + n = strchr(p, ','); + if (n) + *n++ = '\0'; + if (!strcmp(p, "read")) + td->o.replay_skip |= 1u << DDIR_READ; + else if (!strcmp(p, "write")) + td->o.replay_skip |= 1u << DDIR_WRITE; + else if (!strcmp(p, "trim")) + td->o.replay_skip |= 1u << DDIR_TRIM; + else if (!strcmp(p, "sync")) + td->o.replay_skip |= 1u << DDIR_SYNC; + else { + log_err("Unknown skip type: %s\n", p); + ret = 1; + break; + } + p = n; + } + free(str); + return ret; +} + static int str_ignore_error_cb(void *data, const char *input) { struct thread_data *td = cb_data_to_td(data); @@ -3158,6 +3195,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_IOLOG, }, + { + .name = "replay_skip", + .lname = "Replay Skip", + .type = FIO_OPT_STR, + .cb = str_replay_skip_cb, + .off1 = offsetof(struct thread_options, replay_skip), + .parent = "read_iolog", + .help = "Skip certain IO types (read,write,trim,flush)", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_IOLOG, + }, { .name = "exec_prerun", .lname = "Pre-execute runnable", diff --git a/server.h b/server.h index 48968603..b48bbe16 100644 --- a/server.h +++ b/server.h @@ -48,7 +48,7 @@ struct fio_net_cmd_reply { }; enum { - FIO_SERVER_VER = 72, + FIO_SERVER_VER = 73, FIO_SERVER_MAX_FRAGMENT_PDU = 1024, FIO_SERVER_MAX_CMD_MB = 2048, diff --git a/thread_options.h b/thread_options.h index 4ec570dc..52026e36 100644 --- a/thread_options.h +++ b/thread_options.h @@ -316,6 +316,7 @@ struct thread_options { unsigned int replay_align; unsigned int replay_scale; unsigned int replay_time_scale; + unsigned int replay_skip; unsigned int per_job_logs; @@ -590,6 +591,7 @@ struct thread_options_pack { uint32_t replay_align; uint32_t replay_scale; uint32_t replay_time_scale; + uint32_t replay_skip; uint32_t per_job_logs; -- 2.25.1