Merge branch 'enable-dataplacement-scheme' of https://github.com/parkvibes/fio
[fio.git] / options.c
index 6b2cb53f77b381db1e9fa875ad73f96111ed124c..f5d221c776317fe50e2e0229a8e9564d244b8db4 100644 (file)
--- a/options.c
+++ b/options.c
@@ -270,16 +270,60 @@ static int str_fdp_pli_cb(void *data, const char *input)
        strip_blank_front(&str);
        strip_blank_end(str);
 
-       while ((v = strsep(&str, ",")) != NULL && i < FIO_MAX_PLIS)
-               td->o.fdp_plis[i++] = strtoll(v, NULL, 0);
+       while ((v = strsep(&str, ",")) != NULL && i < FIO_MAX_DP_IDS) {
+               unsigned long long id = strtoull(v, NULL, 0);
+               if (id > 0xFFFF) {
+                       log_err("Placement IDs cannot exceed 0xFFFF\n");
+                       free(p);
+                       return 1;
+               }
+               td->o.dp_ids[i++] = id;
+       }
        free(p);
 
-       qsort(td->o.fdp_plis, i, sizeof(*td->o.fdp_plis), fio_fdp_cmp);
-       td->o.fdp_nrpli = i;
+       qsort(td->o.dp_ids, i, sizeof(*td->o.dp_ids), fio_fdp_cmp);
+       td->o.dp_nr_ids = i;
 
        return 0;
 }
 
+/* str_dp_scheme_cb() is a callback function for parsing the fdp_scheme option
+       This function validates the fdp_scheme filename. */
+static int str_dp_scheme_cb(void *data, const char *input)
+{
+       struct thread_data *td = cb_data_to_td(data);
+       struct stat sb;
+       char *filename;
+       int ret = 0;
+
+       if (parse_dryrun())
+               return 0;
+
+       filename = strdup(td->o.dp_scheme_file);
+       strip_blank_front(&filename);
+       strip_blank_end(filename);
+
+       strcpy(td->o.dp_scheme_file, filename);
+
+       if (lstat(filename, &sb) < 0){
+               ret = errno;
+               log_err("fio: lstat() error related to %s\n", filename);
+               td_verror(td, ret, "lstat");
+               goto out;
+       }
+
+       if (!S_ISREG(sb.st_mode)) {
+               ret = errno;
+               log_err("fio: %s is not a file\n", filename);
+               td_verror(td, ret, "S_ISREG");
+               goto out;
+       }
+
+out:
+       free(filename);
+       return ret;
+}
+
 static int str_bssplit_cb(void *data, const char *input)
 {
        struct thread_data *td = cb_data_to_td(data);
@@ -647,7 +691,7 @@ static int fio_clock_source_cb(void *data, const char *str)
        return 0;
 }
 
-static int str_rwmix_read_cb(void *data, unsigned long long *val)
+static int str_rwmix_read_cb(void *data, long long *val)
 {
        struct thread_data *td = cb_data_to_td(data);
 
@@ -656,7 +700,7 @@ static int str_rwmix_read_cb(void *data, unsigned long long *val)
        return 0;
 }
 
-static int str_rwmix_write_cb(void *data, unsigned long long *val)
+static int str_rwmix_write_cb(void *data, long long *val)
 {
        struct thread_data *td = cb_data_to_td(data);
 
@@ -1625,7 +1669,7 @@ static int str_gtod_reduce_cb(void *data, int *il)
        return 0;
 }
 
-static int str_offset_cb(void *data, unsigned long long *__val)
+static int str_offset_cb(void *data, long long *__val)
 {
        struct thread_data *td = cb_data_to_td(data);
        unsigned long long v = *__val;
@@ -1646,7 +1690,7 @@ 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)
+static int str_offset_increment_cb(void *data, long long *__val)
 {
        struct thread_data *td = cb_data_to_td(data);
        unsigned long long v = *__val;
@@ -1667,7 +1711,7 @@ static int str_offset_increment_cb(void *data, unsigned long long *__val)
        return 0;
 }
 
-static int str_size_cb(void *data, unsigned long long *__val)
+static int str_size_cb(void *data, long long *__val)
 {
        struct thread_data *td = cb_data_to_td(data);
        unsigned long long v = *__val;
@@ -1711,7 +1755,7 @@ static int str_io_size_cb(void *data, unsigned long long *__val)
        return 0;
 }
 
-static int str_zoneskip_cb(void *data, unsigned long long *__val)
+static int str_zoneskip_cb(void *data, long long *__val)
 {
        struct thread_data *td = cb_data_to_td(data);
        unsigned long long v = *__val;
@@ -2395,6 +2439,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_INVALID,
        },
+       {
+               .name   = "num_range",
+               .lname  = "Number of ranges",
+               .type   = FIO_OPT_INT,
+               .off1   = offsetof(struct thread_options, num_range),
+               .maxval = MAX_TRIM_RANGE,
+               .help   = "Number of ranges for trim command",
+               .def    = "1",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_INVALID,
+       },
        {
                .name   = "bs",
                .lname  = "Block size",
@@ -3699,36 +3754,78 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .group  = FIO_OPT_G_INVALID,
        },
        {
-               .name   = "fdp_pli_select",
-               .lname  = "FDP Placement ID select",
+               .name   = "dataplacement",
+               .alias  = "data_placement",
+               .lname  = "Data Placement interface",
+               .type   = FIO_OPT_STR,
+               .off1   = offsetof(struct thread_options, dp_type),
+               .help   = "Data Placement interface to use",
+               .def    = "none",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_INVALID,
+               .posval = {
+                         { .ival = "none",
+                           .oval = FIO_DP_NONE,
+                           .help = "Do not specify a data placement interface",
+                         },
+                         { .ival = "fdp",
+                           .oval = FIO_DP_FDP,
+                           .help = "Use Flexible Data Placement interface",
+                         },
+                         { .ival = "streams",
+                           .oval = FIO_DP_STREAMS,
+                           .help = "Use Streams interface",
+                         },
+               },
+       },
+       {
+               .name   = "plid_select",
+               .alias  = "fdp_pli_select",
+               .lname  = "Data Placement ID selection strategy",
                .type   = FIO_OPT_STR,
-               .off1   = offsetof(struct thread_options, fdp_pli_select),
-               .help   = "Select which FDP placement ID to use next",
+               .off1   = offsetof(struct thread_options, dp_id_select),
+               .help   = "Strategy for selecting next Data Placement ID",
                .def    = "roundrobin",
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_INVALID,
                .posval = {
                          { .ival = "random",
-                           .oval = FIO_FDP_RANDOM,
+                           .oval = FIO_DP_RANDOM,
                            .help = "Choose a Placement ID at random (uniform)",
                          },
                          { .ival = "roundrobin",
-                           .oval = FIO_FDP_RR,
+                           .oval = FIO_DP_RR,
                            .help = "Round robin select Placement IDs",
                          },
+                         { .ival = "scheme",
+                           .oval = FIO_DP_SCHEME,
+                           .help = "Use a scheme(based on LBA) to select Placement IDs",
+                         },
                },
        },
        {
-               .name   = "fdp_pli",
-               .lname  = "FDP Placement ID indicies",
+               .name   = "plids",
+               .alias  = "fdp_pli",
+               .lname  = "Stream IDs/Data Placement ID indices",
                .type   = FIO_OPT_STR,
                .cb     = str_fdp_pli_cb,
-               .off1   = offsetof(struct thread_options, fdp_plis),
-               .help   = "Sets which placement ids to use (defaults to all)",
+               .off1   = offsetof(struct thread_options, dp_ids),
+               .help   = "Sets which Data Placement ids to use (defaults to all for FDP)",
                .hide   = 1,
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_INVALID,
        },
+       {
+               .name   = "dp_scheme",
+               .lname  = "Data Placement Scheme",
+               .type   = FIO_OPT_STR_STORE,
+               .cb     = str_dp_scheme_cb,
+               .off1   = offsetof(struct thread_options, dp_scheme_file),
+               .maxlen = PATH_MAX,
+               .help   = "scheme file that specifies offset-RUH mapping",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_INVALID,
+       },
        {
                .name   = "lockmem",
                .lname  = "Lock memory",
@@ -3875,6 +3972,18 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_THINKTIME,
        },
+       {
+               .name   = "thinkcycles",
+               .lname  = "Think cycles",
+               .type   = FIO_OPT_INT,
+               .off1   = offsetof(struct thread_options, thinkcycles),
+               .help   = "Spin for a constant amount of cycles between requests",
+               .def    = "0",
+               .parent = "thinktime",
+               .hide   = 1,
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_THINKTIME,
+       },
        {
                .name   = "thinktime_blocks",
                .lname  = "Thinktime blocks",
@@ -4528,14 +4637,38 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .group  = FIO_OPT_G_INVALID,
        },
        {
-               .name   = "log_max_value",
-               .lname  = "Log maximum instead of average",
-               .type   = FIO_OPT_BOOL,
+               .name   = "log_window_value",
+               .alias  = "log_max_value",
+               .lname  = "Log maximum, average or both values",
+               .type   = FIO_OPT_STR,
                .off1   = offsetof(struct thread_options, log_max),
-               .help   = "Log max sample in a window instead of average",
-               .def    = "0",
+               .help   = "Log max, average or both sample in a window",
+               .def    = "avg",
                .category = FIO_OPT_C_LOG,
                .group  = FIO_OPT_G_INVALID,
+               .posval = {
+                         { .ival = "avg",
+                           .oval = IO_LOG_SAMPLE_AVG,
+                           .help = "Log average value over the window",
+                         },
+                         { .ival = "max",
+                           .oval = IO_LOG_SAMPLE_MAX,
+                           .help = "Log maximum value in the window",
+                         },
+                         { .ival = "both",
+                           .oval = IO_LOG_SAMPLE_BOTH,
+                           .help = "Log both average and maximum values over the window"
+                         },
+                         /* Compatibility with former boolean values */
+                         { .ival = "0",
+                           .oval = IO_LOG_SAMPLE_AVG,
+                           .help = "Alias for 'avg'",
+                         },
+                         { .ival = "1",
+                           .oval = IO_LOG_SAMPLE_MAX,
+                           .help = "Alias for 'max'",
+                         },
+               },
        },
        {
                .name   = "log_offset",