log_buf(out, "\n");
}
+void json_add_job_opts(struct json_object *root, const char *name,
+ struct flist_head *opt_list, bool num_jobs)
+{
+ struct json_object *dir_object;
+ struct flist_head *entry;
+ struct print_option *p;
+
+ if (flist_empty(opt_list))
+ return;
+
+ dir_object = json_create_object();
+ json_object_add_value_object(root, name, dir_object);
+
+ flist_for_each(entry, opt_list) {
+ const char *pos = "";
+
+ p = flist_entry(entry, struct print_option, list);
+ if (!num_jobs && !strcmp(p->name, "numjobs"))
+ continue;
+ if (p->value)
+ pos = p->value;
+ json_object_add_value_string(dir_object, p->name, pos);
+ }
+}
+
static struct json_object *show_thread_status_json(struct thread_stat *ts,
- struct group_run_stats *rs)
+ struct group_run_stats *rs,
+ struct flist_head *opt_list)
{
struct json_object *root, *tmp;
struct jobs_eta *je;
json_object_add_value_int(root, "elapsed", je->elapsed_sec);
}
+ if (opt_list)
+ json_add_job_opts(root, "job options", opt_list, true);
+
add_ddir_status_json(ts, rs, DDIR_READ, root);
add_ddir_status_json(ts, rs, DDIR_WRITE, root);
add_ddir_status_json(ts, rs, DDIR_TRIM, root);
struct json_object *show_thread_status(struct thread_stat *ts,
struct group_run_stats *rs,
+ struct flist_head *opt_list,
struct buf_output *out)
{
struct json_object *ret = NULL;
if (output_format & FIO_OUTPUT_TERSE)
show_thread_status_terse(ts, rs, out);
if (output_format & FIO_OUTPUT_JSON)
- ret = show_thread_status_json(ts, rs);
+ ret = show_thread_status_json(ts, rs, opt_list);
if (output_format & FIO_OUTPUT_NORMAL)
show_thread_status_normal(ts, rs, out);
struct json_object *root = NULL;
struct json_array *array = NULL;
struct buf_output output[FIO_OUTPUT_NR];
+ struct flist_head **opt_lists;
runstats = malloc(sizeof(struct group_run_stats) * (groupid + 1));
}
threadstats = malloc(nr_ts * sizeof(struct thread_stat));
+ opt_lists = malloc(nr_ts * sizeof(struct flist_head *));
- for (i = 0; i < nr_ts; i++)
+ for (i = 0; i < nr_ts; i++) {
init_thread_stat(&threadstats[i]);
+ opt_lists[i] = NULL;
+ }
j = 0;
last_ts = -1;
ts->clat_percentiles = td->o.clat_percentiles;
ts->percentile_precision = td->o.percentile_precision;
memcpy(ts->percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
+ opt_lists[j] = &td->opt_list;
idx++;
ts->members++;
if (output_format & FIO_OUTPUT_NORMAL)
log_buf(&output[__FIO_OUTPUT_NORMAL], "\n");
if (output_format & FIO_OUTPUT_JSON) {
+ struct thread_data *global;
char time_buf[32];
time_t time_p;
json_object_add_value_string(root, "fio version", fio_version_string);
json_object_add_value_int(root, "timestamp", time_p);
json_object_add_value_string(root, "time", time_buf);
+ global = get_global_options();
+ json_add_job_opts(root, "global options", &global->opt_list, false);
array = json_create_array();
json_object_add_value_array(root, "jobs", array);
}
+ if (is_backend)
+ fio_server_send_job_options(&get_global_options()->opt_list, -1U);
+
for (i = 0; i < nr_ts; i++) {
ts = &threadstats[i];
rs = &runstats[ts->groupid];
- if (is_backend)
+ if (is_backend) {
+ fio_server_send_job_options(opt_lists[i], i);
fio_server_send_ts(ts, rs);
- else {
+ } else {
if (output_format & FIO_OUTPUT_TERSE)
show_thread_status_terse(ts, rs, &output[__FIO_OUTPUT_TERSE]);
if (output_format & FIO_OUTPUT_JSON) {
- struct json_object *tmp = show_thread_status_json(ts, rs);
+ struct json_object *tmp = show_thread_status_json(ts, rs, opt_lists[i]);
json_array_add_value_object(array, tmp);
}
if (output_format & FIO_OUTPUT_NORMAL)
log_info_flush();
free(runstats);
free(threadstats);
+ free(opt_lists);
}
void show_run_stats(void)
fio_gettime(&tv, NULL);
for_each_td(td, i) {
- rt[i] = mtime_since(&td->start, &tv);
- if (td_read(td) && td->io_bytes[DDIR_READ])
- td->ts.runtime[DDIR_READ] += rt[i];
- if (td_write(td) && td->io_bytes[DDIR_WRITE])
- td->ts.runtime[DDIR_WRITE] += rt[i];
- if (td_trim(td) && td->io_bytes[DDIR_TRIM])
- td->ts.runtime[DDIR_TRIM] += rt[i];
-
td->update_rusage = 1;
td->ts.io_bytes[DDIR_READ] = td->io_bytes[DDIR_READ];
td->ts.io_bytes[DDIR_WRITE] = td->io_bytes[DDIR_WRITE];
td->ts.io_bytes[DDIR_TRIM] = td->io_bytes[DDIR_TRIM];
td->ts.total_run_time = mtime_since(&td->epoch, &tv);
+
+ rt[i] = mtime_since(&td->start, &tv);
+ if (td_read(td) && td->ts.io_bytes[DDIR_READ])
+ td->ts.runtime[DDIR_READ] += rt[i];
+ if (td_write(td) && td->ts.io_bytes[DDIR_WRITE])
+ td->ts.runtime[DDIR_WRITE] += rt[i];
+ if (td_trim(td) && td->ts.io_bytes[DDIR_TRIM])
+ td->ts.runtime[DDIR_TRIM] += rt[i];
}
for_each_td(td, i) {
__show_run_stats();
for_each_td(td, i) {
- if (td_read(td) && td->io_bytes[DDIR_READ])
+ if (td_read(td) && td->ts.io_bytes[DDIR_READ])
td->ts.runtime[DDIR_READ] -= rt[i];
- if (td_write(td) && td->io_bytes[DDIR_WRITE])
+ if (td_write(td) && td->ts.io_bytes[DDIR_WRITE])
td->ts.runtime[DDIR_WRITE] -= rt[i];
- if (td_trim(td) && td->io_bytes[DDIR_TRIM])
+ if (td_trim(td) && td->ts.io_bytes[DDIR_TRIM])
td->ts.runtime[DDIR_TRIM] -= rt[i];
}