#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <netinet/in.h>
#include "fio.h"
#include "verify.h"
#include "crc/crc32c.h"
+char client_sockaddr_str[INET6_ADDRSTRLEN] = { 0 };
+
/*
* Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
*/
for (i = 0; i < sizeof(int) * 8; i++) {
if ((1 << i) & *val) {
- if (i > max_cpu) {
+ if (i >= max_cpu) {
log_err("fio: CPU %d too large (max=%ld)\n", i,
- max_cpu);
+ max_cpu - 1);
return 1;
}
dprint(FD_PARSE, "set cpu allowed %d\n", i);
ret = 1;
break;
}
- if (icpu > max_cpu) {
+ if (icpu >= max_cpu) {
log_err("fio: CPU %d too large (max=%ld)\n",
- icpu, max_cpu);
+ icpu, max_cpu - 1);
ret = 1;
break;
}
return 0;
if (td->o.random_distribution == FIO_RAND_DIST_ZIPF)
- val = 1.1;
+ val = FIO_DEF_ZIPF;
else if (td->o.random_distribution == FIO_RAND_DIST_PARETO)
- val = 0.2;
+ val = FIO_DEF_PARETO;
+ else if (td->o.random_distribution == FIO_RAND_DIST_GAUSS)
+ val = 0.0;
else
return 0;
return 1;
}
td->o.zipf_theta.u.f = val;
- } else {
+ } else if (td->o.random_distribution == FIO_RAND_DIST_PARETO) {
if (val <= 0.00 || val >= 1.00) {
log_err("fio: pareto input out of range (0 < input < 1.0)\n");
return 1;
}
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");
+ return 1;
+ }
+ td->o.gauss_dev.u.f = val;
}
return 0;
* Returns the directory at the index, indexes > entires will be
* assigned via modulo division of the index
*/
-int set_name_idx(char *target, char *input, int index)
+int set_name_idx(char *target, size_t tlen, char *input, int index)
{
unsigned int cur_idx;
int len;
for (cur_idx = 0; cur_idx <= index; cur_idx++)
fname = get_next_name(&str);
- len = sprintf(target, "%s/", fname);
+ if (client_sockaddr_str[0]) {
+ len = snprintf(target, tlen, "%s/%s.", fname,
+ client_sockaddr_str);
+ } else
+ len = snprintf(target, tlen, "%s/", fname);
+
+ target[tlen - 1] = '\0';
free(p);
return len;
return ret;
}
-static int str_lockfile_cb(void *data, const char fio_unused *str)
-{
- struct thread_data *td = data;
-
- if (td->files_index) {
- log_err("fio: lockfile= option must precede filename=\n");
- return 1;
- }
-
- return 0;
-}
-
static int str_opendir_cb(void *data, const char fio_unused *str)
{
struct thread_data *td = data;
return 0;
}
-static int str_gtod_cpu_cb(void *data, long long *il)
-{
- struct thread_data *td = data;
- int val = *il;
-
- td->o.gtod_cpu = val;
- td->o.gtod_offload = 1;
- return 0;
-}
-
static int str_size_cb(void *data, unsigned long long *__val)
{
struct thread_data *td = data;
.name = "Tiobench profile",
.mask = FIO_OPT_G_TIOBENCH,
},
+ {
+ .name = "MTD",
+ .mask = FIO_OPT_G_MTD,
+ },
{
.name = NULL,
.parent = "filename",
.hide = 0,
.def = "none",
- .cb = str_lockfile_cb,
.category = FIO_OPT_C_FILE,
.group = FIO_OPT_G_FILENAME,
.posval = {
.oval = TD_DDIR_RANDRW,
.help = "Random read and write mix"
},
+ { .ival = "trimwrite",
+ .oval = TD_DDIR_TRIMWRITE,
+ .help = "Trim and write mix, trims preceding writes"
+ },
},
},
{
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_IO_BASIC,
},
+ {
+ .name = "io_submit_mode",
+ .lname = "IO submit mode",
+ .type = FIO_OPT_STR,
+ .off1 = td_var_offset(io_submit_mode),
+ .help = "How IO submissions and completions are done",
+ .def = "inline",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_IO_BASIC,
+ .posval = {
+ { .ival = "inline",
+ .oval = IO_MODE_INLINE,
+ .help = "Submit and complete IO inline",
+ },
+ { .ival = "offload",
+ .oval = IO_MODE_OFFLOAD,
+ .help = "Offload submit and complete to threads",
+ },
+ },
+ },
{
.name = "size",
.lname = "Size",
.group = FIO_OPT_G_INVALID,
},
{
- .name = "io_limit",
- .lname = "IO Limit",
+ .name = "io_size",
+ .alias = "io_limit",
+ .lname = "IO Size",
.type = FIO_OPT_STR_VAL,
.off1 = td_var_offset(io_limit),
.interval = 1024 * 1024,
.oval = FIO_RAND_DIST_PARETO,
.help = "Pareto distribution",
},
+ { .ival = "normal",
+ .oval = FIO_RAND_DIST_GAUSS,
+ .help = "Normal (gaussian) distribution",
+ },
},
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_RANDOM,
.category = FIO_OPT_C_FILE,
.group = FIO_OPT_G_INVALID,
},
+#ifdef FIO_HAVE_STREAMID
+ {
+ .name = "fadvise_stream",
+ .lname = "Fadvise stream",
+ .type = FIO_OPT_INT,
+ .off1 = td_var_offset(fadvise_stream),
+ .help = "Use fadvise() to set stream ID",
+ .category = FIO_OPT_C_FILE,
+ .group = FIO_OPT_G_INVALID,
+ },
+#endif
{
.name = "fsync",
.lname = "Fsync",
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_IOLOG,
},
+ {
+ .name = "replay_scale",
+ .lname = "Replace offset scale factor",
+ .type = FIO_OPT_INT,
+ .off1 = td_var_offset(replay_scale),
+ .parent = "read_iolog",
+ .def = "1",
+ .help = "Align offsets to this blocksize",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_IOLOG,
+ },
+ {
+ .name = "replay_align",
+ .lname = "Replace alignment",
+ .type = FIO_OPT_INT,
+ .off1 = td_var_offset(replay_align),
+ .parent = "read_iolog",
+ .help = "Scale offset down by this factor",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_IOLOG,
+ .pow2 = 1,
+ },
{
.name = "exec_prerun",
.lname = "Pre-execute runnable",
.group = FIO_OPT_G_INVALID,
},
#endif
+ {
+ .name = "block_error_percentiles",
+ .lname = "Block error percentiles",
+ .type = FIO_OPT_BOOL,
+ .off1 = td_var_offset(block_error_hist),
+ .help = "Record trim block errors and make a histogram",
+ .def = "0",
+ .category = FIO_OPT_C_LOG,
+ .group = FIO_OPT_G_INVALID,
+ },
{
.name = "bwavgtime",
.lname = "Bandwidth average time",
},
{
.name = "percentile_list",
- .lname = "Completion latency percentile list",
+ .lname = "Percentile list",
.type = FIO_OPT_FLOAT_LIST,
.off1 = td_var_offset(percentile_list),
.off2 = td_var_offset(percentile_precision),
- .help = "Specify a custom list of percentiles to report",
+ .help = "Specify a custom list of percentiles to report for "
+ "completion latency and block errors",
.def = "1:5:10:20:30:40:50:60:70:80:90:95:99:99.5:99.9:99.95:99.99",
.maxlen = FIO_IO_U_LIST_MAX_LEN,
.minfp = 0.0,
.name = "gtod_cpu",
.lname = "Dedicated gettimeofday() CPU",
.type = FIO_OPT_INT,
- .cb = str_gtod_cpu_cb,
+ .off1 = td_var_offset(gtod_cpu),
.help = "Set up dedicated gettimeofday() thread on this CPU",
.verify = gtod_cpu_verify,
.category = FIO_OPT_C_GENERAL,
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_IO_FLOW,
},
+ {
+ .name = "skip_bad",
+ .lname = "Skip operations against bad blocks",
+ .type = FIO_OPT_BOOL,
+ .off1 = td_var_offset(skip_bad),
+ .help = "Skip operations against known bad blocks.",
+ .hide = 1,
+ .def = "0",
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_MTD,
+ },
{
.name = NULL,
},
},
};
+void fio_keywords_exit(void)
+{
+ struct fio_keyword *kw;
+
+ kw = &fio_keywords[0];
+ while (kw->word) {
+ free(kw->replace);
+ kw->replace = NULL;
+ kw++;
+ }
+}
+
void fio_keywords_init(void)
{
unsigned long long mb_memory;
return find_option(fio_options, name);
}
-int __fio_option_is_set(struct thread_options *o, unsigned int off1)
+static struct fio_option *find_next_opt(struct thread_options *o,
+ struct fio_option *from,
+ unsigned int off1)
{
- unsigned int opt_off, index, offset;
- struct fio_option *opt = NULL;
- int i;
+ struct fio_option *opt;
- for (i = 0; fio_options[i].name; i++) {
- if (off1 == fio_options[i].off1) {
- opt = &fio_options[i];
+ if (!from)
+ from = &fio_options[0];
+ else
+ from++;
+
+ opt = NULL;
+ do {
+ if (off1 == from->off1) {
+ opt = from;
break;
}
- }
+ from++;
+ } while (from->name);
- if (!opt) {
- log_err("fio: no option found at offset %u\n", off1);
- return 0;
- }
+ return opt;
+}
+
+static int opt_is_set(struct thread_options *o, struct fio_option *opt)
+{
+ unsigned int opt_off, index, offset;
opt_off = opt - &fio_options[0];
index = opt_off / (8 * sizeof(uint64_t));
return (o->set_options[index] & (1UL << offset)) != 0;
}
+int __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) {
+ if (opt_is_set(o, opt))
+ return 1;
+
+ next = opt;
+ }
+
+ return 0;
+}
+
void fio_option_mark_set(struct thread_options *o, struct fio_option *opt)
{
unsigned int opt_off, index, offset;