parse: add support for unsupported options
[fio.git] / options.c
index 7075d84d42493b8bec52702151dbdb4be578fbdf..26356ffdf12c9b4ca78dc99f08edbe040c53ac23 100644 (file)
--- a/options.c
+++ b/options.c
 
 char client_sockaddr_str[INET6_ADDRSTRLEN] = { 0 };
 
+struct pattern_fmt_desc fmt_desc[] = {
+       {
+               .fmt   = "%o",
+               .len   = FIELD_SIZE(struct io_u *, offset),
+               .paste = paste_blockoff
+       }
+};
+
 /*
  * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
  */
@@ -716,12 +724,77 @@ out:
 static int str_fst_cb(void *data, const char *str)
 {
        struct thread_data *td = data;
-       char *nr = get_opt_postfix(str);
+       double val;
+       bool done = false;
+       char *nr;
 
        td->file_service_nr = 1;
-       if (nr) {
-               td->file_service_nr = atoi(nr);
+
+       switch (td->o.file_service_type) {
+       case FIO_FSERVICE_RANDOM:
+       case FIO_FSERVICE_RR:
+       case FIO_FSERVICE_SEQ:
+               nr = get_opt_postfix(str);
+               if (nr) {
+                       td->file_service_nr = atoi(nr);
+                       free(nr);
+               }
+               done = true;
+               break;
+       case FIO_FSERVICE_ZIPF:
+               val = FIO_DEF_ZIPF;
+               break;
+       case FIO_FSERVICE_PARETO:
+               val = FIO_DEF_PARETO;
+               break;
+       case FIO_FSERVICE_GAUSS:
+               val = 0.0;
+               break;
+       default:
+               log_err("fio: bad file service type: %d\n", td->o.file_service_type);
+               return 1;
+       }
+
+       if (done)
+               return 0;
+
+       nr = get_opt_postfix(str);
+       if (nr && !str_to_float(nr, &val, 0)) {
+               log_err("fio: file service type random postfix parsing failed\n");
                free(nr);
+               return 1;
+       }
+
+       free(nr);
+
+       switch (td->o.file_service_type) {
+       case FIO_FSERVICE_ZIPF:
+               if (val == 1.00) {
+                       log_err("fio: zipf theta must be different than 1.0\n");
+                       return 1;
+               }
+               if (parse_dryrun())
+                       return 0;
+               td->zipf_theta = val;
+               break;
+       case FIO_FSERVICE_PARETO:
+               if (val <= 0.00 || val >= 1.00) {
+                          log_err("fio: pareto input out of range (0 < input < 1.0)\n");
+                          return 1;
+               }
+               if (parse_dryrun())
+                       return 0;
+               td->pareto_h = val;
+               break;
+       case FIO_FSERVICE_GAUSS:
+               if (val < 0.00 || val >= 100.00) {
+                          log_err("fio: normal deviation out of range (0 <= input < 100.0)\n");
+                          return 1;
+               }
+               if (parse_dryrun())
+                       return 0;
+               td->gauss_dev = val;
+               break;
        }
 
        return 0;
@@ -974,8 +1047,8 @@ static int str_random_distribution_cb(void *data, const char *str)
                        return 0;
                td->o.pareto_h.u.f = val;
        } else {
-               if (val <= 0.00 || val >= 100.0) {
-                       log_err("fio: normal deviation out of range (0 < input < 100.0)\n");
+               if (val < 0.00 || val >= 100.0) {
+                       log_err("fio: normal deviation out of range (0 <= input < 100.0)\n");
                        return 1;
                }
                if (parse_dryrun())
@@ -1051,7 +1124,8 @@ 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, size_t tlen, char *input, int index)
+int set_name_idx(char *target, size_t tlen, char *input, int index,
+                bool unique_filename)
 {
        unsigned int cur_idx;
        int len;
@@ -1063,7 +1137,7 @@ int set_name_idx(char *target, size_t tlen, char *input, int index)
        for (cur_idx = 0; cur_idx <= index; cur_idx++)
                fname = get_next_name(&str);
 
-       if (client_sockaddr_str[0]) {
+       if (client_sockaddr_str[0] && unique_filename) {
                len = snprintf(target, tlen, "%s/%s.", fname,
                                client_sockaddr_str);
        } else
@@ -1184,20 +1258,13 @@ static int str_dedupe_cb(void *data, unsigned long long *il)
 
 static int str_verify_pattern_cb(void *data, const char *input)
 {
-       struct pattern_fmt_desc fmt_desc[] = {
-               {
-                       .fmt   = "%o",
-                       .len   = FIELD_SIZE(struct io_u *, offset),
-                       .paste = paste_blockoff
-               }
-       };
        struct thread_data *td = data;
        int ret;
 
        td->o.verify_fmt_sz = ARRAY_SIZE(td->o.verify_fmt);
        ret = parse_and_fill_pattern(input, strlen(input), td->o.verify_pattern,
-                       MAX_PATTERN_SIZE, fmt_desc, sizeof(fmt_desc),
-                       td->o.verify_fmt, &td->o.verify_fmt_sz);
+                                    MAX_PATTERN_SIZE, fmt_desc, sizeof(fmt_desc),
+                                    td->o.verify_fmt, &td->o.verify_fmt_sz);
        if (ret < 0)
                return 1;
 
@@ -1324,6 +1391,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "filename_format",
+               .lname  = "Filename Format",
                .type   = FIO_OPT_STR_STORE,
                .off1   = td_var_offset(filename_format),
                .prio   = -1, /* must come after "directory" */
@@ -1332,6 +1400,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_FILE,
                .group  = FIO_OPT_G_FILENAME,
        },
+       {
+               .name   = "unique_filename",
+               .lname  = "Unique Filename",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(unique_filename),
+               .help   = "For network clients, prefix file with source IP",
+               .def    = "1",
+               .category = FIO_OPT_C_FILE,
+               .group  = FIO_OPT_G_FILENAME,
+       },
        {
                .name   = "lockfile",
                .lname  = "Lockfile",
@@ -1470,7 +1548,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                            .help = "Use preadv/pwritev",
                          },
 #endif
-#ifdef CONFIG_PWRITEV
+#ifdef FIO_HAVE_PWRITEV2
                          { .ival = "pvsync2",
                            .help = "Use preadv2/pwritev2",
                          },
@@ -1567,6 +1645,12 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                          { .ival = "libhdfs",
                            .help = "Hadoop Distributed Filesystem (HDFS) engine"
                          },
+#endif
+#ifdef CONFIG_PMEMBLK
+                         { .ival = "pmemblk",
+                           .help = "NVML libpmemblk based IO engine",
+                         },
+
 #endif
                          { .ival = "external",
                            .help = "Load external engine (append name)",
@@ -1594,7 +1678,6 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .help   = "Number of IO buffers to submit in one go",
                .parent = "iodepth",
                .hide   = 1,
-               .minval = 1,
                .interval = 1,
                .def    = "1",
                .category = FIO_OPT_C_IO,
@@ -1893,6 +1976,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "random_generator",
+               .lname  = "Random Generator",
                .type   = FIO_OPT_STR,
                .off1   = td_var_offset(random_generator),
                .help   = "Type of random number generator to use",
@@ -1917,6 +2001,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "random_distribution",
+               .lname  = "Random Distribution",
                .type   = FIO_OPT_STR,
                .off1   = td_var_offset(random_distribution),
                .cb     = str_random_distribution_cb,
@@ -1937,7 +2022,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                          },
                          { .ival = "normal",
                            .oval = FIO_RAND_DIST_GAUSS,
-                           .help = "Normal (gaussian) distribution",
+                           .help = "Normal (Gaussian) distribution",
                          },
                          { .ival = "zoned",
                            .oval = FIO_RAND_DIST_ZONED,
@@ -1972,6 +2057,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "allrandrepeat",
+               .lname  = "All Random Repeat",
                .type   = FIO_OPT_BOOL,
                .off1   = td_var_offset(allrand_repeatable),
                .help   = "Use repeatable random numbers for everything",
@@ -2013,7 +2099,19 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .posval = {
                          { .ival = "random",
                            .oval = FIO_FSERVICE_RANDOM,
-                           .help = "Choose a file at random",
+                           .help = "Choose a file at random (uniform)",
+                         },
+                         { .ival = "zipf",
+                           .oval = FIO_FSERVICE_ZIPF,
+                           .help = "Zipf randomized",
+                         },
+                         { .ival = "pareto",
+                           .oval = FIO_FSERVICE_PARETO,
+                           .help = "Pareto randomized",
+                         },
+                         { .ival = "gauss",
+                           .oval = FIO_FSERVICE_GAUSS,
+                           .help = "Normal (guassian) distribution",
                          },
                          { .ival = "roundrobin",
                            .oval = FIO_FSERVICE_RR,
@@ -2459,6 +2557,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "verifysort_nr",
+               .lname  = "Verify Sort Nr",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(verifysort_nr),
                .help   = "Pre-load and sort verify blocks for a read workload",
@@ -2580,6 +2679,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
 #endif
        {
                .name   = "experimental_verify",
+               .lname  = "Experimental Verify",
                .off1   = td_var_offset(experimental_verify),
                .type   = FIO_OPT_BOOL,
                .help   = "Enable experimental verification",
@@ -2994,6 +3094,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "max_latency",
+               .lname  = "Max Latency",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(max_latency),
                .help   = "Maximum tolerated IO latency (usec)",
@@ -3088,6 +3189,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "create_only",
+               .lname  = "Create Only",
                .type   = FIO_OPT_BOOL,
                .off1   = td_var_offset(create_only),
                .help   = "Only perform file creation phase",
@@ -3170,6 +3272,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
 #ifdef CONFIG_LIBNUMA
        {
                .name   = "numa_cpu_nodes",
+               .lname  = "NUMA CPU Nodes",
                .type   = FIO_OPT_STR,
                .cb     = str_numa_cpunodes_cb,
                .off1   = td_var_offset(numa_cpunodes),
@@ -3179,6 +3282,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "numa_mem_policy",
+               .lname  = "NUMA Memory Policy",
                .type   = FIO_OPT_STR,
                .cb     = str_numa_mpol_cb,
                .off1   = td_var_offset(numa_memnodes),
@@ -3269,6 +3373,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "per_job_logs",
+               .lname  = "Per Job Logs",
                .type   = FIO_OPT_BOOL,
                .off1   = td_var_offset(per_job_logs),
                .help   = "Include job number in generated log files or not",
@@ -3599,6 +3704,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "unified_rw_reporting",
+               .lname  = "Unified RW Reporting",
                .type   = FIO_OPT_BOOL,
                .off1   = td_var_offset(unified_rw_rep),
                .help   = "Unify reporting across data direction",
@@ -3652,6 +3758,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "ignore_error",
+               .lname  = "Ignore Error",
                .type   = FIO_OPT_STR,
                .cb     = str_ignore_error_cb,
                .off1   = td_var_offset(ignore_error_nr),
@@ -3662,6 +3769,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "error_dump",
+               .lname  = "Error Dump",
                .type   = FIO_OPT_BOOL,
                .off1   = td_var_offset(error_dump),
                .def    = "0",
@@ -4169,7 +4277,8 @@ static void show_closest_option(const char *opt)
                i++;
        }
 
-       if (best_option != -1 && string_distance_ok(name, best_distance))
+       if (best_option != -1 && string_distance_ok(name, best_distance) &&
+           fio_options[best_option].type != FIO_OPT_UNSUPPORTED)
                log_err("Did you mean %s?\n", fio_options[best_option].name);
 
        free(name);