int read_only = 0;
int status_interval = 0;
-static int write_lat_log;
-
static int prev_group_jobs;
unsigned long fio_debug = 0;
void free_threads_shm(void)
{
- struct shmid_ds sbuf;
-
if (threads) {
void *tp = threads;
+#ifndef CONFIG_NO_SHM
+ struct shmid_ds sbuf;
threads = NULL;
shmdt(tp);
shmctl(shm_id, IPC_RMID, &sbuf);
shm_id = -1;
+#else
+ threads = NULL;
+ free(tp);
+#endif
}
}
size += file_hash_size;
size += sizeof(unsigned int);
+#ifndef CONFIG_NO_SHM
shm_id = shmget(0, size, IPC_CREAT | 0600);
if (shm_id != -1)
break;
perror("shmget");
break;
}
+#else
+ threads = malloc(size);
+ if (threads)
+ break;
+#endif
max_jobs >>= 1;
} while (max_jobs);
+#ifndef CONFIG_NO_SHM
if (shm_id == -1)
return 1;
perror("shmat");
return 1;
}
+#endif
memset(threads, 0, max_jobs * sizeof(struct thread_data));
hash = (void *) threads + max_jobs * sizeof(struct thread_data);
* Return a free job structure.
*/
static struct thread_data *get_new_job(int global, struct thread_data *parent,
- int preserve_eo)
+ int preserve_eo, const char *jobname)
{
struct thread_data *td;
td->thread_number = thread_number;
+ if (jobname)
+ td->o.name = strdup(jobname);
+
if (!parent->o.group_reporting)
stat_number++;
if (td->io_ops)
free_ioengine(td);
+ if (td->o.name)
+ free(td->o.name);
+
memset(&threads[td->thread_number - 1], 0, sizeof(*td));
thread_number--;
}
char fname[PATH_MAX];
int numjobs, file_alloced;
struct thread_options *o = &td->o;
+ char logname[PATH_MAX + 32];
/*
* the def_thread is just for options, it's not a real job
if (setup_rate(td))
goto err;
- if (o->lat_log_file || write_lat_log) {
- setup_log(&td->lat_log, o->log_avg_msec, IO_LOG_TYPE_LAT);
- setup_log(&td->slat_log, o->log_avg_msec, IO_LOG_TYPE_SLAT);
- setup_log(&td->clat_log, o->log_avg_msec, IO_LOG_TYPE_CLAT);
+ if (o->lat_log_file) {
+ snprintf(logname, sizeof(logname), "%s_lat.log", o->lat_log_file);
+ setup_log(&td->lat_log, o->log_avg_msec, IO_LOG_TYPE_LAT,
+ o->log_offset, logname);
+ snprintf(logname, sizeof(logname), "%s_slat.log", o->lat_log_file);
+ setup_log(&td->slat_log, o->log_avg_msec, IO_LOG_TYPE_SLAT,
+ o->log_offset, logname);
+ snprintf(logname, sizeof(logname), "%s_clat.log", o->lat_log_file);
+ setup_log(&td->clat_log, o->log_avg_msec, IO_LOG_TYPE_CLAT,
+ o->log_offset, logname);
+ }
+ if (o->bw_log_file) {
+ snprintf(logname, sizeof(logname), "%s_bw.log", o->bw_log_file);
+ setup_log(&td->bw_log, o->log_avg_msec, IO_LOG_TYPE_BW,
+ o->log_offset, logname);
+ }
+ if (o->iops_log_file) {
+ snprintf(logname, sizeof(logname), "%s_iops.log", o->iops_log_file);
+ setup_log(&td->iops_log, o->log_avg_msec, IO_LOG_TYPE_IOPS,
+ o->log_offset, logname);
}
- if (o->bw_log_file || write_bw_log)
- setup_log(&td->bw_log, o->log_avg_msec, IO_LOG_TYPE_BW);
- if (o->iops_log_file)
- setup_log(&td->iops_log, o->log_avg_msec, IO_LOG_TYPE_IOPS);
if (!o->name)
o->name = strdup(jobname);
*/
numjobs = o->numjobs;
while (--numjobs) {
- struct thread_data *td_new = get_new_job(0, td, 1);
+ struct thread_data *td_new = get_new_job(0, td, 1, 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);
+ td_parent = get_new_job(1, &def_thread, 0, jobname);
else if (!in_global && !td) {
if (!td_parent)
td_parent = &def_thread;
- td = get_new_job(0, td_parent, 0);
+ td = get_new_job(0, td_parent, 0, jobname);
}
if (in_global)
fio_options_parse(td_parent, (char **) &o[i], 1, 0);
first_sect = 0;
}
- td = get_new_job(global, &def_thread, 0);
+ td = get_new_job(global, &def_thread, 0, name);
if (!td) {
ret = 1;
break;
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(" --latency-log\t\tGenerate per-job latency logs\n");
printf(" --bandwidth-log\tGenerate per-job bandwidth logs\n");
printf(" --minimal\t\tMinimal (terse) output\n");
printf(" --output-format=x\tOutput format (terse,json,normal)\n");
}
break;
case 'l':
- write_lat_log = 1;
+ log_err("fio: --latency-log is deprecated. Use per-job latency log options.\n");
+ do_exit++;
+ exit_val = 1;
break;
case 'b':
write_bw_log = 1;
break;
case 'o':
- if (f_out)
+ if (f_out && f_out != stdout)
fclose(f_out);
f_out = fopen(optarg, "w+");
if (is_section && skip_this_section(val))
continue;
- td = get_new_job(global, &def_thread, 1);
- if (!td || ioengine_load(td))
- goto out_free;
+ td = get_new_job(global, &def_thread, 1, NULL);
+ if (!td || ioengine_load(td)) {
+ if (td) {
+ put_job(td);
+ td = NULL;
+ }
+ do_exit++;
+ break;
+ }
fio_options_set_ioengine_opts(l_opts, td);
}
if (!ret && !strcmp(opt, "ioengine")) {
free_ioengine(td);
- if (ioengine_load(td))
- goto out_free;
+ if (ioengine_load(td)) {
+ if (td) {
+ put_job(td);
+ td = NULL;
+ }
+ do_exit++;
+ break;
+ }
fio_options_set_ioengine_opts(l_opts, td);
}
break;
break;
ret = fio_cmd_ioengine_option_parse(td, opt, val);
- did_arg = 1;
break;
}
case 'w':
break;
case 'S':
did_arg = 1;
+#ifndef CONFIG_NO_SHM
if (nr_clients) {
log_err("fio: can't be both client and server\n");
do_exit++;
fio_server_set_arg(optarg);
is_backend = 1;
backend = 1;
+#else
+ log_err("fio: client/server requires SHM support\n");
+ do_exit++;
+ exit_val = 1;
+#endif
break;
case 'D':
if (pid_file)