X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=gfio.c;h=04c841d91669e666395d8d9ef56fe7e174eba32e;hb=019dd47743caec2954f9960d178516b760abca26;hp=8f84638c356c2223aea9d24b984773e6bcdad9ca;hpb=62bc937f9ee196342184ff1ece0b9f404bbd0585;p=fio.git diff --git a/gfio.c b/gfio.c index 8f84638c..04c841d9 100644 --- a/gfio.c +++ b/gfio.c @@ -23,6 +23,7 @@ */ #include #include +#include #include #include @@ -32,8 +33,10 @@ #include "graph.h" static int gfio_server_running; +static const char *gfio_graph_font; static void gfio_update_thread_status(char *status_message, double perc); +static void view_log(GtkWidget *w, gpointer data); #define ARRAYSIZE(x) (sizeof((x)) / (sizeof((x)[0]))) @@ -93,6 +96,8 @@ struct gui { #define DRAWING_AREA_XDIM 1000 #define DRAWING_AREA_YDIM 400 GtkWidget *drawing_area; + int drawing_area_xdim; + int drawing_area_ydim; GtkWidget *error_info_bar; GtkWidget *error_label; GtkWidget *results_notebook; @@ -118,36 +123,39 @@ struct gfio_client { struct gui *ui; GtkWidget *results_widget; GtkWidget *disk_util_frame; + GtkWidget *err_entry; }; static void setup_iops_graph(struct gui *ui) { if (ui->iops_graph) graph_free(ui->iops_graph); - ui->iops_graph = graph_new((int) DRAWING_AREA_XDIM / 2.0, - (int) DRAWING_AREA_YDIM); + ui->iops_graph = graph_new(DRAWING_AREA_XDIM / 2.0, + DRAWING_AREA_YDIM, gfio_graph_font); graph_title(ui->iops_graph, "IOPS"); - graph_x_title(ui->iops_graph, "Time"); - graph_y_title(ui->iops_graph, "IOPS"); + graph_x_title(ui->iops_graph, "Time (secs)"); + graph_y_title(ui->iops_graph, "IOs / sec"); graph_add_label(ui->iops_graph, "Read IOPS"); graph_add_label(ui->iops_graph, "Write IOPS"); - graph_set_color(ui->iops_graph, "Read IOPS", 0.7, 0.0, 0.0); - graph_set_color(ui->iops_graph, "Write IOPS", 0.0, 0.0, 0.7); + graph_set_color(ui->iops_graph, "Read IOPS", 0.13, 0.54, 0.13); + graph_set_color(ui->iops_graph, "Write IOPS", 1.0, 0.0, 0.0); + line_graph_set_data_count_limit(ui->iops_graph, 100); } static void setup_bandwidth_graph(struct gui *ui) { if (ui->bandwidth_graph) graph_free(ui->bandwidth_graph); - ui->bandwidth_graph = graph_new((int) DRAWING_AREA_XDIM / 2.0, - (int) DRAWING_AREA_YDIM); + ui->bandwidth_graph = graph_new(DRAWING_AREA_XDIM / 2.0, + DRAWING_AREA_YDIM, gfio_graph_font); graph_title(ui->bandwidth_graph, "Bandwidth"); - graph_x_title(ui->bandwidth_graph, "Time"); - graph_y_title(ui->bandwidth_graph, "Bandwidth"); + graph_x_title(ui->bandwidth_graph, "Time (secs)"); + graph_y_title(ui->bandwidth_graph, "Kbytes / sec"); graph_add_label(ui->bandwidth_graph, "Read Bandwidth"); graph_add_label(ui->bandwidth_graph, "Write Bandwidth"); - graph_set_color(ui->bandwidth_graph, "Read Bandwidth", 0.7, 0.0, 0.0); - graph_set_color(ui->bandwidth_graph, "Write Bandwidth", 0.0, 0.0, 0.7); + graph_set_color(ui->bandwidth_graph, "Read Bandwidth", 0.13, 0.54, 0.13); + graph_set_color(ui->bandwidth_graph, "Write Bandwidth", 1.0, 0.0, 0.0); + line_graph_set_data_count_limit(ui->bandwidth_graph, 100); } static void clear_ui_info(struct gui *ui) @@ -809,6 +817,7 @@ static GtkWidget *get_results_window(struct gui *ui) win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(win), "Results"); + gtk_window_set_default_size(GTK_WINDOW(win), 1024, 768); g_signal_connect(win, "delete-event", G_CALLBACK(results_window_delete), ui); g_signal_connect(win, "destroy", G_CALLBACK(results_window_delete), ui); @@ -823,19 +832,25 @@ static GtkWidget *get_results_window(struct gui *ui) static void gfio_display_ts(struct fio_client *client, struct thread_stat *ts, struct group_run_stats *rs) { - GtkWidget *res_win, *box, *vbox, *entry; + GtkWidget *res_win, *box, *vbox, *entry, *scroll; struct gfio_client *gc = client->client_data; gdk_threads_enter(); res_win = get_results_window(gc->ui); + scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_container_set_border_width(GTK_CONTAINER(scroll), 5); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + vbox = gtk_vbox_new(FALSE, 3); - box = gtk_hbox_new(TRUE, 3); - gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 5); + box = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), box, TRUE, FALSE, 5); + + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), vbox); - gtk_notebook_append_page(GTK_NOTEBOOK(res_win), vbox, gtk_label_new(ts->name)); + gtk_notebook_append_page(GTK_NOTEBOOK(res_win), scroll, gtk_label_new(ts->name)); gc->results_widget = vbox; @@ -849,7 +864,7 @@ static void gfio_display_ts(struct fio_client *client, struct thread_stat *ts, entry_set_int_value(entry, ts->groupid); entry = new_info_entry_in_frame(box, "Jobs"); entry_set_int_value(entry, ts->members); - entry = new_info_entry_in_frame(box, "Error"); + gc->err_entry = entry = new_info_entry_in_frame(box, "Error"); entry_set_int_value(entry, ts->error); entry = new_info_entry_in_frame(box, "PID"); entry_set_int_value(entry, ts->pid); @@ -889,6 +904,9 @@ static void gfio_text_op(struct fio_client *client, struct fio_net_cmd *cmd) gtk_list_store_set(gc->ui->log_model, &iter, 2, p->level, -1); gtk_list_store_set(gc->ui->log_model, &iter, 3, p->buf, -1); + if (p->level == FIO_LOG_ERR) + view_log(NULL, (gpointer) gc->ui); + gdk_threads_leave(); } @@ -897,13 +915,13 @@ static void gfio_disk_util_op(struct fio_client *client, struct fio_net_cmd *cmd struct cmd_du_pdu *p = (struct cmd_du_pdu *) cmd->payload; struct gfio_client *gc = client->client_data; GtkWidget *box, *frame, *entry, *vbox; + double util; + char tmp[16]; gdk_threads_enter(); - if (!gc->results_widget) { - printf("no results!\n"); + if (!gc->results_widget) goto out; - } if (!gc->disk_util_frame) { gc->disk_util_frame = gtk_frame_new("Disk utilization"); @@ -954,6 +972,16 @@ static void gfio_disk_util_op(struct fio_client *client, struct fio_net_cmd *cmd entry = new_info_entry_in_frame(vbox, "Time in queue"); entry_set_int_value(entry, p->dus.time_in_queue); + util = 0.0; + if (p->dus.msec) + util = (double) 100 * p->dus.io_ticks / (double) p->dus.msec; + if (util > 100.0) + util = 100.0; + + sprintf(tmp, "%3.2f%%", util); + entry = new_info_entry_in_frame(vbox, "Disk utilization"); + gtk_entry_set_text(GTK_ENTRY(entry), tmp); + gtk_widget_show_all(gc->results_widget); out: gdk_threads_leave(); @@ -996,11 +1024,22 @@ static void gfio_group_stats_op(struct fio_client *client, gdk_threads_leave(); } +static gint on_config_drawing_area(GtkWidget *w, GdkEventConfigure *event) +{ + ui.drawing_area_xdim = w->allocation.width; + ui.drawing_area_ydim = w->allocation.height; + return TRUE; +} + static int on_expose_drawing_area(GtkWidget *w, GdkEvent *event, gpointer p) { struct gui *ui = (struct gui *) p; cairo_t *cr; + graph_set_size(ui->iops_graph, ui->drawing_area_xdim / 2.0, + ui->drawing_area_ydim); + graph_set_size(ui->bandwidth_graph, ui->drawing_area_xdim / 2.0, + ui->drawing_area_ydim); cr = gdk_cairo_create(w->window); cairo_set_source_rgb(cr, 0, 0, 0); @@ -1012,8 +1051,7 @@ static int on_expose_drawing_area(GtkWidget *w, GdkEvent *event, gpointer p) cairo_restore(cr); cairo_save(cr); - cairo_translate(cr, DRAWING_AREA_XDIM / 2.0, 0); - // DRAWING_AREA_YDIM * 0.05); + cairo_translate(cr, ui->drawing_area_xdim / 2.0, 0); line_graph_draw(ui->iops_graph, cr); cairo_stroke(cr); cairo_restore(cr); @@ -1213,7 +1251,9 @@ static void gfio_client_timed_out(struct fio_client *client) GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); - content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + /* gtk_dialog_get_content_area() is 2.14 and newer */ + content = GTK_DIALOG(dialog)->vbox; + label = gtk_label_new((const gchar *) buf); gtk_container_add(GTK_CONTAINER(content), label); gtk_widget_show_all(dialog); @@ -1225,6 +1265,20 @@ static void gfio_client_timed_out(struct fio_client *client) gdk_threads_leave(); } +static void gfio_client_stop(struct fio_client *client, struct fio_net_cmd *cmd) +{ + struct gfio_client *gc = client->client_data; + + gdk_threads_enter(); + + gfio_set_connected(gc->ui, 0); + + if (gc->err_entry) + entry_set_int_value(gc->err_entry, client->error); + + gdk_threads_leave(); +} + struct client_ops gfio_client_ops = { .text_op = gfio_text_op, .disk_util = gfio_disk_util_op, @@ -1235,6 +1289,7 @@ struct client_ops gfio_client_ops = { .quit = gfio_quit_op, .add_job = gfio_add_job_op, .timed_out = gfio_client_timed_out, + .stop = gfio_client_stop, .stay_connected = 1, }; @@ -1436,7 +1491,8 @@ static int get_connection_details(char **host, int *port, int *type, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); frame = gtk_frame_new("Hostname / socket name"); - vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + /* gtk_dialog_get_content_area() is 2.14 and newer */ + vbox = GTK_DIALOG(dialog)->vbox; gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5); box = gtk_vbox_new(FALSE, 6); @@ -1662,7 +1718,7 @@ static void view_log(GtkWidget *w, gpointer data) static void preferences(GtkWidget *w, gpointer data) { - GtkWidget *dialog, *frame, *box, **buttons; + GtkWidget *dialog, *frame, *box, **buttons, *vbox, *font; int i; dialog = gtk_dialog_new_with_buttons("Preferences", @@ -1674,17 +1730,35 @@ static void preferences(GtkWidget *w, gpointer data) frame = gtk_frame_new("Debug logging"); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5); + + vbox = gtk_vbox_new(FALSE, 6); + gtk_container_add(GTK_CONTAINER(frame), vbox); + box = gtk_hbox_new(FALSE, 6); - gtk_container_add(GTK_CONTAINER(frame), box); + gtk_container_add(GTK_CONTAINER(vbox), box); buttons = malloc(sizeof(GtkWidget *) * FD_DEBUG_MAX); for (i = 0; i < FD_DEBUG_MAX; i++) { + if (i == 7) { + box = gtk_hbox_new(FALSE, 6); + gtk_container_add(GTK_CONTAINER(vbox), box); + } + + buttons[i] = gtk_check_button_new_with_label(debug_levels[i].name); gtk_widget_set_tooltip_text(buttons[i], debug_levels[i].help); gtk_box_pack_start(GTK_BOX(box), buttons[i], FALSE, FALSE, 6); } + frame = gtk_frame_new("Graph font"); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5); + vbox = gtk_vbox_new(FALSE, 6); + gtk_container_add(GTK_CONTAINER(frame), vbox); + + font = gtk_font_button_new(); + gtk_box_pack_start(GTK_BOX(vbox), font, FALSE, FALSE, 5); + gtk_widget_show_all(dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) { @@ -1700,21 +1774,49 @@ static void preferences(GtkWidget *w, gpointer data) fio_debug |= (1UL << i); } + gfio_graph_font = strdup(gtk_font_button_get_font_name(GTK_FONT_BUTTON(font))); gtk_widget_destroy(dialog); } static void about_dialog(GtkWidget *w, gpointer data) { + const char *authors[] = { + "Jens Axboe ", + "Stephen Carmeron ", + NULL + }; + const char *license[] = { + "Fio is free software; you can redistribute it and/or modify " + "it under the terms of the GNU General Public License as published by " + "the Free Software Foundation; either version 2 of the License, or " + "(at your option) any later version.\n", + "Fio is distributed in the hope that it will be useful, " + "but WITHOUT ANY WARRANTY; without even the implied warranty of " + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " + "GNU General Public License for more details.\n", + "You should have received a copy of the GNU General Public License " + "along with Fio; if not, write to the Free Software Foundation, Inc., " + "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" + }; + char *license_trans; + + license_trans = g_strconcat(license[0], "\n", license[1], "\n", + license[2], "\n", NULL); + gtk_show_about_dialog(NULL, "program-name", "gfio", "comments", "Gtk2 UI for fio", - "license", "GPLv2", + "license", license_trans, + "website", "http://git.kernel.dk/?p=fio.git;a=summary", + "authors", authors, "version", fio_version_string, - "copyright", "Jens Axboe 2012", + "copyright", "© 2012 Jens Axboe ", "logo-icon-name", "fio", /* Must be last: */ - NULL, NULL, + "wrap-license", TRUE, NULL); + + g_free (license_trans); } static GtkActionEntry menu_items[] = { @@ -1778,6 +1880,7 @@ static void init_ui(int *argc, char **argv[], struct gui *ui) GtkSettings *settings; GtkUIManager *uimanager; GtkWidget *menu, *probe, *probe_frame, *probe_box; + GdkColor white; memset(ui, 0, sizeof(*ui)); @@ -1796,7 +1899,7 @@ static void init_ui(int *argc, char **argv[], struct gui *ui) 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), 700, 500); + gtk_window_set_default_size(GTK_WINDOW(ui->window), 700, 700); g_signal_connect(ui->window, "delete-event", G_CALLBACK(quit_clicked), NULL); g_signal_connect(ui->window, "destroy", G_CALLBACK(quit_clicked), NULL); @@ -1863,11 +1966,17 @@ static void init_ui(int *argc, char **argv[], struct gui *ui) /* * Set up a drawing area and IOPS and bandwidth graphs */ + gdk_color_parse("white", &white); ui->drawing_area = gtk_drawing_area_new(); + ui->drawing_area_xdim = DRAWING_AREA_XDIM; + ui->drawing_area_ydim = DRAWING_AREA_YDIM; gtk_widget_set_size_request(GTK_WIDGET(ui->drawing_area), - DRAWING_AREA_XDIM, DRAWING_AREA_YDIM); + ui->drawing_area_xdim, ui->drawing_area_ydim); + gtk_widget_modify_bg(ui->drawing_area, GTK_STATE_NORMAL, &white); g_signal_connect(G_OBJECT(ui->drawing_area), "expose_event", G_CALLBACK (on_expose_drawing_area), ui); + g_signal_connect(G_OBJECT(ui->drawing_area), "configure_event", + G_CALLBACK (on_config_drawing_area), ui); ui->scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ui->scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);