},
{
.name = (char *) "output-format",
- .has_arg = optional_argument,
+ .has_arg = required_argument,
.val = 'F' | FIO_CLIENT_FLAG,
},
{
td->loops = 1;
if (td->o.block_error_hist && td->o.nr_files != 1) {
- log_err("fio: block error histogram only available with "
+ log_err("fio: block error histogram only available "
"with a single file per job, but %d files "
"provided\n", td->o.nr_files);
ret = 1;
return p;
}
-static int exists_and_not_file(const char *filename)
+static int exists_and_not_regfile(const char *filename)
{
struct stat sb;
if (lstat(filename, &sb) == -1)
return 0;
+#ifndef WIN32 /* NOT Windows */
+ if (S_ISREG(sb.st_mode))
+ return 0;
+#else
/* \\.\ is the device namespace in Windows, where every file
* is a device node */
if (S_ISREG(sb.st_mode) && strncmp(filename, "\\\\.\\", 4) != 0)
return 0;
+#endif
return 1;
}
+static void init_rand_file_service(struct thread_data *td)
+{
+ unsigned long nranges = td->o.nr_files << FIO_FSERVICE_SHIFT;
+ 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_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);
+ 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_disable_hash(&td->next_file_gauss);
+ }
+}
+
+void td_fill_verify_state_seed(struct thread_data *td)
+{
+ bool use64;
+
+ if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64)
+ use64 = 1;
+ else
+ use64 = 0;
+
+ init_rand_seed(&td->verify_state, td->rand_seeds[FIO_RAND_VER_OFF],
+ use64);
+}
+
static void td_fill_rand_seeds_internal(struct thread_data *td, bool use64)
{
int i;
init_rand_seed(&td->bsrange_state, td->rand_seeds[FIO_RAND_BS_OFF], use64);
- init_rand_seed(&td->verify_state, td->rand_seeds[FIO_RAND_VER_OFF], use64);
+ td_fill_verify_state_seed(td);
init_rand_seed(&td->rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF], false);
if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
init_rand_seed(&td->next_file_state, td->rand_seeds[FIO_RAND_FILE_OFF], use64);
- else if (td->o.file_service_type & __FIO_FSERVICE_NONUNIFORM) {
- unsigned long nranges;
-
- nranges = td->o.nr_files << FIO_FSERVICE_SHIFT;
-
- if (td->o.file_service_type == FIO_FSERVICE_ZIPF) {
- zipf_init(&td->next_file_zipf, nranges, td->zipf_theta, td->rand_seeds[FIO_RAND_FILE_OFF]);
- 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, td->rand_seeds[FIO_RAND_FILE_OFF]);
- 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, td->rand_seeds[FIO_RAND_FILE_OFF]);
- gauss_disable_hash(&td->next_file_gauss);
- }
- }
+ else if (td->o.file_service_type & __FIO_FSERVICE_NONUNIFORM)
+ init_rand_file_service(td);
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);
if (!o->filename && !td->files_index && !o->read_iolog_file) {
file_alloced = 1;
- if (o->nr_files == 1 && exists_and_not_file(jobname))
+ if (o->nr_files == 1 && exists_and_not_regfile(jobname))
add_file(td, jobname, job_add_num, 0);
else {
for (i = 0; i < o->nr_files; i++)
struct log_params p = {
.td = td,
.avg_msec = o->log_avg_msec,
+ .hist_msec = o->log_hist_msec,
+ .hist_coarseness = o->log_hist_coarseness,
.log_type = IO_LOG_TYPE_LAT,
.log_offset = o->log_offset,
.log_gz = o->log_gz,
td->thread_number, suf, o->per_job_logs);
setup_log(&td->clat_log, &p, logname);
}
+
+ if (o->hist_log_file) {
+ struct log_params p = {
+ .td = td,
+ .avg_msec = o->log_avg_msec,
+ .hist_msec = o->log_hist_msec,
+ .hist_coarseness = o->log_hist_coarseness,
+ .log_type = IO_LOG_TYPE_HIST,
+ .log_offset = o->log_offset,
+ .log_gz = o->log_gz,
+ .log_gz_store = o->log_gz_store,
+ };
+ const char *suf;
+
+ if (p.log_gz_store)
+ suf = "log.fz";
+ else
+ suf = "log";
+
+ gen_log_name(logname, sizeof(logname), "clat_hist", o->hist_log_file,
+ td->thread_number, suf, o->per_job_logs);
+ setup_log(&td->clat_hist_log, &p, logname);
+ }
+
if (o->bw_log_file) {
struct log_params p = {
.td = td,
.avg_msec = o->log_avg_msec,
+ .hist_msec = o->log_hist_msec,
+ .hist_coarseness = o->log_hist_coarseness,
.log_type = IO_LOG_TYPE_BW,
.log_offset = o->log_offset,
.log_gz = o->log_gz,
p.avg_msec = min(o->log_avg_msec, o->bw_avg_time);
else
o->bw_avg_time = p.avg_msec;
+
+ p.hist_msec = o->log_hist_msec;
+ p.hist_coarseness = o->log_hist_coarseness;
if (p.log_gz_store)
suf = "log.fz";
struct log_params p = {
.td = td,
.avg_msec = o->log_avg_msec,
+ .hist_msec = o->log_hist_msec,
+ .hist_coarseness = o->log_hist_coarseness,
.log_type = IO_LOG_TYPE_IOPS,
.log_offset = o->log_offset,
.log_gz = o->log_gz,
p.avg_msec = min(o->log_avg_msec, o->iops_avg_time);
else
o->iops_avg_time = p.avg_msec;
+
+ p.hist_msec = o->log_hist_msec;
+ p.hist_coarseness = o->log_hist_coarseness;
if (p.log_gz_store)
suf = "log.fz";
struct thread_data *td = NULL;
int c, ini_idx = 0, lidx, ret = 0, do_exit = 0, exit_val = 0;
char *ostr = cmd_optstr;
- void *pid_file = NULL;
+ char *pid_file = NULL;
void *cur_client = NULL;
int backend = 0;
output_format = FIO_OUTPUT_TERSE;
break;
case 'F':
- if (!optarg) {
- log_err("fio: missing --output-format argument\n");
- exit_val = 1;
- do_exit++;
- break;
- }
if (parse_output_format(optarg)) {
log_err("fio: failed parsing output-format\n");
exit_val = 1;