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--;
}
{ .keyword = NULL, },
};
-static char *make_filename(char *buf, struct thread_options *o,
+static char *make_filename(char *buf, size_t buf_size,struct thread_options *o,
const char *jobname, int jobnum, int filenum)
{
struct fpre_keyword *f;
for (f = &fpre_keywords[0]; f->keyword; f++)
f->strlen = strlen(f->keyword);
- strcpy(buf, o->filename_format);
+ buf[buf_size - 1] = '\0';
+ strncpy(buf, o->filename_format, buf_size - 1);
+
memset(copy, 0, sizeof(copy));
for (f = &fpre_keywords[0]; f->keyword; f++) {
do {
if (post_start)
strncpy(dst, buf + post_start, dst_left);
- strcpy(buf, copy);
+ strncpy(buf, copy, buf_size - 1);
} while (1);
}
add_file(td, jobname, job_add_num, 0);
else {
for (i = 0; i < o->nr_files; i++)
- add_file(td, make_filename(fname, o, jobname, job_add_num, i), job_add_num, 0);
+ add_file(td, make_filename(fname, sizeof(fname), o, jobname, job_add_num, i), job_add_num, 0);
}
}
*/
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;
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)