static char **ini_file;
static int max_jobs = FIO_MAX_JOBS;
static int dump_cmdline;
-static long long def_timeout;
static int parse_only;
static struct thread_data def_thread;
.has_arg = required_argument,
.val = 'o' | FIO_CLIENT_FLAG,
},
- {
- .name = (char *) "timeout",
- .has_arg = required_argument,
- .val = 't' | FIO_CLIENT_FLAG,
- },
{
.name = (char *) "latency-log",
.has_arg = required_argument,
perror("shmat");
return 1;
}
+ if (shm_attach_to_open_removed())
+ shmctl(shm_id, IPC_RMID, NULL);
#endif
memset(threads, 0, max_jobs * sizeof(struct thread_data));
- fio_debug_jobp = (void *) threads + max_jobs * sizeof(struct thread_data);
+ fio_debug_jobp = (unsigned int *)(threads + max_jobs);
*fio_debug_jobp = -1;
flow_init();
return 0;
}
-static void set_cmd_options(struct thread_data *td)
-{
- struct thread_options *o = &td->o;
-
- if (!o->timeout)
- o->timeout = def_timeout;
-}
-
static void dump_print_option(struct print_option *p)
{
const char *delim;
/*
* Return a free job structure.
*/
-static struct thread_data *get_new_job(int global, struct thread_data *parent,
- int preserve_eo, const char *jobname)
+static struct thread_data *get_new_job(bool global, struct thread_data *parent,
+ bool preserve_eo, const char *jobname)
{
struct thread_data *td;
- if (global) {
- set_cmd_options(&def_thread);
+ if (global)
return &def_thread;
- }
if (setup_thread_area()) {
log_err("error: failed to setup shm segment\n");
return NULL;
copy_opt_list(td, parent);
td->io_ops = NULL;
+ td->io_ops_init = 0;
if (!preserve_eo)
td->eo = NULL;
if (!parent->o.group_reporting || parent == &def_thread)
stat_number++;
- set_cmd_options(td);
return td;
}
td->rate_next_io_time[ddir] = 0;
td->rate_io_issue_bytes[ddir] = 0;
- td->last_usec = 0;
+ td->last_usec[ddir] = 0;
return 0;
}
return delayrange;
}
+/*
+ * <3 Johannes
+ */
+static unsigned int gcd(unsigned int m, unsigned int n)
+{
+ if (!n)
+ return m;
+
+ return gcd(n, m % n);
+}
+
/*
* Lazy way of fixing up options that depend on each other. We could also
* define option callback handlers, but this is easier.
struct thread_options *o = &td->o;
int ret = 0;
-#ifndef FIO_HAVE_PSHARED_MUTEX
+#ifndef CONFIG_PSHARED
if (!o->use_thread) {
log_info("fio: this platform does not support process shared"
" mutexes, forcing use of threads. Use the 'thread'"
/*
* Reads can do overwrites, we always need to pre-create the file
*/
- if (td_read(td) || td_rw(td))
+ if (td_read(td))
o->overwrite = 1;
if (!o->min_bs[DDIR_READ])
o->verify_interval = o->min_bs[DDIR_WRITE];
else if (td_read(td) && o->verify_interval > o->min_bs[DDIR_READ])
o->verify_interval = o->min_bs[DDIR_READ];
+
+ /*
+ * Verify interval must be a factor or both min and max
+ * write size
+ */
+ if (o->verify_interval % o->min_bs[DDIR_WRITE] ||
+ o->verify_interval % o->max_bs[DDIR_WRITE])
+ o->verify_interval = gcd(o->min_bs[DDIR_WRITE],
+ o->max_bs[DDIR_WRITE]);
}
if (o->pre_read) {
- o->invalidate_cache = 0;
+ if (o->invalidate_cache)
+ o->invalidate_cache = 0;
if (td_ioengine_flagged(td, FIO_PIPEIO)) {
log_info("fio: cannot pre-read files with an IO engine"
" that isn't seekable. Pre-read disabled.\n");
bool use64;
if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64)
- use64 = 1;
+ use64 = true;
else
- use64 = 0;
+ use64 = false;
init_rand_seed(&td->verify_state, td->rand_seeds[FIO_RAND_VER_OFF],
use64);
init_rand_seed(&td->file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF], use64);
init_rand_seed(&td->trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF], use64);
init_rand_seed(&td->delay_state, td->rand_seeds[FIO_RAND_START_DELAY], use64);
- init_rand_seed(&td->poisson_state, td->rand_seeds[FIO_RAND_POISSON_OFF], 0);
+ init_rand_seed(&td->poisson_state[0], td->rand_seeds[FIO_RAND_POISSON_OFF], 0);
+ init_rand_seed(&td->poisson_state[1], td->rand_seeds[FIO_RAND_POISSON2_OFF], 0);
+ init_rand_seed(&td->poisson_state[2], td->rand_seeds[FIO_RAND_POISSON3_OFF], 0);
init_rand_seed(&td->dedupe_state, td->rand_seeds[FIO_DEDUPE_OFF], false);
init_rand_seed(&td->zone_state, td->rand_seeds[FIO_RAND_ZONE_OFF], false);
}
if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64)
- use64 = 1;
+ use64 = true;
else
- use64 = 0;
+ use64 = false;
td_fill_rand_seeds_internal(td, use64);
*/
if (origeo) {
memcpy(td->eo, origeo, td->io_ops->option_struct_size);
- options_mem_dupe(td->eo, td->io_ops->options);
+ options_mem_dupe(td->io_ops->options, td->eo);
} else {
memset(td->eo, 0, td->io_ops->option_struct_size);
fill_default_options(td->eo, td->io_ops->options);
if (o->verify_async || o->io_submit_mode == IO_MODE_OFFLOAD)
td->flags |= TD_F_NEED_LOCK;
+
+ if (o->mem_type == MEM_CUDA_MALLOC)
+ td->flags &= ~TD_F_SCRAMBLE_BUFFERS;
}
static int setup_random_seeds(struct thread_data *td)
unsigned long seed;
unsigned int i;
- if (!td->o.rand_repeatable && !fio_option_is_set(&td->o, rand_seed))
- return init_random_state(td, td->rand_seeds, sizeof(td->rand_seeds));
+ if (!td->o.rand_repeatable && !fio_option_is_set(&td->o, rand_seed)) {
+ int ret = init_random_seeds(td->rand_seeds, sizeof(td->rand_seeds));
+ if (!ret)
+ td_fill_rand_seeds(td);
+ return ret;
+ }
seed = td->o.rand_seed;
for (i = 0; i < 4; i++)
if (!o->filename_format || !strlen(o->filename_format)) {
sprintf(buf, "%s.%d.%d", jobname, jobnum, filenum);
- return NULL;
+ return buf;
}
for (f = &fpre_keywords[0]; f->keyword; f++)
td->ts.slat_stat[i].min_val = ULONG_MAX;
td->ts.lat_stat[i].min_val = ULONG_MAX;
td->ts.bw_stat[i].min_val = ULONG_MAX;
+ td->ts.iops_stat[i].min_val = ULONG_MAX;
}
td->ddir_seq_nr = o->ddir_seq_nr;
prev_group_jobs++;
if (setup_random_seeds(td)) {
- td_verror(td, errno, "init_random_state");
+ td_verror(td, errno, "setup_random_seeds");
goto err;
}
ddir_str(o->td_ddir));
if (o->bs_is_seq_rand)
- log_info("bs=%s-%s,%s-%s, bs_is_seq_rand, ",
+ log_info("bs=(R) %s-%s, (W) %s-%s, bs_is_seq_rand, ",
c1, c2, c3, c4);
else
- log_info("bs=%s-%s,%s-%s,%s-%s, ",
+ log_info("bs=(R) %s-%s, (W) %s-%s, (T) %s-%s, ",
c1, c2, c3, c4, c5, c6);
log_info("ioengine=%s, iodepth=%u\n",
*/
numjobs = o->numjobs;
while (--numjobs) {
- struct thread_data *td_new = get_new_job(0, td, 1, jobname);
+ struct thread_data *td_new = get_new_job(false, td, true, jobname);
if (!td_new)
goto err;
sprintf(jobname, "%s", o[i] + 5);
}
if (in_global && !td_parent)
- td_parent = get_new_job(1, &def_thread, 0, jobname);
+ td_parent = get_new_job(true, &def_thread, false, jobname);
else if (!in_global && !td) {
if (!td_parent)
td_parent = &def_thread;
- td = get_new_job(0, td_parent, 0, jobname);
+ td = get_new_job(false, td_parent, false, jobname);
}
if (in_global)
fio_options_parse(td_parent, (char **) &o[i], 1);
char *file, int is_buf, int stonewall_flag, int type,
int nested, char *name, char ***popts, int *aopts, int *nopts)
{
- unsigned int global = 0;
+ bool global = false;
char *string;
FILE *f;
char *p;
first_sect = 0;
}
- td = get_new_job(global, &def_thread, 0, name);
+ td = get_new_job(global, &def_thread, false, name);
if (!td) {
ret = 1;
break;
#endif
}
+/*
+ * Following options aren't printed by usage().
+ * --append-terse - Equivalent to --output-format=terse, see f6a7df53.
+ * --latency-log - Deprecated option.
+ */
static void usage(const char *name)
{
printf("%s\n", fio_version_string);
show_debug_categories();
printf(" --parse-only\t\tParse options only, don't start any IO\n");
printf(" --output\t\tWrite output to file\n");
- printf(" --runtime\t\tRuntime in seconds\n");
printf(" --bandwidth-log\tGenerate aggregate bandwidth logs\n");
printf(" --minimal\t\tMinimal (terse) output\n");
printf(" --output-format=type\tOutput format (terse,json,json+,normal)\n");
printf(" --version\t\tPrint version info and exit\n");
printf(" --help\t\tPrint this page\n");
printf(" --cpuclock-test\tPerform test/validation of CPU clock\n");
- printf(" --crctest=type\tTest speed of checksum functions\n");
+ printf(" --crctest=[type]\tTest speed of checksum functions\n");
printf(" --cmdhelp=cmd\t\tPrint command help, \"all\" for all of"
" them\n");
printf(" --enghelp=engine\tPrint ioengine help, or list"
smalloc_pool_size <<= 10;
sinit();
break;
- case 't':
- if (check_str_time(optarg, &def_timeout, 1)) {
- log_err("fio: failed parsing time %s\n", optarg);
- do_exit++;
- exit_val = 1;
- }
- break;
case 'l':
log_err("fio: --latency-log is deprecated. Use per-job latency log options.\n");
do_exit++;
case 'b':
write_bw_log = 1;
break;
- case 'o':
+ case 'o': {
+ FILE *tmp;
+
if (f_out && f_out != stdout)
fclose(f_out);
- f_out = fopen(optarg, "w+");
- if (!f_out) {
- perror("fopen output");
- exit(1);
+ tmp = fopen(optarg, "w+");
+ if (!tmp) {
+ log_err("fio: output file open error: %s\n", strerror(errno));
+ exit_val = 1;
+ do_exit++;
+ break;
}
- f_err = f_out;
+ f_err = f_out = tmp;
break;
+ }
case 'm':
output_format = FIO_OUTPUT_TERSE;
break;
break;
case 'V':
terse_version = atoi(optarg);
- if (!(terse_version == 2 || terse_version == 3 ||
- terse_version == 4)) {
+ if (!(terse_version >= 2 && terse_version <= 5)) {
log_err("fio: bad terse version format\n");
exit_val = 1;
do_exit++;
if (is_section && skip_this_section(val))
continue;
- td = get_new_job(global, &def_thread, 1, NULL);
+ td = get_new_job(global, &def_thread, true, NULL);
if (!td || ioengine_load(td)) {
if (td) {
put_job(td);
if (!ret) {
ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type);
if (ret)
- did_arg = 1;
+ exit(1);
}
}
}
out_free:
- if (pid_file)
- free(pid_file);
-
return ini_idx;
}
if (did_arg)
return 0;
- log_err("No jobs(s) defined\n\n");
+ log_err("No job(s) defined\n\n");
if (!did_arg) {
usage(argv[0]);