X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=options.c;h=f26ff77647329a645f0fa4ead9eb9a58adcceba7;hp=fcf427037f77f0ab456efc055b725a485fbe2512;hb=5054e67c7d87f25a9eb7b647adaee5e1c9c7cc5b;hpb=6a5c4d92ce70a05d2fee981b6f133373c0ef62f8 diff --git a/options.c b/options.c index fcf42703..f26ff776 100644 --- a/options.c +++ b/options.c @@ -104,7 +104,7 @@ static int bssplit_ddir(struct thread_options *o, int ddir, char *str) if (str_to_decimal(fname, &val, 1, o)) { log_err("fio: bssplit conversion failed\n"); - free(o->bssplit); + free(bssplit); return 1; } @@ -168,6 +168,9 @@ static int str_bssplit_cb(void *data, const char *input) char *str, *p, *odir, *ddir; int ret = 0; + if (parse_dryrun()) + return 0; + p = str = strdup(input); strip_blank_front(&str); @@ -271,6 +274,7 @@ static int ignore_error_type(struct thread_data *td, int etype, char *str) if (!error[i]) { log_err("Unknown error %s, please use number value \n", fname); + free(error); return 1; } i++; @@ -289,6 +293,10 @@ static int str_ignore_error_cb(void *data, const char *input) struct thread_data *td = data; char *str, *p, *n; int type = 0, ret = 1; + + if (parse_dryrun()) + return 0; + p = str = strdup(input); strip_blank_front(&str); @@ -314,6 +322,9 @@ static int str_rw_cb(void *data, const char *str) struct thread_options *o = &td->o; char *nr = get_opt_postfix(str); + if (parse_dryrun()) + return 0; + o->ddir_seq_nr = 1; o->ddir_seq_add = 0; @@ -390,6 +401,9 @@ static int str_cpumask_cb(void *data, unsigned long long *val) long max_cpu; int ret; + if (parse_dryrun()) + return 0; + ret = fio_cpuset_init(&td->o.cpumask); if (ret < 0) { log_err("fio: cpuset_init failed\n"); @@ -488,6 +502,9 @@ static int str_cpus_allowed_cb(void *data, const char *input) struct thread_data *td = data; int ret; + if (parse_dryrun()) + return 0; + ret = set_cpus_allowed(td, &td->o.cpumask, input); if (!ret) td->o.cpumask_set = 1; @@ -513,6 +530,9 @@ static int str_numa_cpunodes_cb(void *data, char *input) { struct thread_data *td = data; + if (parse_dryrun()) + return 0; + /* numa_parse_nodestring() parses a character string list * of nodes into a bit mask. The bit mask is allocated by * numa_allocate_nodemask(), so it should be freed by @@ -533,10 +553,14 @@ static int str_numa_mpol_cb(void *data, char *input) { struct thread_data *td = data; const char * const policy_types[] = - { "default", "prefer", "bind", "interleave", "local" }; + { "default", "prefer", "bind", "interleave", "local", NULL }; int i; + char *nodelist; - char *nodelist = strchr(input, ':'); + if (parse_dryrun()) + return 0; + + nodelist = strchr(input, ':'); if (nodelist) { /* NUL-terminate mode */ *nodelist++ = '\0'; @@ -668,6 +692,9 @@ static int str_random_distribution_cb(void *data, const char *str) double val; char *nr; + if (parse_dryrun()) + return 0; + if (td->o.random_distribution == FIO_RAND_DIST_ZIPF) val = 1.1; else if (td->o.random_distribution == FIO_RAND_DIST_PARETO) @@ -776,6 +803,9 @@ static int str_directory_cb(void *data, const char fio_unused *str) struct thread_data *td = data; struct stat sb; + if (parse_dryrun()) + return 0; + if (lstat(td->o.directory, &sb) < 0) { int ret = errno; @@ -795,6 +825,9 @@ static int str_opendir_cb(void *data, const char fio_unused *str) { struct thread_data *td = data; + if (parse_dryrun()) + return 0; + if (!td->files_index) td->o.nr_files = 0; @@ -805,7 +838,7 @@ static int str_verify_pattern_cb(void *data, const char *input) { struct thread_data *td = data; long off; - int i = 0, j = 0, len, k, base = 10; + int i = 0, j = 0, len, k, base = 10, pattern_length; char *loc1, *loc2; loc1 = strstr(input, "0x"); @@ -844,10 +877,23 @@ static int str_verify_pattern_cb(void *data, const char *input) * Fill the pattern all the way to the end. This greatly reduces * the number of memcpy's we have to do when verifying the IO. */ + pattern_length = i; while (i > 1 && i * 2 <= MAX_PATTERN_SIZE) { memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], i); i *= 2; } + + /* + * Fill remainder, if the pattern multiple ends up not being + * MAX_PATTERN_SIZE. + */ + while (i > 1 && i < MAX_PATTERN_SIZE) { + unsigned int b = min(pattern_length, MAX_PATTERN_SIZE - i); + + memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], b); + i += b; + } + if (i == 1) { /* * The code in verify_io_u_pattern assumes a single byte pattern @@ -868,20 +914,6 @@ static int str_verify_pattern_cb(void *data, const char *input) return 0; } -static int str_lockfile_cb(void *data, const char *str) -{ - struct thread_data *td = data; - char *nr = get_opt_postfix(str); - - td->o.lockfile_batch = 1; - if (nr) { - td->o.lockfile_batch = atoi(nr); - free(nr); - } - - return 0; -} - static int str_gtod_reduce_cb(void *data, int *il) { struct thread_data *td = data; @@ -950,19 +982,6 @@ static int gtod_cpu_verify(struct fio_option *o, void *data) return 0; } -static int kb_base_verify(struct fio_option *o, void *data) -{ - struct thread_data *td = data; - - if (td->o.kb_base != 1024 && td->o.kb_base != 1000) { - log_err("fio: kb_base set to nonsensical value: %u\n", - td->o.kb_base); - return 1; - } - - return 0; -} - /* * Option grouping */ @@ -1161,11 +1180,20 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_FILE, .group = FIO_OPT_G_FILENAME, }, + { + .name = "filename_format", + .type = FIO_OPT_STR_STORE, + .off1 = td_var_offset(filename_format), + .prio = -1, /* must come after "directory" */ + .help = "Override default $jobname.$jobnum.$filenum naming", + .def = "$jobname.$jobnum.$filenum", + .category = FIO_OPT_C_FILE, + .group = FIO_OPT_G_FILENAME, + }, { .name = "lockfile", .lname = "Lockfile", .type = FIO_OPT_STR, - .cb = str_lockfile_cb, .off1 = td_var_offset(file_lock_mode), .help = "Lock file when doing IO to it", .parent = "filename", @@ -1290,6 +1318,11 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .ival = "vsync", .help = "Use readv/writev", }, +#ifdef CONFIG_PWRITEV + { .ival = "pvsync", + .help = "Use preadv/pwritev", + }, +#endif #ifdef CONFIG_LIBAIO { .ival = "libaio", .help = "Linux native asynchronous IO", @@ -1481,6 +1514,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_INVALID, }, + { + .name = "number_ios", + .lname = "Number of IOs to perform", + .type = FIO_OPT_STR_VAL, + .off1 = td_var_offset(number_ios), + .help = "Force job completion of this number of IOs", + .def = "0", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_INVALID, + }, { .name = "bs", .lname = "Block size", @@ -1556,6 +1599,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_INVALID, }, + { + .name = "bs_is_seq_rand", + .lname = "Block size division is seq/random (not read/write)", + .type = FIO_OPT_BOOL, + .off1 = td_var_offset(bs_is_seq_rand), + .help = "Consider any blocksize setting to be sequential,ramdom", + .def = "0", + .parent = "blocksize", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_INVALID, + }, { .name = "randrepeat", .lname = "Random repeatable", @@ -1647,6 +1701,28 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_RANDOM, }, + { + .name = "percentage_random", + .lname = "Percentage Random", + .type = FIO_OPT_INT, + .off1 = td_var_offset(perc_rand[DDIR_READ]), + .off2 = td_var_offset(perc_rand[DDIR_WRITE]), + .off3 = td_var_offset(perc_rand[DDIR_TRIM]), + .maxval = 100, + .help = "Percentage of seq/random mix that should be random", + .def = "100,100,100", + .interval = 5, + .inverse = "percentage_sequential", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_RANDOM, + }, + { + .name = "percentage_sequential", + .lname = "Percentage Sequential", + .type = FIO_OPT_DEPRECATED, + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_RANDOM, + }, { .name = "nrfiles", .lname = "Number of files", @@ -2358,7 +2434,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .lname = "Lock memory", .type = FIO_OPT_STR_VAL, .off1 = td_var_offset(lockmem), - .help = "Lock down this amount of memory", + .help = "Lock down this amount of memory (per worker)", .def = "0", .interval = 1024 * 1024, .category = FIO_OPT_C_GENERAL, @@ -2635,12 +2711,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .type = FIO_OPT_STR, .cb = str_numa_cpunodes_cb, .help = "NUMA CPU nodes bind", + .category = FIO_OPT_C_GENERAL, + .group = FIO_OPT_G_INVALID, }, { .name = "numa_mem_policy", .type = FIO_OPT_STR, .cb = str_numa_mpol_cb, .help = "NUMA memory policy setup", + .category = FIO_OPT_C_GENERAL, + .group = FIO_OPT_G_INVALID, }, #endif { @@ -2731,7 +2811,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .name = "write_iops_log", .lname = "Write IOPS log", - .type = FIO_OPT_STR, + .type = FIO_OPT_STR_STORE, .off1 = td_var_offset(iops_log_file), .help = "Write log of IOPS during run", .category = FIO_OPT_C_LOG, @@ -2777,10 +2857,9 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .name = "group_reporting", .lname = "Group reporting", - .type = FIO_OPT_BOOL, + .type = FIO_OPT_STR_SET, .off1 = td_var_offset(group_reporting), .help = "Do reporting on a per-group basis", - .def = "1", .category = FIO_OPT_C_STAT, .group = FIO_OPT_G_INVALID, }, @@ -3077,13 +3156,46 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .lname = "KB Base", .type = FIO_OPT_INT, .off1 = td_var_offset(kb_base), - .verify = kb_base_verify, .prio = 1, .def = "1024", + .posval = { + { .ival = "1024", + .oval = 1024, + .help = "Use 1024 as the K base", + }, + { .ival = "1000", + .oval = 1000, + .help = "Use 1000 as the K base", + }, + }, .help = "How many bytes per KB for reporting (1000 or 1024)", .category = FIO_OPT_C_GENERAL, .group = FIO_OPT_G_INVALID, }, + { + .name = "unit_base", + .lname = "Base unit for reporting (Bits or Bytes)", + .type = FIO_OPT_INT, + .off1 = td_var_offset(unit_base), + .prio = 1, + .posval = { + { .ival = "0", + .oval = 0, + .help = "Auto-detect", + }, + { .ival = "8", + .oval = 8, + .help = "Normal (byte based)", + }, + { .ival = "1", + .oval = 1, + .help = "Bit based", + }, + }, + .help = "Bit multiple of result summary data (8 for byte, 1 for bit)", + .category = FIO_OPT_C_GENERAL, + .group = FIO_OPT_G_INVALID, + }, { .name = "hugepage-size", .lname = "Hugepage size", @@ -3491,7 +3603,7 @@ int fio_cmd_option_parse(struct thread_data *td, const char *opt, char *val) int fio_cmd_ioengine_option_parse(struct thread_data *td, const char *opt, char *val) { - return parse_cmd_option(opt, val, td->io_ops->options, td); + return parse_cmd_option(opt, val, td->io_ops->options, td->eo); } void fio_fill_default_options(struct thread_data *td)