First stab at adding job options to json output
authorJens Axboe <axboe@fb.com>
Tue, 15 Dec 2015 17:30:57 +0000 (10:30 -0700)
committerJens Axboe <axboe@fb.com>
Tue, 15 Dec 2015 17:30:57 +0000 (10:30 -0700)
Signed-off-by: Jens Axboe <axboe@fb.com>
fio.h
init.c
options.c
stat.c

diff --git a/fio.h b/fio.h
index 1ff6662b5ef5d5b7b09dd086e9a575e7cb694cae..ddc29dbdb038cc40673b2164c3ff0c7a744750f7 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -499,7 +499,7 @@ extern int parse_dryrun(void);
 extern int fio_running_or_pending_io_threads(void);
 extern int fio_set_fd_nonblocking(int, const char *);
 extern void sig_show_status(int sig);
-extern bool is_def_thread(struct thread_data *);
+extern struct thread_data *get_global_options(void);
 
 extern uintptr_t page_mask;
 extern uintptr_t page_size;
diff --git a/init.c b/init.c
index fb8c9cfb7a085a7b1b1679d4add329efc9dca3db..e314fa1d9d8586b486555d37e0673c83b4a375ce 100644 (file)
--- a/init.c
+++ b/init.c
@@ -1774,6 +1774,7 @@ int parse_jobs_ini(char *file, int is_buf, int stonewall_flag, int type)
 static int fill_def_thread(void)
 {
        memset(&def_thread, 0, sizeof(def_thread));
+       INIT_FLIST_HEAD(&def_thread.opt_list);
 
        fio_getaffinity(getpid(), &def_thread.o.cpumask);
        def_thread.o.error_dump = 1;
@@ -2633,7 +2634,7 @@ void options_default_fill(struct thread_options *o)
        memcpy(o, &def_thread.o, sizeof(*o));
 }
 
-bool is_def_thread(struct thread_data *td)
+struct thread_data *get_global_options(void)
 {
-       return td == &def_thread;
+       return &def_thread;
 }
index caa00af8f5e1dcf9c74c24ef8c1a4b1ea344e5d8..964e2634b5dd16c1af4cd1233019d9a1a63bd752 100644 (file)
--- a/options.c
+++ b/options.c
@@ -4081,20 +4081,16 @@ static void show_closest_option(const char *opt)
 
 int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
 {
-       struct flist_head *opt_list = NULL;
        int i, ret, unknown;
        char **opts_copy;
 
-       if (!is_def_thread(td))
-               opt_list = &td->opt_list;
-
        sort_options(opts, fio_options, num_opts);
        opts_copy = dup_and_sub_options(opts, num_opts);
 
        for (ret = 0, i = 0, unknown = 0; i < num_opts; i++) {
                struct fio_option *o;
                int newret = parse_option(opts_copy[i], opts[i], fio_options,
-                                               &o, td, opt_list);
+                                               &o, td, &td->opt_list);
 
                if (!newret && o)
                        fio_option_mark_set(&td->o, o);
@@ -4127,7 +4123,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
                        if (td->eo)
                                newret = parse_option(opts_copy[i], opts[i],
                                                      td->io_ops->options, &o,
-                                                     td->eo, opt_list);
+                                                     td->eo, &td->opt_list);
 
                        ret |= newret;
                        if (!o) {
diff --git a/stat.c b/stat.c
index ca066175d94243f51d7bd2773f0de1b4982c1fa1..e47b510f55d20f65e065d0807a20f81dd3402182 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -1086,8 +1086,32 @@ static void show_thread_status_terse_v3_v4(struct thread_stat *ts,
        log_buf(out, "\n");
 }
 
+static void json_add_job_opts(struct json_object *root, const char *name,
+                             struct flist_head *opt_list)
+{
+       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 (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;
@@ -1110,6 +1134,9 @@ static struct json_object *show_thread_status_json(struct thread_stat *ts,
                json_object_add_value_int(root, "elapsed", je->elapsed_sec);
        }
 
+       if (opt_list)
+               json_add_job_opts(root, "job options", opt_list);
+
        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);
@@ -1246,7 +1273,7 @@ struct json_object *show_thread_status(struct thread_stat *ts,
        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, NULL);
        if (output_format & FIO_OUTPUT_NORMAL)
                show_thread_status_normal(ts, rs,  out);
 
@@ -1427,6 +1454,7 @@ void __show_run_stats(void)
        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));
 
@@ -1452,9 +1480,12 @@ void __show_run_stats(void)
        }
 
        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;
@@ -1473,6 +1504,7 @@ void __show_run_stats(void)
                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++;
@@ -1596,6 +1628,7 @@ void __show_run_stats(void)
        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;
 
@@ -1608,6 +1641,8 @@ void __show_run_stats(void)
                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);
                array = json_create_array();
                json_object_add_value_array(root, "jobs", array);
        }
@@ -1622,7 +1657,7 @@ void __show_run_stats(void)
                        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)
@@ -1665,6 +1700,7 @@ void __show_run_stats(void)
        log_info_flush();
        free(runstats);
        free(threadstats);
+       free(opt_lists);
 }
 
 void show_run_stats(void)