X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=init.c;h=07daaa84b17c6318727846e9634919c328fe6a07;hp=c3442849c0900a89ee1e26260682bb5642384989;hb=ef37053efdfb8c3b8b6deef43c0969753e6adb44;hpb=2fbe1e195999e23c95b08d03eadac0b5f95330e7 diff --git a/init.c b/init.c index c3442849..07daaa84 100644 --- a/init.c +++ b/init.c @@ -45,7 +45,6 @@ const char fio_version_string[] = FIO_VERSION; #define FIO_RANDSEED (0xb1899bedUL) static char **ini_file; -static int max_jobs = FIO_MAX_JOBS; static bool dump_cmdline; static bool parse_only; static bool merge_blktrace_only; @@ -328,6 +327,7 @@ void free_threads_shm(void) static void free_shm(void) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (nr_segments) { flow_exit(); fio_debug_jobp = NULL; @@ -344,6 +344,7 @@ static void free_shm(void) fio_filelock_exit(); file_hash_exit(); scleanup(); +#endif } static int add_thread_segment(void) @@ -352,8 +353,10 @@ static int add_thread_segment(void) size_t size = JOBS_PER_SEG * sizeof(struct thread_data); int i; - if (nr_segments + 1 >= REAL_MAX_SEG) + if (nr_segments + 1 >= REAL_MAX_SEG) { + log_err("error: maximum number of jobs reached.\n"); return -1; + } size += 2 * sizeof(unsigned int); @@ -445,19 +448,6 @@ static void dump_opt_list(struct thread_data *td) } } -static void fio_dump_options_free(struct thread_data *td) -{ - while (!flist_empty(&td->opt_list)) { - struct print_option *p; - - p = flist_first_entry(&td->opt_list, struct print_option, list); - flist_del_init(&p->list); - free(p->name); - free(p->value); - free(p); - } -} - static void copy_opt_list(struct thread_data *dst, struct thread_data *src) { struct flist_head *entry; @@ -494,11 +484,6 @@ static struct thread_data *get_new_job(bool global, struct thread_data *parent, log_err("error: failed to setup shm segment\n"); return NULL; } - if (thread_number >= max_jobs) { - log_err("error: maximum number of jobs (%d) reached.\n", - max_jobs); - return NULL; - } seg = &segments[cur_segment]; td = &seg->threads[seg->nr_threads++]; @@ -648,6 +633,11 @@ static int fixup_options(struct thread_data *td) ret |= 1; } + if (o->zone_mode == ZONE_MODE_ZBD && !o->create_serialize) { + log_err("fio: --zonemode=zbd and --create_serialize=0 are not compatible.\n"); + ret |= 1; + } + if (o->zone_mode == ZONE_MODE_STRIDED && !o->zone_size) { log_err("fio: --zonesize must be specified when using --zonemode=strided.\n"); ret |= 1; @@ -963,9 +953,33 @@ static int fixup_options(struct thread_data *td) /* * Fix these up to be nsec internally */ - o->max_latency *= 1000ULL; + for_each_rw_ddir(ddir) + o->max_latency[ddir] *= 1000ULL; + o->latency_target *= 1000ULL; + /* + * Dedupe working set verifications + */ + if (o->dedupe_percentage && o->dedupe_mode == DEDUPE_MODE_WORKING_SET) { + if (!fio_option_is_set(o, size)) { + log_err("fio: pregenerated dedupe working set " + "requires size to be set\n"); + ret |= 1; + } else if (o->nr_files != 1) { + log_err("fio: dedupe working set mode supported with " + "single file per job, but %d files " + "provided\n", o->nr_files); + ret |= 1; + } else if (o->dedupe_working_set_percentage + o->dedupe_percentage > 100) { + log_err("fio: impossible to reach expected dedupe percentage %u " + "since %u percentage of size is reserved to dedupe working set " + "(those are unique pages)\n", + o->dedupe_percentage, o->dedupe_working_set_percentage); + ret |= 1; + } + } + return ret; } @@ -975,13 +989,13 @@ static void init_rand_file_service(struct thread_data *td) const unsigned int seed = td->rand_seeds[FIO_RAND_FILE_OFF]; if (td->o.file_service_type == FIO_FSERVICE_ZIPF) { - zipf_init(&td->next_file_zipf, nranges, td->zipf_theta, seed); + zipf_init(&td->next_file_zipf, nranges, td->zipf_theta, td->random_center, seed); zipf_disable_hash(&td->next_file_zipf); } else if (td->o.file_service_type == FIO_FSERVICE_PARETO) { - pareto_init(&td->next_file_zipf, nranges, td->pareto_h, seed); + pareto_init(&td->next_file_zipf, nranges, td->pareto_h, td->random_center, seed); zipf_disable_hash(&td->next_file_zipf); } else if (td->o.file_service_type == FIO_FSERVICE_GAUSS) { - gauss_init(&td->next_file_gauss, nranges, td->gauss_dev, seed); + gauss_init(&td->next_file_gauss, nranges, td->gauss_dev, td->random_center, seed); gauss_disable_hash(&td->next_file_gauss); } } @@ -1039,6 +1053,7 @@ static void td_fill_rand_seeds_internal(struct thread_data *td, bool use64) 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); init_rand_seed(&td->prio_state, td->rand_seeds[FIO_RAND_PRIO_CMDS], false); + init_rand_seed(&td->dedupe_working_set_index_state, td->rand_seeds[FIO_RAND_DEDUPE_WORKING_SET_IX], use64); if (!td_random(td)) return; @@ -1106,18 +1121,15 @@ int ioengine_load(struct thread_data *td) * for this name and see if they match. If they do, then * the engine is unchanged. */ - dlhandle = td->io_ops_dlhandle; + dlhandle = td->io_ops->dlhandle; ops = load_ioengine(td); if (!ops) goto fail; - if (ops == td->io_ops && dlhandle == td->io_ops_dlhandle) { - if (dlhandle) - dlclose(dlhandle); + if (ops == td->io_ops && dlhandle == td->io_ops->dlhandle) return 0; - } - if (dlhandle && dlhandle != td->io_ops_dlhandle) + if (dlhandle && dlhandle != td->io_ops->dlhandle) dlclose(dlhandle); /* Unload the old engine. */ @@ -1243,7 +1255,8 @@ enum { FPRE_NONE = 0, FPRE_JOBNAME, FPRE_JOBNUM, - FPRE_FILENUM + FPRE_FILENUM, + FPRE_CLIENTUID }; static struct fpre_keyword { @@ -1254,6 +1267,7 @@ static struct fpre_keyword { { .keyword = "$jobname", .key = FPRE_JOBNAME, }, { .keyword = "$jobnum", .key = FPRE_JOBNUM, }, { .keyword = "$filenum", .key = FPRE_FILENUM, }, + { .keyword = "$clientuid", .key = FPRE_CLIENTUID, }, { .keyword = NULL, }, }; @@ -1343,6 +1357,21 @@ static char *make_filename(char *buf, size_t buf_size,struct thread_options *o, } break; } + case FPRE_CLIENTUID: { + int ret; + ret = snprintf(dst, dst_left, "%s", client_sockaddr_str); + if (ret < 0) + break; + else if (ret > dst_left) { + log_err("fio: truncated filename\n"); + dst += dst_left; + dst_left = 0; + } else { + dst += ret; + dst_left -= ret; + } + break; + } default: assert(0); break; @@ -1485,6 +1514,9 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, if (fixup_options(td)) goto err; + if (init_dedupe_working_set_seeds(td)) + goto err; + /* * Belongs to fixup_options, but o->name is not necessarily set as yet */ @@ -1516,16 +1548,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, memcpy(td->ts.percentile_list, o->percentile_list, sizeof(o->percentile_list)); td->ts.sig_figs = o->sig_figs; - for (i = 0; i < DDIR_RWDIR_CNT; i++) { - td->ts.clat_stat[i].min_val = ULONG_MAX; - 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->ts.clat_high_prio_stat[i].min_val = ULONG_MAX; - td->ts.clat_low_prio_stat[i].min_val = ULONG_MAX; - } - td->ts.sync_stat.min_val = ULONG_MAX; + init_thread_stat_min_vals(&td->ts); td->ddir_seq_nr = o->ddir_seq_nr; if ((o->stonewall || o->new_group) && prev_group_jobs) { @@ -1551,6 +1574,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, .hist_coarseness = o->log_hist_coarseness, .log_type = IO_LOG_TYPE_LAT, .log_offset = o->log_offset, + .log_prio = o->log_prio, .log_gz = o->log_gz, .log_gz_store = o->log_gz_store, }; @@ -1562,17 +1586,23 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, else suf = "log"; - gen_log_name(logname, sizeof(logname), "lat", pre, - td->thread_number, suf, o->per_job_logs); - setup_log(&td->lat_log, &p, logname); + if (!o->disable_lat) { + gen_log_name(logname, sizeof(logname), "lat", pre, + td->thread_number, suf, o->per_job_logs); + setup_log(&td->lat_log, &p, logname); + } - gen_log_name(logname, sizeof(logname), "slat", pre, - td->thread_number, suf, o->per_job_logs); - setup_log(&td->slat_log, &p, logname); + if (!o->disable_slat) { + gen_log_name(logname, sizeof(logname), "slat", pre, + td->thread_number, suf, o->per_job_logs); + setup_log(&td->slat_log, &p, logname); + } - gen_log_name(logname, sizeof(logname), "clat", pre, - td->thread_number, suf, o->per_job_logs); - setup_log(&td->clat_log, &p, logname); + if (!o->disable_clat) { + gen_log_name(logname, sizeof(logname), "clat", pre, + td->thread_number, suf, o->per_job_logs); + setup_log(&td->clat_log, &p, logname); + } } @@ -1584,6 +1614,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, .hist_coarseness = o->log_hist_coarseness, .log_type = IO_LOG_TYPE_HIST, .log_offset = o->log_offset, + .log_prio = o->log_prio, .log_gz = o->log_gz, .log_gz_store = o->log_gz_store, }; @@ -1615,6 +1646,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, .hist_coarseness = o->log_hist_coarseness, .log_type = IO_LOG_TYPE_BW, .log_offset = o->log_offset, + .log_prio = o->log_prio, .log_gz = o->log_gz, .log_gz_store = o->log_gz_store, }; @@ -1646,6 +1678,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, .hist_coarseness = o->log_hist_coarseness, .log_type = IO_LOG_TYPE_IOPS, .log_offset = o->log_offset, + .log_prio = o->log_prio, .log_gz = o->log_gz, .log_gz_store = o->log_gz_store, }; @@ -2741,12 +2774,7 @@ int parse_cmd_line(int argc, char *argv[], int client_type) warnings_fatal = 1; break; case 'j': - max_jobs = atoi(optarg); - if (!max_jobs || max_jobs > REAL_MAX_JOBS) { - log_err("fio: invalid max jobs: %d\n", max_jobs); - do_exit++; - exit_val = 1; - } + /* we don't track/need this anymore, ignore it */ break; case 'S': did_arg = true;