Add support for latency probing over an interval of load
[fio.git] / options.c
index 6bd745553644283681c095853bca80483671c975..52acf978129d6c900e45635579e672d8b1bb542b 100644 (file)
--- a/options.c
+++ b/options.c
@@ -13,6 +13,7 @@
 #include "lib/pattern.h"
 #include "options.h"
 #include "optgroup.h"
+#include "target.h"
 
 char client_sockaddr_str[INET6_ADDRSTRLEN] = { 0 };
 
@@ -480,9 +481,54 @@ static int str_rwmix_write_cb(void *data, unsigned long long *val)
        return 0;
 }
 
+static int str_iodepth_mode_cb(void *data, const char *input)
+{
+       struct thread_data *td = cb_data_to_td(data);
+       struct thread_options *o = &td->o;
+       char *str, *p, *n;
+       int ret = 1;
+
+       if (o->iodepth_mode == IOD_NONE)
+               return 0;
+
+       if (parse_dryrun())
+               return 0;
+
+       p = str = strdup(input);
+
+       strip_blank_front(&str);
+       strip_blank_end(str);
+
+       n = strchr(p, ':');
+       if (!n)
+               goto err;
+
+       *n++ = '\0';
+
+       /* format is now 'low-min/step' */
+       ret = sscanf(n, "%u-%u/%u,%u/%u", &o->lat_step_low, &o->lat_step_high,
+                                       &o->lat_step_inc, &o->lat_step_ramp,
+                                       &o->lat_step_run);
+       if (ret == 5) {
+               ret = 0;
+               o->lat_step_ramp *= 1000;
+               o->lat_step_run *= 1000;
+       } else if (ret == 3) {
+               o->lat_step_ramp = IOD_STEPPED_DEF_RAMP;
+               o->lat_step_run = IOD_STEPPED_DEF_RUN;
+               ret = 0;
+       } else
+               ret = 1;
+err:
+       if (ret)
+               log_err("fio: failed parsing <%s>\n", input);
+       free(str);
+       return ret;
+}
+
 static int str_exitall_cb(void)
 {
-       exitall_on_terminate = 1;
+       exitall_on_terminate = true;
        return 0;
 }
 
@@ -1155,7 +1201,7 @@ static int str_steadystate_cb(void *data, const char *str)
  * is escaped with a '\', then that ':' is part of the filename and does not
  * indicate a new file.
  */
-static char *get_next_name(char **ptr)
+char *get_next_str(char **ptr)
 {
        char *str = *ptr;
        char *p, *start;
@@ -1197,14 +1243,14 @@ static char *get_next_name(char **ptr)
 }
 
 
-static int get_max_name_idx(char *input)
+int get_max_str_idx(char *input)
 {
        unsigned int cur_idx;
        char *str, *p;
 
        p = str = strdup(input);
        for (cur_idx = 0; ; cur_idx++)
-               if (get_next_name(&str) == NULL)
+               if (get_next_str(&str) == NULL)
                        break;
 
        free(p);
@@ -1224,9 +1270,9 @@ int set_name_idx(char *target, size_t tlen, char *input, int index,
 
        p = str = strdup(input);
 
-       index %= get_max_name_idx(input);
+       index %= get_max_str_idx(input);
        for (cur_idx = 0; cur_idx <= index; cur_idx++)
-               fname = get_next_name(&str);
+               fname = get_next_str(&str);
 
        if (client_sockaddr_str[0] && unique_filename) {
                len = snprintf(target, tlen, "%s/%s.", fname,
@@ -1247,9 +1293,9 @@ char* get_name_by_idx(char *input, int index)
 
        p = str = strdup(input);
 
-       index %= get_max_name_idx(input);
+       index %= get_max_str_idx(input);
        for (cur_idx = 0; cur_idx <= index; cur_idx++)
-               fname = get_next_name(&str);
+               fname = get_next_str(&str);
 
        fname = strdup(fname);
        free(p);
@@ -1273,7 +1319,7 @@ static int str_filename_cb(void *data, const char *input)
        if (!td->files_index)
                td->o.nr_files = 0;
 
-       while ((fname = get_next_name(&str)) != NULL) {
+       while ((fname = get_next_str(&str)) != NULL) {
                if (!strlen(fname))
                        break;
                add_file(td, fname, 0, 1);
@@ -1294,7 +1340,7 @@ static int str_directory_cb(void *data, const char fio_unused *unused)
                return 0;
 
        p = str = strdup(td->o.directory);
-       while ((dirname = get_next_name(&str)) != NULL) {
+       while ((dirname = get_next_str(&str)) != NULL) {
                if (lstat(dirname, &sb) < 0) {
                        ret = errno;
 
@@ -1959,6 +2005,30 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_IO_BASIC,
        },
+       {
+               .name   = "iodepth_mode",
+               .lname  = "IO Depth Mode",
+               .type   = FIO_OPT_STR,
+               .off1   = offsetof(struct thread_options, iodepth_mode),
+               .cb     = str_iodepth_mode_cb,
+               .help   = "How to vary the queue depth",
+               .parent = "iodepth",
+               .hide   = 1,
+               .interval = 1,
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IO_BASIC,
+               .posval = {
+                         { .ival = "none",
+                           .oval = IOD_NONE,
+                           .help = "No depth modification",
+                         },
+                         { .ival = "stepped",
+                           .oval = IOD_STEPPED,
+                           .help = "Stepped IO depth:hi-lo/inc,ramp/run",
+                         },
+               },
+       },
+
        {
                .name   = "serialize_overlap",
                .lname  = "Serialize overlap",
@@ -2202,14 +2272,6 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_RANDOM,
        },
-       {
-               .name   = "use_os_rand",
-               .lname  = "Use OS random",
-               .type   = FIO_OPT_DEPRECATED,
-               .off1   = offsetof(struct thread_options, dep_use_os_rand),
-               .category = FIO_OPT_C_IO,
-               .group  = FIO_OPT_G_RANDOM,
-       },
        {
                .name   = "norandommap",
                .lname  = "No randommap",
@@ -3198,6 +3260,35 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_IOLOG,
        },
+       {
+               .name   = "merge_blktrace_file",
+               .lname  = "Merged blktrace output filename",
+               .type   = FIO_OPT_STR_STORE,
+               .off1   = offsetof(struct thread_options, merge_blktrace_file),
+               .help   = "Merged blktrace output filename",
+               .category = FIO_OPT_C_IO,
+               .group = FIO_OPT_G_IOLOG,
+       },
+       {
+               .name   = "merge_blktrace_scalars",
+               .lname  = "Percentage to scale each trace",
+               .type   = FIO_OPT_FLOAT_LIST,
+               .off1   = offsetof(struct thread_options, merge_blktrace_scalars),
+               .maxlen = FIO_IO_U_LIST_MAX_LEN,
+               .help   = "Percentage to scale each trace",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IOLOG,
+       },
+       {
+               .name   = "merge_blktrace_iters",
+               .lname  = "Number of iterations to run per trace",
+               .type   = FIO_OPT_FLOAT_LIST,
+               .off1   = offsetof(struct thread_options, merge_blktrace_iters),
+               .maxlen = FIO_IO_U_LIST_MAX_LEN,
+               .help   = "Number of iterations to run per trace",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IOLOG,
+       },
        {
                .name   = "exec_prerun",
                .lname  = "Pre-execute runnable",