X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=init.c;h=a4b5adb8e2f30bf7e20100b34db12cd4b8a8a341;hp=3c925a31616e27f9b1f94489dff5866092271566;hb=44bb11426e9fe13c509594bc205e4b61225e7483;hpb=d694a6a7c02f577b2bb5d0ad24331b775acf6869 diff --git a/init.c b/init.c index 3c925a31..a4b5adb8 100644 --- a/init.c +++ b/init.c @@ -40,7 +40,6 @@ const char fio_version_string[] = FIO_VERSION; 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; @@ -93,11 +92,6 @@ static struct option l_opts[FIO_NR_OPTIONS] = { .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, @@ -362,10 +356,12 @@ static int setup_thread_area(void) 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(); @@ -373,14 +369,6 @@ static int setup_thread_area(void) 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; @@ -446,15 +434,13 @@ static void copy_opt_list(struct thread_data *dst, struct thread_data *src) /* * 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; @@ -473,6 +459,7 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent, copy_opt_list(td, parent); td->io_ops = NULL; + td->io_ops_init = 0; if (!preserve_eo) td->eo = NULL; @@ -492,7 +479,6 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent, if (!parent->o.group_reporting || parent == &def_thread) stat_number++; - set_cmd_options(td); return td; } @@ -537,7 +523,7 @@ static int __setup_rate(struct thread_data *td, enum fio_ddir ddir) 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; } @@ -581,6 +567,17 @@ static unsigned long long get_rand_start_delay(struct thread_data *td) 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. @@ -590,7 +587,7 @@ static int fixup_options(struct thread_data *td) 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'" @@ -623,7 +620,7 @@ static int fixup_options(struct thread_data *td) /* * 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]) @@ -756,10 +753,20 @@ static int fixup_options(struct thread_data *td) 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"); @@ -902,9 +909,9 @@ void td_fill_verify_state_seed(struct thread_data *td) 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); @@ -926,7 +933,9 @@ static void td_fill_rand_seeds_internal(struct thread_data *td, bool 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); @@ -958,9 +967,9 @@ void td_fill_rand_seeds(struct thread_data *td) } 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); @@ -1017,7 +1026,7 @@ int ioengine_load(struct thread_data *td) */ 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); @@ -1061,6 +1070,9 @@ static void init_flags(struct thread_data *td) 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) @@ -1068,8 +1080,12 @@ 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++) @@ -1111,7 +1127,7 @@ static char *make_filename(char *buf, size_t buf_size,struct thread_options *o, 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++) @@ -1348,6 +1364,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, 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; @@ -1364,7 +1381,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, prev_group_jobs++; if (setup_random_seeds(td)) { - td_verror(td, errno, "init_random_state"); + td_verror(td, errno, "setup_random_seeds"); goto err; } @@ -1525,10 +1542,10 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, 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", @@ -1554,7 +1571,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, */ 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; @@ -1615,11 +1632,11 @@ void add_job_opts(const char **o, int client_type) 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); @@ -1671,7 +1688,7 @@ static int __parse_jobs_ini(struct thread_data *td, 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; @@ -1780,7 +1797,7 @@ static int __parse_jobs_ini(struct thread_data *td, 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; @@ -1984,6 +2001,11 @@ static void show_debug_categories(void) #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); @@ -1992,15 +2014,15 @@ static void usage(const char *name) 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=x\tOutput format (terse,json,json+,normal)\n"); - printf(" --terse-version=x\tSet terse version output format to 'x'\n"); + printf(" --output-format=type\tOutput format (terse,json,json+,normal)\n"); + printf(" --terse-version=type\tSet terse version output format" + " (default 3, or 2 or 4)\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\t\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" @@ -2016,14 +2038,15 @@ static void usage(const char *name) printf(" 't' period passed\n"); printf(" --readonly\t\tTurn on safety read-only checks, preventing" " writes\n"); - printf(" --section=name\tOnly run specified section in job file\n"); + printf(" --section=name\tOnly run specified section in job file," + " multiple sections can be specified\n"); printf(" --alloc-size=kb\tSet smalloc pool to this size in kb" - " (def 1024)\n"); + " (def 16384)\n"); printf(" --warnings-fatal\tFio parser warnings are fatal\n"); printf(" --max-jobs=nr\t\tMaximum number of threads/processes to support\n"); printf(" --server=args\t\tStart a backend fio server\n"); printf(" --daemonize=pidfile\tBackground fio server, write pid to file\n"); - printf(" --client=hostname\tTalk to remote backend fio server at hostname\n"); + printf(" --client=hostname\tTalk to remote backend(s) fio server at hostname\n"); printf(" --remote-config=file\tTell fio server to load this local job file\n"); printf(" --idle-prof=option\tReport cpu idleness on a system or percpu basis\n" "\t\t\t(option=system,percpu) or run unit work\n" @@ -2306,13 +2329,6 @@ int parse_cmd_line(int argc, char *argv[], int client_type) 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++; @@ -2321,17 +2337,22 @@ int parse_cmd_line(int argc, char *argv[], int client_type) 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; @@ -2383,8 +2404,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) 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++; @@ -2465,7 +2485,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) 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); @@ -2703,7 +2723,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) if (!ret) { ret = add_job(td, td->o.name ?: "fio", 0, 0, client_type); if (ret) - did_arg = 1; + exit(1); } } @@ -2715,9 +2735,6 @@ int parse_cmd_line(int argc, char *argv[], int client_type) } out_free: - if (pid_file) - free(pid_file); - return ini_idx; } @@ -2786,7 +2803,7 @@ int parse_options(int argc, char *argv[]) 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]);