Wrap thread_data in thread_segment
[fio.git] / options.c
index f4c9bedf377fe0805c787f1bf349e5b91ce0b7e2..1e91b3e9e23a79eb780b35c22e9cd7681e82ab58 100644 (file)
--- a/options.c
+++ b/options.c
 #include "lib/pattern.h"
 #include "options.h"
 #include "optgroup.h"
+#include "zbd.h"
 
 char client_sockaddr_str[INET6_ADDRSTRLEN] = { 0 };
 
 #define cb_data_to_td(data)    container_of(data, struct thread_data, o)
 
-static struct pattern_fmt_desc fmt_desc[] = {
+static const struct pattern_fmt_desc fmt_desc[] = {
        {
                .fmt   = "%o",
                .len   = FIELD_SIZE(struct io_u *, offset),
                .paste = paste_blockoff
-       }
+       },
+       { }
 };
 
 /*
@@ -1235,7 +1237,8 @@ int set_name_idx(char *target, size_t tlen, char *input, int index,
                len = snprintf(target, tlen, "%s/%s.", fname,
                                client_sockaddr_str);
        } else
-               len = snprintf(target, tlen, "%s/", fname);
+               len = snprintf(target, tlen, "%s%c", fname,
+                               FIO_OS_PATH_SEPARATOR);
 
        target[tlen - 1] = '\0';
        free(p);
@@ -1337,7 +1340,7 @@ static int str_buffer_pattern_cb(void *data, const char *input)
 
        /* FIXME: for now buffer pattern does not support formats */
        ret = parse_and_fill_pattern(input, strlen(input), td->o.buffer_pattern,
-                                    MAX_PATTERN_SIZE, NULL, 0, NULL, NULL);
+                                    MAX_PATTERN_SIZE, NULL, NULL, NULL);
        if (ret < 0)
                return 1;
 
@@ -1386,7 +1389,7 @@ static int str_verify_pattern_cb(void *data, const char *input)
 
        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),
+                                    MAX_PATTERN_SIZE, fmt_desc,
                                     td->o.verify_fmt, &td->o.verify_fmt_sz);
        if (ret < 0)
                return 1;
@@ -1407,13 +1410,20 @@ static int str_gtod_reduce_cb(void *data, int *il)
        struct thread_data *td = cb_data_to_td(data);
        int val = *il;
 
-       td->o.disable_lat = !!val;
-       td->o.disable_clat = !!val;
-       td->o.disable_slat = !!val;
-       td->o.disable_bw = !!val;
-       td->o.clat_percentiles = !val;
-       if (val)
+       /*
+        * Only modfiy options if gtod_reduce==1
+        * Otherwise leave settings alone.
+        */
+       if (val) {
+               td->o.disable_lat = 1;
+               td->o.disable_clat = 1;
+               td->o.disable_slat = 1;
+               td->o.disable_bw = 1;
+               td->o.clat_percentiles = 0;
+               td->o.lat_percentiles = 0;
+               td->o.slat_percentiles = 0;
                td->ts_cache_mask = 63;
+       }
 
        return 0;
 }
@@ -1434,6 +1444,22 @@ static int str_offset_cb(void *data, unsigned long long *__val)
        return 0;
 }
 
+static int str_offset_increment_cb(void *data, unsigned long long *__val)
+{
+       struct thread_data *td = cb_data_to_td(data);
+       unsigned long long v = *__val;
+
+       if (parse_is_percent(v)) {
+               td->o.offset_increment = 0;
+               td->o.offset_increment_percent = -1ULL - v;
+               dprint(FD_PARSE, "SET offset_increment_percent %d\n",
+                                       td->o.offset_increment_percent);
+       } else
+               td->o.offset_increment = v;
+
+       return 0;
+}
+
 static int str_size_cb(void *data, unsigned long long *__val)
 {
        struct thread_data *td = cb_data_to_td(data);
@@ -1450,6 +1476,26 @@ static int str_size_cb(void *data, unsigned long long *__val)
        return 0;
 }
 
+static int str_io_size_cb(void *data, unsigned long long *__val)
+{
+       struct thread_data *td = cb_data_to_td(data);
+       unsigned long long v = *__val;
+
+       if (parse_is_percent_uncapped(v)) {
+               td->o.io_size = 0;
+               td->o.io_size_percent = -1ULL - v;
+               if (td->o.io_size_percent > 100) {
+                       log_err("fio: io_size values greater than 100%% aren't supported\n");
+                       return 1;
+               }
+               dprint(FD_PARSE, "SET io_size_percent %d\n",
+                                       td->o.io_size_percent);
+       } else
+               td->o.io_size = v;
+
+       return 0;
+}
+
 static int str_write_bw_log_cb(void *data, const char *str)
 {
        struct thread_data *td = cb_data_to_td(data);
@@ -1826,11 +1872,6 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                          { .ival = "cpuio",
                            .help = "CPU cycle burner engine",
                          },
-#ifdef CONFIG_GUASI
-                         { .ival = "guasi",
-                           .help = "GUASI IO engine",
-                         },
-#endif
 #ifdef CONFIG_RDMA
                          { .ival = "rdma",
                            .help = "RDMA IO engine",
@@ -2017,6 +2058,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .alias  = "io_limit",
                .lname  = "IO Size",
                .type   = FIO_OPT_STR_VAL,
+               .cb     = str_io_size_cb,
                .off1   = offsetof(struct thread_options, io_size),
                .help   = "Total size of I/O to be performed",
                .interval = 1024 * 1024,
@@ -2084,6 +2126,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .name   = "offset_increment",
                .lname  = "IO offset increment",
                .type   = FIO_OPT_STR_VAL,
+               .cb     = str_offset_increment_cb,
                .off1   = offsetof(struct thread_options, offset_increment),
                .help   = "What is the increment from one offset to the next",
                .parent = "offset",
@@ -2395,14 +2438,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .parent = "nrfiles",
                .hide   = 1,
        },
-#ifdef FIO_HAVE_ANY_FALLOCATE
        {
                .name   = "fallocate",
                .lname  = "Fallocate",
                .type   = FIO_OPT_STR,
                .off1   = offsetof(struct thread_options, fallocate_mode),
                .help   = "Whether pre-allocation is performed when laying out files",
+#ifdef FIO_HAVE_DEFAULT_FALLOCATE
                .def    = "native",
+#else
+               .def    = "none",
+#endif
                .category = FIO_OPT_C_FILE,
                .group  = FIO_OPT_G_INVALID,
                .posval = {
@@ -2426,6 +2472,10 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                            .help = "Use fallocate(..., FALLOC_FL_KEEP_SIZE, ...)",
                          },
 #endif
+                         { .ival = "truncate",
+                           .oval = FIO_FALLOCATE_TRUNCATE,
+                           .help = "Truncate file to final size instead of allocating"
+                         },
                          /* Compatibility with former boolean values */
                          { .ival = "0",
                            .oval = FIO_FALLOCATE_NONE,
@@ -2439,14 +2489,6 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
 #endif
                },
        },
-#else  /* FIO_HAVE_ANY_FALLOCATE */
-       {
-               .name   = "fallocate",
-               .lname  = "Fallocate",
-               .type   = FIO_OPT_UNSUPPORTED,
-               .help   = "Your platform does not support fallocate",
-       },
-#endif /* FIO_HAVE_ANY_FALLOCATE */
        {
                .name   = "fadvise_hint",
                .lname  = "Fadvise hint",
@@ -3301,6 +3343,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_ZONE,
        },
+       {
+               .name   = "zonecapacity",
+               .lname  = "Zone capacity",
+               .type   = FIO_OPT_STR_VAL,
+               .off1   = offsetof(struct thread_options, zone_capacity),
+               .help   = "Capacity per zone",
+               .def    = "0",
+               .interval = 1024 * 1024,
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_ZONE,
+       },
        {
                .name   = "zonerange",
                .lname  = "Zone range",
@@ -3335,12 +3388,22 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        },
        {
                .name   = "max_open_zones",
-               .lname  = "Maximum number of open zones",
+               .lname  = "Per device/file maximum number of open zones",
                .type   = FIO_OPT_INT,
                .off1   = offsetof(struct thread_options, max_open_zones),
-               .maxval = FIO_MAX_OPEN_ZBD_ZONES,
-               .help   = "Limit random writes to SMR drives to the specified"
-                         " number of sequential zones",
+               .maxval = ZBD_MAX_OPEN_ZONES,
+               .help   = "Limit on the number of simultaneously opened sequential write zones with zonemode=zbd",
+               .def    = "0",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_INVALID,
+       },
+       {
+               .name   = "job_max_open_zones",
+               .lname  = "Job maximum number of open zones",
+               .type   = FIO_OPT_INT,
+               .off1   = offsetof(struct thread_options, job_max_open_zones),
+               .maxval = ZBD_MAX_OPEN_ZONES,
+               .help   = "Limit on the number of simultaneously opened sequential write zones with zonemode=zbd by one thread/process",
                .def    = "0",
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_INVALID,
@@ -3512,7 +3575,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        {
                .name   = "rate",
                .lname  = "I/O rate",
-               .type   = FIO_OPT_INT,
+               .type   = FIO_OPT_ULL,
                .off1   = offsetof(struct thread_options, rate[DDIR_READ]),
                .off2   = offsetof(struct thread_options, rate[DDIR_WRITE]),
                .off3   = offsetof(struct thread_options, rate[DDIR_TRIM]),
@@ -3524,7 +3587,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .name   = "rate_min",
                .alias  = "ratemin",
                .lname  = "I/O min rate",
-               .type   = FIO_OPT_INT,
+               .type   = FIO_OPT_ULL,
                .off1   = offsetof(struct thread_options, ratemin[DDIR_READ]),
                .off2   = offsetof(struct thread_options, ratemin[DDIR_WRITE]),
                .off3   = offsetof(struct thread_options, ratemin[DDIR_TRIM]),
@@ -3647,6 +3710,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_LATPROF,
        },
+       {
+               .name   = "latency_run",
+               .lname  = "Latency Run",
+               .type   = FIO_OPT_BOOL,
+               .off1   = offsetof(struct thread_options, latency_run),
+               .help   = "Keep adjusting queue depth to match latency_target",
+               .def    = "0",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_LATPROF,
+       },
        {
                .name   = "invalidate",
                .lname  = "Cache invalidate",
@@ -3660,14 +3733,32 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        {
                .name   = "sync",
                .lname  = "Synchronous I/O",
-               .type   = FIO_OPT_BOOL,
+               .type   = FIO_OPT_STR,
                .off1   = offsetof(struct thread_options, sync_io),
-               .help   = "Use O_SYNC for buffered writes",
-               .def    = "0",
-               .parent = "buffered",
+               .help   = "Use synchronous write IO",
+               .def    = "none",
                .hide   = 1,
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_IO_TYPE,
+               .posval = {
+                         { .ival = "none",
+                           .oval = 0,
+                         },
+                         { .ival = "0",
+                           .oval = 0,
+                         },
+                         { .ival = "sync",
+                           .oval = O_SYNC,
+                         },
+                         { .ival = "1",
+                           .oval = O_SYNC,
+                         },
+#ifdef O_DSYNC
+                         { .ival = "dsync",
+                           .oval = O_DSYNC,
+                         },
+#endif
+               },
        },
 #ifdef FIO_HAVE_WRITE_HINT
        {
@@ -3924,6 +4015,30 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_GENERAL,
                .group  = FIO_OPT_G_PROCESS,
        },
+       {
+               .name   = "exit_what",
+               .lname  = "What jobs to quit on terminate",
+               .type   = FIO_OPT_STR,
+               .off1   = offsetof(struct thread_options, exit_what),
+               .help   = "Fine-grained control for exitall",
+               .def    = "group",
+               .category = FIO_OPT_C_GENERAL,
+               .group  = FIO_OPT_G_PROCESS,
+               .posval = {
+                         { .ival = "group",
+                           .oval = TERMINATE_GROUP,
+                           .help = "exit_all=1 default behaviour",
+                         },
+                         { .ival = "stonewall",
+                           .oval = TERMINATE_STONEWALL,
+                           .help = "quit all currently running jobs; continue with next stonewall",
+                         },
+                         { .ival = "all",
+                           .oval = TERMINATE_ALL,
+                           .help = "Quit everything",
+                         },
+               },
+       },
        {
                .name   = "exitall_on_error",
                .lname  = "Exit-all on terminate in error",
@@ -4271,7 +4386,6 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .off1   = offsetof(struct thread_options, clat_percentiles),
                .help   = "Enable the reporting of completion latency percentiles",
                .def    = "1",
-               .inverse = "lat_percentiles",
                .category = FIO_OPT_C_STAT,
                .group  = FIO_OPT_G_INVALID,
        },
@@ -4282,7 +4396,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .off1   = offsetof(struct thread_options, lat_percentiles),
                .help   = "Enable the reporting of IO latency percentiles",
                .def    = "0",
-               .inverse = "clat_percentiles",
+               .category = FIO_OPT_C_STAT,
+               .group  = FIO_OPT_G_INVALID,
+       },
+       {
+               .name   = "slat_percentiles",
+               .lname  = "Submission latency percentiles",
+               .type   = FIO_OPT_BOOL,
+               .off1   = offsetof(struct thread_options, slat_percentiles),
+               .help   = "Enable the reporting of submission latency percentiles",
+               .def    = "0",
                .category = FIO_OPT_C_STAT,
                .group  = FIO_OPT_G_INVALID,
        },
@@ -4613,20 +4736,14 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .parent = "flow_id",
                .hide   = 1,
                .def    = "0",
+               .maxval = FLOW_MAX_WEIGHT,
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_IO_FLOW,
        },
        {
                .name   = "flow_watermark",
                .lname  = "I/O flow watermark",
-               .type   = FIO_OPT_INT,
-               .off1   = offsetof(struct thread_options, flow_watermark),
-               .help   = "High watermark for flow control. This option"
-                       " should be set to the same value for all threads"
-                       " with non-zero flow.",
-               .parent = "flow_id",
-               .hide   = 1,
-               .def    = "1024",
+               .type   = FIO_OPT_SOFT_DEPRECATED,
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_IO_FLOW,
        },
@@ -4902,8 +5019,7 @@ char *fio_option_dup_subs(const char *opt)
                return NULL;
        }
 
-       in[OPT_LEN_MAX] = '\0';
-       strncpy(in, opt, OPT_LEN_MAX);
+       snprintf(in, sizeof(in), "%s", opt);
 
        while (*inptr && nchr > 0) {
                if (inptr[0] == '$' && inptr[1] == '{') {