glusterfs: update for new API
[fio.git] / gfio.c
diff --git a/gfio.c b/gfio.c
index e4d1f21..2805396 100644 (file)
--- a/gfio.c
+++ b/gfio.c
@@ -1,7 +1,7 @@
 /*
  * gfio - gui front end for fio - the flexible io tester
  *
- * Copyright (C) 2012 Stephen M. Cameron <stephenmcameron@gmail.com> 
+ * Copyright (C) 2012 Stephen M. Cameron <stephenmcameron@gmail.com>
  * Copyright (C) 2012 Jens Axboe <axboe@kernel.dk>
  *
  * The license below covers all files distributed with fio unless otherwise
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  */
 #include <locale.h>
-#include <malloc.h>
+#include <stdlib.h>
 #include <string.h>
+#include <libgen.h>
 
 #include <glib.h>
 #include <cairo.h>
 #include "gclient.h"
 #include "graph.h"
 
-static int gfio_server_running;
+static bool gfio_server_running;
 static unsigned int gfio_graph_limit = 100;
 
 GdkColor gfio_color_white;
-const char *gfio_graph_font;
+GdkColor gfio_color_lightyellow;
+const char *gfio_graph_font = GRAPH_DEFAULT_FONT;
 
 typedef void (*clickfunction)(GtkWidget *widget, gpointer data);
 
@@ -75,43 +77,49 @@ static struct button_spec {
        },
 };
 
-static struct graph *setup_iops_graph(void)
+static void setup_iops_graph(struct gfio_graphs *gg)
 {
        struct graph *g;
 
        g = graph_new(DRAWING_AREA_XDIM / 2.0, DRAWING_AREA_YDIM, gfio_graph_font);
        graph_title(g, "IOPS (IOs/sec)");
        graph_x_title(g, "Time (secs)");
-       graph_add_label(g, "Read IOPS");
-       graph_add_label(g, "Write IOPS");
-       graph_set_color(g, "Read IOPS", 0.13, 0.54, 0.13);
-       graph_set_color(g, "Write IOPS", 1.0, 0.0, 0.0);
+       gg->read_iops = graph_add_label(g, "Read IOPS");
+       gg->write_iops = graph_add_label(g, "Write IOPS");
+       gg->trim_iops = graph_add_label(g, "Trim IOPS");
+       graph_set_color(g, gg->read_iops, GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+       graph_set_color(g, gg->write_iops, GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+       graph_set_color(g, gg->trim_iops, GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
        line_graph_set_data_count_limit(g, gfio_graph_limit);
        graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
-       return g;
+       graph_set_graph_all_zeroes(g, 0);
+       gg->iops_graph = g;
 }
 
-static struct graph *setup_bandwidth_graph(void)
+static void setup_bandwidth_graph(struct gfio_graphs *gg)
 {
        struct graph *g;
 
        g = graph_new(DRAWING_AREA_XDIM / 2.0, DRAWING_AREA_YDIM, gfio_graph_font);
        graph_title(g, "Bandwidth (bytes/sec)");
        graph_x_title(g, "Time (secs)");
-       graph_add_label(g, "Read Bandwidth");
-       graph_add_label(g, "Write Bandwidth");
-       graph_set_color(g, "Read Bandwidth", 0.13, 0.54, 0.13);
-       graph_set_color(g, "Write Bandwidth", 1.0, 0.0, 0.0);
+       gg->read_bw = graph_add_label(g, "Read Bandwidth");
+       gg->write_bw = graph_add_label(g, "Write Bandwidth");
+       gg->trim_bw = graph_add_label(g, "Trim Bandwidth");
+       graph_set_color(g, gg->read_bw, GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+       graph_set_color(g, gg->write_bw, GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+       graph_set_color(g, gg->trim_bw, GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
        graph_set_base_offset(g, 1);
        line_graph_set_data_count_limit(g, 100);
        graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
-       return g;
+       graph_set_graph_all_zeroes(g, 0);
+       gg->bandwidth_graph = g;
 }
 
 static void setup_graphs(struct gfio_graphs *g)
 {
-       g->iops_graph = setup_iops_graph();
-       g->bandwidth_graph = setup_bandwidth_graph();
+       setup_iops_graph(g);
+       setup_bandwidth_graph(g);
 }
 
 void clear_ge_ui_info(struct gui_entry *ge)
@@ -291,7 +299,7 @@ static void gfio_ui_setup_log(struct gui *ui)
        GtkListStore *model;
        GtkWidget *tree_view;
 
-       model = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
+       model = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 
        tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
        gtk_widget_set_can_focus(tree_view, FALSE);
@@ -313,11 +321,13 @@ static void gfio_ui_setup_log(struct gui *ui)
 static gint on_config_drawing_area(GtkWidget *w, GdkEventConfigure *event,
                                   gpointer data)
 {
+       guint width = gtk_widget_get_allocated_width(w);
+       guint height = gtk_widget_get_allocated_height(w);
        struct gfio_graphs *g = data;
 
-       graph_set_size(g->iops_graph, w->allocation.width / 2.0, w->allocation.height);
-       graph_set_position(g->iops_graph, w->allocation.width / 2.0, 0.0);
-       graph_set_size(g->bandwidth_graph, w->allocation.width / 2.0, w->allocation.height);
+       graph_set_size(g->iops_graph, width / 2.0, height);
+       graph_set_position(g->iops_graph, width / 2.0, 0.0);
+       graph_set_size(g->bandwidth_graph, width / 2.0, height);
        graph_set_position(g->bandwidth_graph, 0, 0);
        return TRUE;
 }
@@ -353,7 +363,7 @@ static int on_expose_drawing_area(GtkWidget *w, GdkEvent *event, gpointer p)
        struct gfio_graphs *g = p;
        cairo_t *cr;
 
-       cr = gdk_cairo_create(w->window);
+       cr = gdk_cairo_create(gtk_widget_get_window(w));
 
        if (graph_has_tooltips(g->iops_graph) ||
            graph_has_tooltips(g->bandwidth_graph)) {
@@ -402,11 +412,11 @@ static void ge_widget_destroy(GtkWidget *w, gpointer data)
 
 static void gfio_quit(struct gui *ui)
 {
-        gtk_main_quit();
+       gtk_main_quit();
 }
 
 static void quit_clicked(__attribute__((unused)) GtkWidget *widget,
-                __attribute__((unused)) gpointer data)
+                        gpointer data)
 {
        struct gui *ui = (struct gui *) data;
 
@@ -428,7 +438,19 @@ static int send_job_file(struct gui_entry *ge)
        struct gfio_client *gc = ge->client;
        int ret = 0;
 
-       ret = fio_client_send_ini(gc->client, ge->job_file);
+       /*
+        * Prune old options, we are expecting the return options
+        * when the job file is parsed remotely and returned to us.
+        */
+       while (!flist_empty(&gc->o_list)) {
+               struct gfio_client_options *gco;
+
+               gco = flist_first_entry(&gc->o_list, struct gfio_client_options, list);
+               flist_del(&gco->list);
+               free(gco);
+       }
+
+       ret = fio_client_send_ini(gc->client, ge->job_file, false);
        if (!ret)
                return 0;
 
@@ -438,24 +460,26 @@ static int send_job_file(struct gui_entry *ge)
 
 static void *server_thread(void *arg)
 {
-       is_backend = 1;
-       gfio_server_running = 1;
+       fio_server_create_sk_key();
+       is_backend = true;
+       gfio_server_running = true;
        fio_start_server(NULL);
-       gfio_server_running = 0;
+       gfio_server_running = false;
+       fio_server_destroy_sk_key();
        return NULL;
 }
 
 static void gfio_start_server(struct gui *ui)
 {
        if (!gfio_server_running) {
-               gfio_server_running = 1;
+               gfio_server_running = true;
                pthread_create(&ui->server_t, NULL, server_thread, NULL);
                pthread_detach(ui->server_t);
        }
 }
 
 static void start_job_clicked(__attribute__((unused)) GtkWidget *widget,
-                gpointer data)
+                             gpointer data)
 {
        struct gui_entry *ge = data;
        struct gfio_client *gc = ge->client;
@@ -485,7 +509,7 @@ static void hostname_cb(GtkEntry *entry, gpointer data)
         * or not. Show it if we are a localhost and using network,
         * or using a socket.
         */
-       ctext = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cw->combo));
+       ctext = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(cw->combo));
        if (!ctext || !strncmp(ctext, "IPv4", 4) || !strncmp(ctext, "IPv6", 4))
                uses_net = 1;
        g_free(ctext);
@@ -524,8 +548,7 @@ static int get_connection_details(struct gui_entry *ge)
                        GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
 
        frame = gtk_frame_new("Hostname / socket name");
-       /* gtk_dialog_get_content_area() is 2.14 and newer */
-       vbox = GTK_DIALOG(dialog)->vbox;
+       vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
        gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
 
        box = gtk_vbox_new(FALSE, 6);
@@ -554,10 +577,10 @@ static int get_connection_details(struct gui_entry *ge)
        hbox = gtk_hbox_new(TRUE, 4);
        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
 
-       cw.combo = gtk_combo_box_new_text();
-       gtk_combo_box_append_text(GTK_COMBO_BOX(cw.combo), "IPv4");
-       gtk_combo_box_append_text(GTK_COMBO_BOX(cw.combo), "IPv6");
-       gtk_combo_box_append_text(GTK_COMBO_BOX(cw.combo), "local socket");
+       cw.combo = gtk_combo_box_text_new();
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw.combo), "IPv4");
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw.combo), "IPv6");
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw.combo), "local socket");
        gtk_combo_box_set_active(GTK_COMBO_BOX(cw.combo), 0);
 
        gtk_container_add(GTK_CONTAINER(hbox), cw.combo);
@@ -578,8 +601,8 @@ static int get_connection_details(struct gui_entry *ge)
        /*
         * Connect edit signal, so we can show/not-show the auto start button
         */
-       g_signal_connect(GTK_OBJECT(cw.hentry), "changed", G_CALLBACK(hostname_cb), &cw);
-       g_signal_connect(GTK_OBJECT(cw.combo), "changed", G_CALLBACK(hostname_cb), &cw);
+       g_signal_connect(G_OBJECT(cw.hentry), "changed", G_CALLBACK(hostname_cb), &cw);
+       g_signal_connect(G_OBJECT(cw.combo), "changed", G_CALLBACK(hostname_cb), &cw);
 
        gtk_widget_show_all(dialog);
 
@@ -591,7 +614,7 @@ static int get_connection_details(struct gui_entry *ge)
        ge->host = strdup(gtk_entry_get_text(GTK_ENTRY(cw.hentry)));
        ge->port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pentry));
 
-       typeentry = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cw.combo));
+       typeentry = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(cw.combo));
        if (!typeentry || !strncmp(typeentry, "IPv4", 4))
                ge->type = Fio_client_ipv4;
        else if (!strncmp(typeentry, "IPv6", 4))
@@ -614,14 +637,30 @@ static void gfio_set_client(struct gfio_client *gc, struct fio_client *client)
 
 static void gfio_client_added(struct gui_entry *ge, struct fio_client *client)
 {
+       struct gfio_client_options *gco;
        struct gfio_client *gc;
 
-       gc = malloc(sizeof(*gc));
-       memset(gc, 0, sizeof(*gc));
-       options_default_fill(&gc->o);
+       gc = calloc(1, sizeof(*gc));
+       INIT_FLIST_HEAD(&gc->o_list);
        gc->ge = ge;
        ge->client = gc;
        gfio_set_client(gc, client);
+
+       /*
+        * Just add a default set of options, need to consider how best
+        * to handle this
+        */
+       gco = calloc(1, sizeof(*gco));
+       INIT_FLIST_HEAD(&gco->list);
+       options_default_fill(&gco->o);
+       flist_add_tail(&gco->list, &gc->o_list);
+       gc->o_list_nr++;
+}
+
+static void gfio_clear_graph_data(struct gfio_graphs *g)
+{
+       graph_clear_values(g->iops_graph);
+       graph_clear_values(g->bandwidth_graph);
 }
 
 static void connect_clicked(GtkWidget *widget, gpointer data)
@@ -664,6 +703,7 @@ static void connect_clicked(GtkWidget *widget, gpointer data)
                        if (!ge->ui->handler_running)
                                pthread_create(&ge->ui->t, NULL, job_thread, ge->ui);
                        gfio_set_state(ge, GE_STATE_CONNECTED);
+                       gfio_clear_graph_data(&ge->graphs);
                } else {
                        gfio_report_error(ge, "Failed to connect to %s: %s\n", ge->client->client->hostname, strerror(-ret));
                }
@@ -851,7 +891,7 @@ static int do_file_open_with_tab(struct gui *ui, const gchar *uri)
        if (get_connection_details(ge)) {
                if (ge_is_new)
                        gtk_widget_destroy(ge->vbox);
-                       
+
                return 1;
        }
 
@@ -945,7 +985,7 @@ static void view_log_destroy(GtkWidget *w, gpointer data)
 {
        struct gui *ui = (struct gui *) data;
 
-       gtk_widget_ref(ui->log_tree);
+       g_object_ref(G_OBJECT(ui->log_tree));
        gtk_container_remove(GTK_CONTAINER(w), ui->log_tree);
        gtk_widget_destroy(w);
        ui->log_view = NULL;
@@ -969,12 +1009,12 @@ void gfio_view_log(struct gui *ui)
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
        box = gtk_hbox_new(TRUE, 0);
-       gtk_box_pack_start_defaults(GTK_BOX(box), ui->log_tree);
+       gtk_box_pack_start(GTK_BOX(box), ui->log_tree, TRUE, TRUE, 0);
        g_signal_connect(box, "destroy", G_CALLBACK(view_log_destroy), ui);
        gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), box);
 
        vbox = gtk_vbox_new(TRUE, 5);
-       gtk_box_pack_start_defaults(GTK_BOX(vbox), scroll);
+       gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 0);
 
        gtk_container_add(GTK_CONTAINER(win), vbox);
        gtk_widget_show_all(win);
@@ -991,7 +1031,7 @@ static void connect_job_entry(GtkWidget *w, gpointer data)
 {
        struct gui *ui = (struct gui *) data;
        struct gui_entry *ge;
-       
+
        ge = get_ge_from_cur_tab(ui);
        if (ge)
                connect_clicked(w, ge);
@@ -1014,7 +1054,7 @@ static void edit_job_entry(GtkWidget *w, gpointer data)
 
        ge = get_ge_from_cur_tab(ui);
        if (ge && ge->client)
-               gopt_get_options_window(ui->window, &ge->client->o);
+               gopt_get_options_window(ui->window, ge->client);
 }
 
 static void start_job_entry(GtkWidget *w, gpointer data)
@@ -1045,26 +1085,38 @@ static void view_results(GtkWidget *w, gpointer data)
                gfio_display_end_results(gc);
 }
 
-static void __update_graph_limits(struct gfio_graphs *g)
+static void __update_graph_settings(struct gfio_graphs *g)
 {
        line_graph_set_data_count_limit(g->iops_graph, gfio_graph_limit);
+       graph_set_font(g->iops_graph, gfio_graph_font);
        line_graph_set_data_count_limit(g->bandwidth_graph, gfio_graph_limit);
+       graph_set_font(g->bandwidth_graph, gfio_graph_font);
 }
 
-static void ge_update_lim_fn(gpointer key, gpointer value, gpointer data)
+static void ge_update_settings_fn(gpointer key, gpointer value, gpointer data)
 {
        struct gui_entry *ge = (struct gui_entry *) value;
+       GdkEvent *ev;
+
+       __update_graph_settings(&ge->graphs);
 
-       __update_graph_limits(&ge->graphs);
+       ev = gdk_event_new(GDK_EXPOSE);
+       g_signal_emit_by_name(G_OBJECT(ge->graphs.drawing_area), GFIO_DRAW_EVENT, GTK_WIDGET(ge->graphs.drawing_area), ev, &ge->graphs);
+       gdk_event_free(ev);
 }
 
 static void update_graph_limits(void)
 {
        struct gui *ui = &main_ui;
+       GdkEvent *ev;
 
-       __update_graph_limits(&ui->graphs);
+       __update_graph_settings(&ui->graphs);
 
-       g_hash_table_foreach(ui->ge_hash, ge_update_lim_fn, NULL);
+       ev = gdk_event_new(GDK_EXPOSE);
+       g_signal_emit_by_name(G_OBJECT(ui->graphs.drawing_area), GFIO_DRAW_EVENT, GTK_WIDGET(ui->graphs.drawing_area), ev, &ui->graphs);
+       gdk_event_free(ev);
+
+       g_hash_table_foreach(ui->ge_hash, ge_update_settings_fn, NULL);
 }
 
 static void preferences(GtkWidget *w, gpointer data)
@@ -1082,7 +1134,8 @@ static void preferences(GtkWidget *w, gpointer data)
                NULL);
 
        frame = gtk_frame_new("Graphing");
-       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+       vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+       gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
        vbox = gtk_vbox_new(FALSE, 6);
        gtk_container_add(GTK_CONTAINER(frame), vbox);
 
@@ -1091,7 +1144,7 @@ static void preferences(GtkWidget *w, gpointer data)
        entry = gtk_label_new("Font face to use for graph labels");
        gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 5);
 
-       font = gtk_font_button_new();
+       font = gtk_font_button_new_with_font(gfio_graph_font);
        gtk_box_pack_start(GTK_BOX(hbox), font, FALSE, FALSE, 5);
 
        box = gtk_vbox_new(FALSE, 6);
@@ -1114,7 +1167,8 @@ static void preferences(GtkWidget *w, gpointer data)
 
        spin_int = create_spinbutton(hbox, 100, 100000, gfio_client_ops.eta_msec);
        frame = gtk_frame_new("Debug logging");
-       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+       vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+       gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
        vbox = gtk_vbox_new(FALSE, 6);
        gtk_container_add(GTK_CONTAINER(frame), vbox);
 
@@ -1162,7 +1216,7 @@ static void about_dialog(GtkWidget *w, gpointer data)
 {
        const char *authors[] = {
                "Jens Axboe <axboe@kernel.dk>",
-               "Stephen Carmeron <stephenmcameron@gmail.com>",
+               "Stephen Cameron <stephenmcameron@gmail.com>",
                NULL
        };
        const char *license[] = {
@@ -1187,10 +1241,10 @@ static void about_dialog(GtkWidget *w, gpointer data)
                "program-name", "gfio",
                "comments", "Gtk2 UI for fio",
                "license", license_trans,
-               "website", "http://git.kernel.dk/?p=fio.git;a=summary",
+               "website", "http://git.kernel.dk/cgit/fio/",
                "authors", authors,
                "version", fio_version_string,
-               "copyright", "© 2012 Jens Axboe <axboe@kernel.dk>",
+               "copyright", "© 2012-2017 Jens Axboe <axboe@kernel.dk>",
                "logo-icon-name", "fio",
                /* Must be last: */
                "wrap-license", TRUE,
@@ -1218,7 +1272,7 @@ static GtkActionEntry menu_items[] = {
        { "Quit", GTK_STOCK_QUIT, NULL,   "<Control>Q", NULL, G_CALLBACK(quit_clicked) },
        { "About", GTK_STOCK_ABOUT, NULL,  NULL, NULL, G_CALLBACK(about_dialog) },
 };
-static gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
+static gint nmenu_items = ARRAY_SIZE(menu_items);
 
 static const gchar *ui_string = " \
        <ui> \
@@ -1333,7 +1387,7 @@ static GtkWidget *new_client_page(struct gui_entry *ge)
        g_signal_connect(ge->eta.names, "changed", G_CALLBACK(combo_entry_changed), ge);
        g_signal_connect(ge->eta.names, "destroy", G_CALLBACK(combo_entry_destroy), ge);
        ge->eta.iotype.entry = new_info_entry_in_frame(probe_box, "IO");
-       ge->eta.bs.entry = new_info_entry_in_frame(probe_box, "Blocksize (Read/Write)");
+       ge->eta.bs.entry = new_info_entry_in_frame(probe_box, "Blocksize (Read/Write/Trim)");
        ge->eta.ioengine.entry = new_info_entry_in_frame(probe_box, "IO Engine");
        ge->eta.iodepth.entry = new_info_entry_in_frame(probe_box, "IO Depth");
        ge->eta.jobs = new_info_entry_in_frame(probe_box, "Jobs");
@@ -1341,10 +1395,12 @@ static GtkWidget *new_client_page(struct gui_entry *ge)
 
        probe_box = gtk_hbox_new(FALSE, 3);
        gtk_box_pack_start(GTK_BOX(probe_frame), probe_box, FALSE, FALSE, 3);
-       ge->eta.read_bw = new_info_entry_in_frame(probe_box, "Read BW");
-       ge->eta.read_iops = new_info_entry_in_frame(probe_box, "IOPS");
-       ge->eta.write_bw = new_info_entry_in_frame(probe_box, "Write BW");
-       ge->eta.write_iops = new_info_entry_in_frame(probe_box, "IOPS");
+       ge->eta.read_bw = new_info_entry_in_frame_rgb(probe_box, "Read BW", GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+       ge->eta.read_iops = new_info_entry_in_frame_rgb(probe_box, "Read IOPS", GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+       ge->eta.write_bw = new_info_entry_in_frame_rgb(probe_box, "Write BW", GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+       ge->eta.write_iops = new_info_entry_in_frame_rgb(probe_box, "Write IOPS", GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+       ge->eta.trim_bw = new_info_entry_in_frame_rgb(probe_box, "Trim BW", GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
+       ge->eta.trim_iops = new_info_entry_in_frame_rgb(probe_box, "Trim IOPS", GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
 
        /*
         * Only add this if we have a commit rate
@@ -1366,8 +1422,8 @@ static GtkWidget *new_client_page(struct gui_entry *ge)
        ge->graphs.drawing_area = gtk_drawing_area_new();
        gtk_widget_set_size_request(GTK_WIDGET(ge->graphs.drawing_area),
                DRAWING_AREA_XDIM, DRAWING_AREA_YDIM);
-       gtk_widget_modify_bg(ge->graphs.drawing_area, GTK_STATE_NORMAL, &gfio_color_white);
-       g_signal_connect(G_OBJECT(ge->graphs.drawing_area), "expose_event",
+       gtk_widget_modify_bg(ge->graphs.drawing_area, GTK_STATE_NORMAL, &gfio_color_lightyellow);
+       g_signal_connect(G_OBJECT(ge->graphs.drawing_area), GFIO_DRAW_EVENT,
                                G_CALLBACK(on_expose_drawing_area), &ge->graphs);
        g_signal_connect(G_OBJECT(ge->graphs.drawing_area), "configure_event",
                                G_CALLBACK(on_config_drawing_area), &ge->graphs);
@@ -1381,7 +1437,7 @@ static GtkWidget *new_client_page(struct gui_entry *ge)
        setup_graphs(&ge->graphs);
 
        /*
-        * Set up alignments for widgets at the bottom of ui, 
+        * Set up alignments for widgets at the bottom of ui,
         * align bottom left, expand horizontally but not vertically
         */
        bottom_align = gtk_alignment_new(0, 1, 1, 0);
@@ -1389,7 +1445,7 @@ static GtkWidget *new_client_page(struct gui_entry *ge)
        gtk_container_add(GTK_CONTAINER(bottom_align), ge->buttonbox);
        gtk_box_pack_start(GTK_BOX(main_vbox), bottom_align, FALSE, FALSE, 0);
 
-       add_buttons(ge, buttonspeclist, ARRAYSIZE(buttonspeclist));
+       add_buttons(ge, buttonspeclist, ARRAY_SIZE(buttonspeclist));
 
        /*
         * Set up thread status progress bar
@@ -1427,10 +1483,12 @@ static GtkWidget *new_main_page(struct gui *ui)
        probe_box = gtk_hbox_new(FALSE, 3);
        gtk_box_pack_start(GTK_BOX(probe_frame), probe_box, FALSE, FALSE, 3);
        ui->eta.jobs = new_info_entry_in_frame(probe_box, "Running");
-       ui->eta.read_bw = new_info_entry_in_frame(probe_box, "Read BW");
-       ui->eta.read_iops = new_info_entry_in_frame(probe_box, "IOPS");
-       ui->eta.write_bw = new_info_entry_in_frame(probe_box, "Write BW");
-       ui->eta.write_iops = new_info_entry_in_frame(probe_box, "IOPS");
+       ui->eta.read_bw = new_info_entry_in_frame_rgb(probe_box, "Read BW", GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+       ui->eta.read_iops = new_info_entry_in_frame_rgb(probe_box, "IOPS", GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+       ui->eta.write_bw = new_info_entry_in_frame_rgb(probe_box, "Write BW", GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+       ui->eta.write_iops = new_info_entry_in_frame_rgb(probe_box, "IOPS", GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+       ui->eta.trim_bw = new_info_entry_in_frame_rgb(probe_box, "Trim BW", GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
+       ui->eta.trim_iops = new_info_entry_in_frame_rgb(probe_box, "IOPS", GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
 
        /*
         * Only add this if we have a commit rate
@@ -1452,8 +1510,8 @@ static GtkWidget *new_main_page(struct gui *ui)
        ui->graphs.drawing_area = gtk_drawing_area_new();
        gtk_widget_set_size_request(GTK_WIDGET(ui->graphs.drawing_area),
                DRAWING_AREA_XDIM, DRAWING_AREA_YDIM);
-       gtk_widget_modify_bg(ui->graphs.drawing_area, GTK_STATE_NORMAL, &gfio_color_white);
-       g_signal_connect(G_OBJECT(ui->graphs.drawing_area), "expose_event",
+       gtk_widget_modify_bg(ui->graphs.drawing_area, GTK_STATE_NORMAL, &gfio_color_lightyellow);
+       g_signal_connect(G_OBJECT(ui->graphs.drawing_area), GFIO_DRAW_EVENT,
                        G_CALLBACK(on_expose_drawing_area), &ui->graphs);
        g_signal_connect(G_OBJECT(ui->graphs.drawing_area), "configure_event",
                        G_CALLBACK(on_config_drawing_area), &ui->graphs);
@@ -1468,7 +1526,7 @@ static GtkWidget *new_main_page(struct gui *ui)
        setup_graphs(&ui->graphs);
 
        /*
-        * Set up alignments for widgets at the bottom of ui, 
+        * Set up alignments for widgets at the bottom of ui,
         * align bottom left, expand horizontally but not vertically
         */
        bottom_align = gtk_alignment_new(0, 1, 1, 0);
@@ -1622,16 +1680,22 @@ static void init_ui(int *argc, char **argv[], struct gui *ui)
         * Without it, the update that happens in gfio_update_thread_status
         * doesn't really happen in a timely fashion, you need expose events
         */
+#if !GLIB_CHECK_VERSION(2, 31, 0)
        if (!g_thread_supported())
                g_thread_init(NULL);
+#endif
+
        gdk_threads_init();
 
        gtk_init(argc, argv);
        settings = gtk_settings_get_default();
        gtk_settings_set_long_property(settings, "gtk_tooltip_timeout", 10, "gfio setting");
+#if !GLIB_CHECK_VERSION(2, 36, 0)
        g_type_init();
+#endif
+       gdk_color_parse("#fffff4", &gfio_color_lightyellow);
        gdk_color_parse("white", &gfio_color_white);
-       
+
        ui->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(ui->window), "fio");
        gtk_window_set_default_size(GTK_WINDOW(ui->window), 1024, 768);
@@ -1674,6 +1738,8 @@ int main(int argc, char *argv[], char *envp[])
        if (fio_init_options())
                return 1;
 
+       gopt_init();
+
        memset(&main_ui, 0, sizeof(main_ui));
        main_ui.ge_hash = g_hash_table_new(g_int_hash, g_int_equal);
 
@@ -1684,5 +1750,7 @@ int main(int argc, char *argv[], char *envp[])
        gdk_threads_leave();
 
        g_hash_table_destroy(main_ui.ge_hash);
+
+       gopt_exit();
        return 0;
 }