options: check for conflict between trims and readonly option
[fio.git] / options.c
index 17d7245f5490cc762153ea48d3960605cc0d5909..a174e2cd165316494211a256428c758632da7d86 100644 (file)
--- a/options.c
+++ b/options.c
@@ -57,8 +57,7 @@ struct split {
 };
 
 static int split_parse_ddir(struct thread_options *o, struct split *split,
-                           enum fio_ddir ddir, char *str, bool absolute,
-                           unsigned int max_splits)
+                           char *str, bool absolute, unsigned int max_splits)
 {
        unsigned long long perc;
        unsigned int i;
@@ -125,7 +124,7 @@ static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str,
 
        memset(&split, 0, sizeof(split));
 
-       if (split_parse_ddir(o, &split, ddir, str, data, BSSPLIT_MAX))
+       if (split_parse_ddir(o, &split, str, data, BSSPLIT_MAX))
                return 1;
        if (!split.nr)
                return 0;
@@ -342,6 +341,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);
@@ -845,7 +881,7 @@ static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir,
 
        memset(&split, 0, sizeof(split));
 
-       if (split_parse_ddir(o, &split, ddir, str, absolute, ZONESPLIT_MAX))
+       if (split_parse_ddir(o, &split, str, absolute, ZONESPLIT_MAX))
                return 1;
        if (!split.nr)
                return 0;
@@ -1010,8 +1046,6 @@ static int parse_zoned_distribution(struct thread_data *td, const char *input,
        }
 
        if (parse_dryrun()) {
-               int i;
-
                for (i = 0; i < DDIR_RWDIR_CNT; i++) {
                        free(td->o.zone_split[i]);
                        td->o.zone_split[i] = NULL;
@@ -1521,9 +1555,9 @@ static int rw_verify(const struct fio_option *o, void *data)
 {
        struct thread_data *td = cb_data_to_td(data);
 
-       if (read_only && td_write(td)) {
-               log_err("fio: job <%s> has write bit set, but fio is in"
-                       " read-only mode\n", td->o.name);
+       if (read_only && (td_write(td) || td_trim(td))) {
+               log_err("fio: job <%s> has write or trim bit set, but"
+                       " fio is in read-only mode\n", td->o.name);
                return 1;
        }
 
@@ -1816,11 +1850,6 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                            .help = "GUASI IO engine",
                          },
 #endif
-#ifdef FIO_HAVE_BINJECT
-                         { .ival = "binject",
-                           .help = "binject direct inject block engine",
-                         },
-#endif
 #ifdef CONFIG_RDMA
                          { .ival = "rdma",
                            .help = "RDMA IO engine",
@@ -1856,7 +1885,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
 #endif
 #ifdef CONFIG_PMEMBLK
                          { .ival = "pmemblk",
-                           .help = "NVML libpmemblk based IO engine",
+                           .help = "PMDK libpmemblk based IO engine",
                          },
 
 #endif
@@ -1875,7 +1904,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                          },
 #ifdef CONFIG_LIBPMEM
                          { .ival = "libpmem",
-                           .help = "NVML libpmem based IO engine",
+                           .help = "PMDK libpmem based IO engine",
                          },
 #endif
                },
@@ -2851,25 +2880,14 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        {
                .name   = "verifysort",
                .lname  = "Verify sort",
-               .type   = FIO_OPT_BOOL,
-               .off1   = offsetof(struct thread_options, verifysort),
-               .help   = "Sort written verify blocks for read back",
-               .def    = "1",
-               .parent = "verify",
-               .hide   = 1,
+               .type   = FIO_OPT_SOFT_DEPRECATED,
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_VERIFY,
        },
        {
                .name   = "verifysort_nr",
                .lname  = "Verify Sort Nr",
-               .type   = FIO_OPT_INT,
-               .off1   = offsetof(struct thread_options, verifysort_nr),
-               .help   = "Pre-load and sort verify blocks for a read workload",
-               .minval = 0,
-               .maxval = 131072,
-               .def    = "1024",
-               .parent = "verify",
+               .type   = FIO_OPT_SOFT_DEPRECATED,
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_VERIFY,
        },
@@ -3161,6 +3179,30 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .group  = FIO_OPT_G_IOLOG,
                .pow2   = 1,
        },
+       {
+               .name   = "replay_time_scale",
+               .lname  = "Replay Time Scale",
+               .type   = FIO_OPT_INT,
+               .off1   = offsetof(struct thread_options, replay_time_scale),
+               .def    = "100",
+               .minval = 1,
+               .parent = "read_iolog",
+               .hide   = 1,
+               .help   = "Scale time for replay events",
+               .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",
@@ -4428,15 +4470,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .prio   = 1,
                .posval = {
                          { .ival = "0",
-                           .oval = 0,
+                           .oval = N2S_NONE,
                            .help = "Auto-detect",
                          },
                          { .ival = "8",
-                           .oval = 8,
+                           .oval = N2S_BYTEPERSEC,
                            .help = "Normal (byte based)",
                          },
                          { .ival = "1",
-                           .oval = 1,
+                           .oval = N2S_BITPERSEC,
                            .help = "Bit based",
                          },
                },
@@ -4748,7 +4790,7 @@ static char *bc_calc(char *str)
  * substitution always occurs, even if VARNAME is empty or the corresponding
  * environment variable undefined.
  */
-static char *option_dup_subs(const char *opt)
+char *fio_option_dup_subs(const char *opt)
 {
        char out[OPT_LEN_MAX+1];
        char in[OPT_LEN_MAX+1];
@@ -4853,7 +4895,7 @@ static char **dup_and_sub_options(char **opts, int num_opts)
        int i;
        char **opts_copy = malloc(num_opts * sizeof(*opts));
        for (i = 0; i < num_opts; i++) {
-               opts_copy[i] = option_dup_subs(opts[i]);
+               opts_copy[i] = fio_option_dup_subs(opts[i]);
                if (!opts_copy[i])
                        continue;
                opts_copy[i] = fio_keyword_replace(opts_copy[i]);
@@ -5117,8 +5159,7 @@ struct fio_option *fio_option_find(const char *name)
        return find_option(fio_options, name);
 }
 
-static struct fio_option *find_next_opt(struct thread_options *o,
-                                       struct fio_option *from,
+static struct fio_option *find_next_opt(struct fio_option *from,
                                        unsigned int off1)
 {
        struct fio_option *opt;
@@ -5155,7 +5196,7 @@ bool __fio_option_is_set(struct thread_options *o, unsigned int off1)
        struct fio_option *opt, *next;
 
        next = NULL;
-       while ((opt = find_next_opt(o, next, off1)) != NULL) {
+       while ((opt = find_next_opt(next, off1)) != NULL) {
                if (opt_is_set(o, opt))
                        return true;