gfio: Change some labels to entries and add bw stats to final output
[fio.git] / gfio.c
diff --git a/gfio.c b/gfio.c
index 848e511a8157c975355d36e5a2580fe701e116f4..062f63fdd8e7ffe6e971f3ebd4bcb42678643a14 100644 (file)
--- a/gfio.c
+++ b/gfio.c
@@ -59,6 +59,10 @@ struct probe_widget {
 };
 
 struct eta_widget {
+       GtkWidget *name;
+       GtkWidget *iotype;
+       GtkWidget *ioengine;
+       GtkWidget *iodepth;
        GtkWidget *jobs;
        GtkWidget *files;
        GtkWidget *read_bw;
@@ -80,12 +84,6 @@ struct gui {
        GtkWidget *thread_status_pb;
        GtkWidget *buttonbox;
        GtkWidget *button[ARRAYSIZE(buttonspeclist)];
-       GtkWidget *hostname_hbox;
-       GtkWidget *hostname_label;
-       GtkWidget *hostname_entry;
-       GtkWidget *port_button;
-       GtkWidget *port_label;
-       GtkWidget *hostname_combo_box; /* ipv4, ipv6 or socket */
        GtkWidget *scrolled_window;
        GtkWidget *textview;
        GtkWidget *error_info_bar;
@@ -101,6 +99,66 @@ struct gui {
        char **job_files;
 } ui;
 
+static void clear_ui_info(struct gui *ui)
+{
+       gtk_label_set_text(GTK_LABEL(ui->probe.hostname), "");
+       gtk_label_set_text(GTK_LABEL(ui->probe.os), "");
+       gtk_label_set_text(GTK_LABEL(ui->probe.arch), "");
+       gtk_label_set_text(GTK_LABEL(ui->probe.fio_ver), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.name), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.iotype), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.ioengine), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.iodepth), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.jobs), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.files), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.read_bw), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.read_iops), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.write_bw), "");
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.write_iops), "");
+}
+
+static GtkWidget *new_info_entry_in_frame(GtkWidget *box, const char *label)
+{
+       GtkWidget *entry, *frame;
+
+       frame = gtk_frame_new(label);
+       entry = gtk_entry_new();
+       gtk_entry_set_editable(GTK_ENTRY(entry), 0);
+       gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 3);
+       gtk_container_add(GTK_CONTAINER(frame), entry);
+
+       return entry;
+}
+
+static GtkWidget *new_info_label_in_frame(GtkWidget *box, const char *label)
+{
+       GtkWidget *label_widget;
+       GtkWidget *frame;
+
+       frame = gtk_frame_new(label);
+       label_widget = gtk_label_new(NULL);
+       gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 3);
+       gtk_container_add(GTK_CONTAINER(frame), label_widget);
+
+       return label_widget;
+}
+
+static GtkWidget *create_spinbutton(GtkWidget *hbox, double min, double max, double defval)
+{
+       GtkWidget *button, *box;
+
+       box = gtk_hbox_new(FALSE, 3);
+       gtk_container_add(GTK_CONTAINER(hbox), box);
+
+       button = gtk_spin_button_new_with_range(min, max, 1.0);
+       gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
+
+       gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(button), GTK_UPDATE_IF_VALID);
+       gtk_spin_button_set_value(GTK_SPIN_BUTTON(button), defval);
+
+       return button;
+}
+
 static void gfio_set_connected(struct gui *ui, int connected)
 {
        if (connected) {
@@ -114,9 +172,359 @@ static void gfio_set_connected(struct gui *ui, int connected)
        }
 }
 
-static void gfio_text_op(struct fio_client *client,
-                FILE *f, __u16 pdu_len, const char *buf)
+static void label_set_int_value(GtkWidget *entry, unsigned int val)
+{
+       char tmp[80];
+
+       sprintf(tmp, "%u", val);
+       gtk_label_set_text(GTK_LABEL(entry), tmp);
+}
+
+static void entry_set_int_value(GtkWidget *entry, unsigned int val)
+{
+       char tmp[80];
+
+       sprintf(tmp, "%u", val);
+       gtk_entry_set_text(GTK_ENTRY(entry), tmp);
+}
+
+#define ALIGN_LEFT 1
+#define ALIGN_RIGHT 2
+#define INVISIBLE 4
+#define UNSORTABLE 8
+
+GtkTreeViewColumn *tree_view_column(GtkWidget *tree_view, int index, const char *title, unsigned int flags)
+{
+       GtkCellRenderer *renderer;
+       GtkTreeViewColumn *col;
+       double xalign = 0.0; /* left as default */
+       PangoAlignment align;
+       gboolean visible;
+
+       align = (flags & ALIGN_LEFT) ? PANGO_ALIGN_LEFT :
+               (flags & ALIGN_RIGHT) ? PANGO_ALIGN_RIGHT :
+               PANGO_ALIGN_CENTER;
+       visible = !(flags & INVISIBLE);
+
+       renderer = gtk_cell_renderer_text_new();
+       col = gtk_tree_view_column_new();
+
+       gtk_tree_view_column_set_title(col, title);
+       if (!(flags & UNSORTABLE))
+               gtk_tree_view_column_set_sort_column_id(col, index);
+       gtk_tree_view_column_set_resizable(col, TRUE);
+       gtk_tree_view_column_pack_start(col, renderer, TRUE);
+       gtk_tree_view_column_add_attribute(col, renderer, "text", index);
+       gtk_object_set(GTK_OBJECT(renderer), "alignment", align, NULL);
+       switch (align) {
+       case PANGO_ALIGN_LEFT:
+               xalign = 0.0;
+               break;
+       case PANGO_ALIGN_CENTER:
+               xalign = 0.5;
+               break;
+       case PANGO_ALIGN_RIGHT:
+               xalign = 1.0;
+               break;
+       }
+       gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(renderer), xalign, 0.5);
+       gtk_tree_view_column_set_visible(col, visible);
+       gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);
+       return col;
+}
+
+static GtkWidget *gfio_output_clat_percentiles(unsigned int *ovals,
+                                              fio_fp64_t *plist,
+                                              unsigned int len,
+                                              const char *base,
+                                              unsigned int scale)
+{
+       GType types[FIO_IO_U_LIST_MAX_LEN];
+       GtkWidget *tree_view;
+       GtkTreeSelection *selection;
+       GtkListStore *model;
+       GtkTreeIter iter;
+       int i;
+
+       for (i = 0; i < len; i++)
+               types[i] = G_TYPE_INT;
+
+       model = gtk_list_store_newv(len, types);
+
+       tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
+       gtk_widget_set_can_focus(tree_view, FALSE);
+
+       selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
+       gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_BROWSE);
+
+       for (i = 0; i < len; i++) {
+               char fbuf[8];
+
+               sprintf(fbuf, "%2.2f%%", plist[i].u.f);
+               tree_view_column(tree_view, i, fbuf, ALIGN_RIGHT | UNSORTABLE);
+       }
+
+       gtk_list_store_append(model, &iter);
+
+       for (i = 0; i < len; i++)
+               gtk_list_store_set(model, &iter, i, ovals[i], -1);
+
+       return tree_view;
+}
+
+static void gfio_show_clat_percentiles(GtkWidget *vbox, struct thread_stat *ts,
+                                      int ddir)
+{
+       unsigned int *io_u_plat = ts->io_u_plat[ddir];
+       unsigned long nr = ts->clat_stat[ddir].samples;
+       fio_fp64_t *plist = ts->percentile_list;
+       unsigned int *ovals, len, minv, maxv, scale_down;
+       const char *base;
+       GtkWidget *tree_view, *frame, *hbox;
+       char tmp[64];
+
+       len = calc_clat_percentiles(io_u_plat, nr, plist, &ovals, &maxv, &minv);
+       if (!len)
+               goto out;
+
+       /*
+        * We default to usecs, but if the value range is such that we
+        * should scale down to msecs, do that.
+        */
+       if (minv > 2000 && maxv > 99999) {
+               scale_down = 1;
+               base = "msec";
+       } else {
+               scale_down = 0;
+               base = "usec";
+       }
+
+       tree_view = gfio_output_clat_percentiles(ovals, plist, len, base, scale_down);
+
+       sprintf(tmp, "Completion percentiles (%s)", base);
+       frame = gtk_frame_new(tmp);
+       gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+
+       hbox = gtk_hbox_new(FALSE, 3);
+       gtk_container_add(GTK_CONTAINER(frame), hbox);
+
+       gtk_box_pack_start(GTK_BOX(hbox), tree_view, TRUE, FALSE, 3);
+out:
+       if (ovals)
+               free(ovals);
+}
+
+static void gfio_show_lat(GtkWidget *vbox, const char *name, unsigned long min,
+                         unsigned long max, double mean, double dev)
+{
+       const char *base = "(usec)";
+       GtkWidget *hbox, *label, *frame;
+       char *minp, *maxp;
+       char tmp[64];
+
+       if (!usec_to_msec(&min, &max, &mean, &dev))
+               base = "(msec)";
+
+       minp = num2str(min, 6, 1, 0);
+       maxp = num2str(max, 6, 1, 0);
+
+       sprintf(tmp, "%s %s", name, base);
+       frame = gtk_frame_new(tmp);
+       gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+
+       hbox = gtk_hbox_new(FALSE, 3);
+       gtk_container_add(GTK_CONTAINER(frame), hbox);
+
+       label = new_info_label_in_frame(hbox, "Minimum");
+       gtk_label_set_text(GTK_LABEL(label), minp);
+       label = new_info_label_in_frame(hbox, "Maximum");
+       gtk_label_set_text(GTK_LABEL(label), maxp);
+       label = new_info_label_in_frame(hbox, "Average");
+       sprintf(tmp, "%5.02f", mean);
+       gtk_label_set_text(GTK_LABEL(label), tmp);
+       label = new_info_label_in_frame(hbox, "Standard deviation");
+       sprintf(tmp, "%5.02f", dev);
+       gtk_label_set_text(GTK_LABEL(label), tmp);
+
+       free(minp);
+       free(maxp);
+
+}
+
+#define GFIO_CLAT      1
+#define GFIO_SLAT      2
+#define GFIO_LAT       4
+
+static void gfio_show_ddir_status(GtkWidget *mbox, struct group_run_stats *rs,
+                                 struct thread_stat *ts, int ddir)
+{
+       const char *ddir_label[2] = { "Read", "Write" };
+       GtkWidget *frame, *label, *box, *vbox;
+       unsigned long min, max, runt;
+       unsigned long long bw, iops;
+       unsigned int flags = 0;
+       double mean, dev;
+       char *io_p, *bw_p, *iops_p;
+       int i2p;
+
+       if (!ts->runtime[ddir])
+               return;
+
+       i2p = is_power_of_2(rs->kb_base);
+       runt = ts->runtime[ddir];
+
+       bw = (1000 * ts->io_bytes[ddir]) / runt;
+       io_p = num2str(ts->io_bytes[ddir], 6, 1, i2p);
+       bw_p = num2str(bw, 6, 1, i2p);
+
+       iops = (1000 * (uint64_t)ts->total_io_u[ddir]) / runt;
+       iops_p = num2str(iops, 6, 1, 0);
+
+       box = gtk_hbox_new(FALSE, 3);
+       gtk_box_pack_start(GTK_BOX(mbox), box, TRUE, FALSE, 3);
+
+       frame = gtk_frame_new(ddir_label[ddir]);
+       gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 5);
+
+       vbox = gtk_vbox_new(FALSE, 3);
+       gtk_container_add(GTK_CONTAINER(frame), vbox);
+
+       box = gtk_hbox_new(FALSE, 3);
+       gtk_box_pack_start(GTK_BOX(vbox), box, TRUE, FALSE, 3);
+
+       label = new_info_label_in_frame(box, "IO");
+       gtk_label_set_text(GTK_LABEL(label), io_p);
+       label = new_info_label_in_frame(box, "Bandwidth");
+       gtk_label_set_text(GTK_LABEL(label), bw_p);
+       label = new_info_label_in_frame(box, "IOPS");
+       gtk_label_set_text(GTK_LABEL(label), iops_p);
+       label = new_info_label_in_frame(box, "Runtime (msec)");
+       label_set_int_value(label, ts->runtime[ddir]);
+
+       if (calc_lat(&ts->slat_stat[ddir], &min, &max, &mean, &dev))
+               flags |= GFIO_SLAT;
+       if (calc_lat(&ts->clat_stat[ddir], &min, &max, &mean, &dev))
+               flags |= GFIO_CLAT;
+       if (calc_lat(&ts->lat_stat[ddir], &min, &max, &mean, &dev))
+               flags |= GFIO_LAT;
+
+       if (flags) {
+               frame = gtk_frame_new("Latency");
+               gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+
+               vbox = gtk_vbox_new(FALSE, 3);
+               gtk_container_add(GTK_CONTAINER(frame), vbox);
+
+               if (flags & GFIO_SLAT)
+                       gfio_show_lat(vbox, "Submission latency", min, max, mean, dev);
+               if (flags & GFIO_CLAT)
+                       gfio_show_lat(vbox, "Completion latency", min, max, mean, dev);
+               if (flags & GFIO_LAT)
+                       gfio_show_lat(vbox, "Total latency", min, max, mean, dev);
+       }
+
+       if (ts->clat_percentiles)
+               gfio_show_clat_percentiles(vbox, ts, ddir);
+
+       if (calc_lat(&ts->bw_stat[ddir], &min, &max, &mean, &dev)) {
+               double p_of_agg = 100.0;
+               const char *bw_str = "KB";
+               char tmp[32];
+
+               if (rs->agg[ddir]) {
+                       p_of_agg = mean * 100 / (double) rs->agg[ddir];
+                       if (p_of_agg > 100.0)
+                               p_of_agg = 100.0;
+               }
+
+               if (mean > 999999.9) {
+                       min /= 1000.0;
+                       max /= 1000.0;
+                       mean /= 1000.0;
+                       dev /= 1000.0;
+                       bw_str = "MB";
+               }
+
+               frame = gtk_frame_new("Bandwidth");
+               gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 5);
+
+               vbox = gtk_vbox_new(FALSE, 3);
+               gtk_container_add(GTK_CONTAINER(frame), vbox);
+
+               label = new_info_label_in_frame(vbox, "Bandwidth");
+               gtk_label_set_text(GTK_LABEL(label), bw_str);
+               label = new_info_label_in_frame(vbox, "Minimum");
+               label_set_int_value(label, min);
+               label = new_info_label_in_frame(vbox, "Maximum");
+               label_set_int_value(label, max);
+               label = new_info_label_in_frame(vbox, "Percentage of jobs");
+               sprintf(tmp, "%3.2f%%", p_of_agg);
+               gtk_label_set_text(GTK_LABEL(label), tmp);
+               label = new_info_label_in_frame(vbox, "Average");
+               sprintf(tmp, "%5.02f", mean);
+               gtk_label_set_text(GTK_LABEL(label), tmp);
+               label = new_info_label_in_frame(vbox, "Standard deviation");
+               sprintf(tmp, "%5.02f", dev);
+               gtk_label_set_text(GTK_LABEL(label), tmp);
+       }
+
+       free(io_p);
+       free(bw_p);
+       free(iops_p);
+}
+
+static void gfio_display_ts(struct fio_client *client, struct thread_stat *ts,
+                           struct group_run_stats *rs)
+{
+       GtkWidget *dialog, *box, *vbox, *entry, *content;
+       struct gui *ui = client->client_data;
+
+       gdk_threads_enter();
+
+       dialog = gtk_dialog_new_with_buttons("Results", GTK_WINDOW(ui->window),
+                       GTK_DIALOG_DESTROY_WITH_PARENT,
+                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
+
+       g_signal_connect_swapped(dialog, "response",
+                             G_CALLBACK(gtk_widget_destroy),
+                             dialog);
+
+       content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+       vbox = gtk_vbox_new(FALSE, 3);
+       gtk_container_add(GTK_CONTAINER(content), vbox);
+
+       box = gtk_hbox_new(TRUE, 3);
+       gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 5);
+
+       entry = new_info_entry_in_frame(box, "Name");
+       gtk_entry_set_text(GTK_ENTRY(entry), ts->name);
+       if (strlen(ts->description)) {
+               entry = new_info_entry_in_frame(box, "Description");
+               gtk_entry_set_text(GTK_ENTRY(entry), ts->description);
+       }
+       entry = new_info_entry_in_frame(box, "Group ID");
+       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");
+       entry_set_int_value(entry, ts->error);
+       entry = new_info_entry_in_frame(box, "PID");
+       entry_set_int_value(entry, ts->pid);
+
+       if (ts->io_bytes[DDIR_READ])
+               gfio_show_ddir_status(vbox, rs, ts, DDIR_READ);
+       if (ts->io_bytes[DDIR_WRITE])
+               gfio_show_ddir_status(vbox, rs, ts, DDIR_WRITE);
+
+       gtk_widget_show_all(dialog);
+
+       gdk_threads_leave();
+}
+
+static void gfio_text_op(struct fio_client *client, struct fio_net_cmd *cmd)
 {
+#if 0
        GtkTextBuffer *buffer;
        GtkTextIter end;
 
@@ -127,6 +535,9 @@ static void gfio_text_op(struct fio_client *client,
        gdk_threads_leave();
        gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(ui.textview),
                                        &end, 0.0, FALSE, 0.0,0.0);
+#else
+       fio_client_ops.text_op(client, cmd);
+#endif
 }
 
 static void gfio_disk_util_op(struct fio_client *client, struct fio_net_cmd *cmd)
@@ -135,16 +546,39 @@ static void gfio_disk_util_op(struct fio_client *client, struct fio_net_cmd *cmd
        fio_client_ops.disk_util(client, cmd);
 }
 
-static void gfio_thread_status_op(struct fio_net_cmd *cmd)
+extern int sum_stat_clients;
+extern struct thread_stat client_ts;
+extern struct group_run_stats client_gs;
+
+static int sum_stat_nr;
+
+static void gfio_thread_status_op(struct fio_client *client,
+                                 struct fio_net_cmd *cmd)
 {
-       printf("gfio_thread_status_op called\n");
-       fio_client_ops.thread_status(cmd);
+       struct cmd_ts_pdu *p = (struct cmd_ts_pdu *) cmd->payload;
+
+       gfio_display_ts(client, &p->ts, &p->rs);
+
+       if (sum_stat_clients == 1)
+               return;
+
+       sum_thread_stats(&client_ts, &p->ts, sum_stat_nr);
+       sum_group_stats(&client_gs, &p->rs);
+
+       client_ts.members++;
+       client_ts.groupid = p->ts.groupid;
+
+       if (++sum_stat_nr == sum_stat_clients) {
+               strcpy(client_ts.name, "All clients");
+               gfio_display_ts(client, &client_ts, &client_gs);
+       }
 }
 
-static void gfio_group_stats_op(struct fio_net_cmd *cmd)
+static void gfio_group_stats_op(struct fio_client *client,
+                               struct fio_net_cmd *cmd)
 {
        printf("gfio_group_stats_op called\n");
-       fio_client_ops.group_stats(cmd);
+       fio_client_ops.group_stats(client, cmd);
 }
 
 static void gfio_update_eta(struct jobs_eta *je)
@@ -165,9 +599,9 @@ static void gfio_update_eta(struct jobs_eta *je)
        }
 
        sprintf(tmp, "%u", je->nr_running);
-       gtk_label_set_text(GTK_LABEL(ui.eta.jobs), tmp);
+       gtk_entry_set_text(GTK_ENTRY(ui.eta.jobs), tmp);
        sprintf(tmp, "%u", je->files_open);
-       gtk_label_set_text(GTK_LABEL(ui.eta.files), tmp);
+       gtk_entry_set_text(GTK_ENTRY(ui.eta.files), tmp);
 
 #if 0
        if (je->m_rate[0] || je->m_rate[1] || je->t_rate[0] || je->t_rate[1]) {
@@ -176,17 +610,17 @@ static void gfio_update_eta(struct jobs_eta *je)
 
                mr = num2str(je->m_rate, 4, 0, i2p);
                tr = num2str(je->t_rate, 4, 0, i2p);
-               gtk_label_set_text(GTK_LABEL(ui.eta.
+               gtk_entry_set_text(GTK_ENTRY(ui.eta);
                p += sprintf(p, ", CR=%s/%s KB/s", tr, mr);
                free(tr);
                free(mr);
        } else if (je->m_iops || je->t_iops)
                p += sprintf(p, ", CR=%d/%d IOPS", je->t_iops, je->m_iops);
-#else
-       gtk_label_set_text(GTK_LABEL(ui.eta.cr_bw), "---");
-       gtk_label_set_text(GTK_LABEL(ui.eta.cr_iops), "---");
-       gtk_label_set_text(GTK_LABEL(ui.eta.cw_bw), "---");
-       gtk_label_set_text(GTK_LABEL(ui.eta.cw_iops), "---");
+
+       gtk_entry_set_text(GTK_ENTRY(ui.eta.cr_bw), "---");
+       gtk_entry_set_text(GTK_ENTRY(ui.eta.cr_iops), "---");
+       gtk_entry_set_text(GTK_ENTRY(ui.eta.cw_bw), "---");
+       gtk_entry_set_text(GTK_ENTRY(ui.eta.cw_iops), "---");
 #endif
 
        if (je->eta_sec != INT_MAX && je->nr_running) {
@@ -207,10 +641,10 @@ static void gfio_update_eta(struct jobs_eta *je)
                iops_str[0] = num2str(je->iops[0], 4, 1, 0);
                iops_str[1] = num2str(je->iops[1], 4, 1, 0);
 
-               gtk_label_set_text(GTK_LABEL(ui.eta.read_bw), rate_str[0]);
-               gtk_label_set_text(GTK_LABEL(ui.eta.read_iops), iops_str[0]);
-               gtk_label_set_text(GTK_LABEL(ui.eta.write_bw), rate_str[1]);
-               gtk_label_set_text(GTK_LABEL(ui.eta.write_iops), iops_str[1]);
+               gtk_entry_set_text(GTK_ENTRY(ui.eta.read_bw), rate_str[0]);
+               gtk_entry_set_text(GTK_ENTRY(ui.eta.read_iops), iops_str[0]);
+               gtk_entry_set_text(GTK_ENTRY(ui.eta.write_bw), rate_str[1]);
+               gtk_entry_set_text(GTK_ENTRY(ui.eta.write_iops), iops_str[1]);
 
                free(rate_str[0]);
                free(rate_str[1]);
@@ -227,19 +661,6 @@ static void gfio_update_eta(struct jobs_eta *je)
        gfio_update_thread_status(output, perc);
 }
 
-static void gfio_eta_op(struct fio_client *client, struct fio_net_cmd *cmd)
-{
-       struct jobs_eta *je = (struct jobs_eta *) cmd->payload;
-       struct client_eta *eta = (struct client_eta *) (uintptr_t) cmd->tag;
-
-       client->eta_in_flight = NULL;
-       flist_del_init(&client->eta_list);
-
-       fio_client_convert_jobs_eta(je);
-       fio_client_sum_jobs_eta(&eta->eta, je);
-       fio_client_dec_jobs_eta(eta, gfio_update_eta);
-}
-
 static void gfio_probe_op(struct fio_client *client, struct fio_net_cmd *cmd)
 {
        struct cmd_probe_pdu *probe = (struct cmd_probe_pdu *) cmd->payload;
@@ -286,14 +707,72 @@ static void gfio_quit_op(struct fio_client *client)
        gfio_set_connected(ui, 0);
 }
 
+static void gfio_add_job_op(struct fio_client *client, struct fio_net_cmd *cmd)
+{
+       struct cmd_add_job_pdu *p = (struct cmd_add_job_pdu *) cmd->payload;
+       struct gui *ui = client->client_data;
+       char tmp[8];
+       int i;
+
+       p->iodepth              = le32_to_cpu(p->iodepth);
+       p->rw                   = le32_to_cpu(p->rw);
+
+       for (i = 0; i < 2; i++) {
+               p->min_bs[i]    = le32_to_cpu(p->min_bs[i]);
+               p->max_bs[i]    = le32_to_cpu(p->max_bs[i]);
+       }
+
+       p->numjobs              = le32_to_cpu(p->numjobs);
+       p->group_reporting      = le32_to_cpu(p->group_reporting);
+
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.name), (gchar *) p->jobname);
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.iotype), ddir_str(p->rw));
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.ioengine), (gchar *) p->ioengine);
+
+       sprintf(tmp, "%u", p->iodepth);
+       gtk_entry_set_text(GTK_ENTRY(ui->eta.iodepth), tmp);
+}
+
+static void gfio_client_timed_out(struct fio_client *client)
+{
+       struct gui *ui = client->client_data;
+       GtkWidget *dialog, *label, *content;
+       char buf[256];
+
+       gdk_threads_enter();
+
+       gfio_set_connected(ui, 0);
+       clear_ui_info(ui);
+
+       sprintf(buf, "Client %s: timeout talking to server.\n", client->hostname);
+
+       dialog = gtk_dialog_new_with_buttons("Timed out!",
+                       GTK_WINDOW(ui->window),
+                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                       GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+       content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+       label = gtk_label_new((const gchar *) buf);
+       gtk_container_add(GTK_CONTAINER(content), label);
+       gtk_widget_show_all(dialog);
+       gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
+
+       gtk_dialog_run(GTK_DIALOG(dialog));
+       gtk_widget_destroy(dialog);
+
+       gdk_threads_leave();
+}
+
 struct client_ops gfio_client_ops = {
        .text_op                = gfio_text_op,
        .disk_util              = gfio_disk_util_op,
        .thread_status          = gfio_thread_status_op,
        .group_stats            = gfio_group_stats_op,
-       .eta                    = gfio_eta_op,
+       .eta                    = gfio_update_eta,
        .probe                  = gfio_probe_op,
        .quit                   = gfio_quit_op,
+       .add_job                = gfio_add_job_op,
+       .timed_out              = gfio_client_timed_out,
        .stay_connected         = 1,
 };
 
@@ -305,9 +784,7 @@ static void quit_clicked(__attribute__((unused)) GtkWidget *widget,
 
 static void *job_thread(void *arg)
 {
-       printf("job thread starts\n");
        fio_handle_clients(&gfio_client_ops);
-       printf("job thread exits\n");
        return NULL;
 }
 
@@ -350,17 +827,24 @@ static void start_job_clicked(__attribute__((unused)) GtkWidget *widget,
        start_job_thread(ui);
 }
 
-static void connect_clicked(__attribute__((unused)) GtkWidget *widget,
-                gpointer data)
+static void file_open(GtkWidget *w, gpointer data);
+
+static void connect_clicked(GtkWidget *widget, gpointer data)
 {
        struct gui *ui = data;
 
        if (!ui->connected) {
+               if (!ui->nr_job_files)
+                       file_open(widget, data);
+               gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ui->thread_status_pb), "No jobs running");
                fio_clients_connect();
                pthread_create(&ui->t, NULL, job_thread, NULL);
                gfio_set_connected(ui, 1);
-       } else
+       } else {
+               fio_clients_terminate();
                gfio_set_connected(ui, 0);
+               clear_ui_info(ui);
+       }
 }
 
 static void add_button(struct gui *ui, int i, GtkWidget *buttonbox,
@@ -392,7 +876,7 @@ static void on_info_bar_response(GtkWidget *widget, gint response,
        }
 }
 
-void report_error(GErrorerror)
+void report_error(GError *error)
 {
        if (ui.error_info_bar == NULL) {
                ui.error_info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_OK,
@@ -415,11 +899,102 @@ void report_error(GError* error)
        }
 }
 
+static int get_connection_details(char **host, int *port, int *type,
+                                 int *server_start)
+{
+       GtkWidget *dialog, *box, *vbox, *hentry, *hbox, *frame, *pentry, *combo;
+       GtkWidget *button;
+       char *typeentry;
+
+       dialog = gtk_dialog_new_with_buttons("Connection details",
+                       GTK_WINDOW(ui.window),
+                       GTK_DIALOG_DESTROY_WITH_PARENT,
+                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                       GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
+
+       frame = gtk_frame_new("Hostname / socket name");
+       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);
+       gtk_container_add(GTK_CONTAINER(frame), box);
+
+       hbox = gtk_hbox_new(TRUE, 10);
+       gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
+       hentry = gtk_entry_new();
+       gtk_entry_set_text(GTK_ENTRY(hentry), "localhost");
+       gtk_box_pack_start(GTK_BOX(hbox), hentry, TRUE, TRUE, 0);
+
+       frame = gtk_frame_new("Port");
+       gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+       box = gtk_vbox_new(FALSE, 10);
+       gtk_container_add(GTK_CONTAINER(frame), box);
+
+       hbox = gtk_hbox_new(TRUE, 4);
+       gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
+       pentry = create_spinbutton(hbox, 1, 65535, FIO_NET_PORT);
+
+       frame = gtk_frame_new("Type");
+       gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+       box = gtk_vbox_new(FALSE, 10);
+       gtk_container_add(GTK_CONTAINER(frame), box);
+
+       hbox = gtk_hbox_new(TRUE, 4);
+       gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
+
+       combo = gtk_combo_box_text_new();
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), "IPv4");
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), "IPv6");
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), "local socket");
+       gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
+
+       gtk_container_add(GTK_CONTAINER(hbox), combo);
+
+       frame = gtk_frame_new("Options");
+       gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+       box = gtk_vbox_new(FALSE, 10);
+       gtk_container_add(GTK_CONTAINER(frame), box);
+
+       hbox = gtk_hbox_new(TRUE, 4);
+       gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
+
+       button = gtk_check_button_new_with_label("Auto-spawn fio backend");
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), 1);
+       gtk_widget_set_tooltip_text(button, "When running fio locally, it is necessary to have the backend running on the same system. If this is checked, gfio will start the backend automatically for you if it isn't already running.");
+       gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 6);
+
+       gtk_widget_show_all(dialog);
+
+       if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
+               gtk_widget_destroy(dialog);
+               return 1;
+       }
+
+       *host = strdup(gtk_entry_get_text(GTK_ENTRY(hentry)));
+       *port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pentry));
+
+       typeentry = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo));
+       if (!typeentry || !strncmp(typeentry, "IPv4", 4))
+               *type = Fio_client_ipv4;
+       else if (!strncmp(typeentry, "IPv6", 4))
+               *type = Fio_client_ipv6;
+       else
+               *type = Fio_client_socket;
+       g_free(typeentry);
+
+       *server_start = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+
+       gtk_widget_destroy(dialog);
+       return 0;
+}
+
 static void file_open(GtkWidget *w, gpointer data)
 {
        GtkWidget *dialog;
        GSList *filenames, *fn_glist;
        GtkFileFilter *filter;
+       char *host;
+       int port, type, server_start;
 
        dialog = gtk_file_chooser_dialog_new("Open File",
                GTK_WINDOW(ui.window),
@@ -442,43 +1017,35 @@ static void file_open(GtkWidget *w, gpointer data)
        }
 
        fn_glist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
+
+       gtk_widget_destroy(dialog);
+
+       if (get_connection_details(&host, &port, &type, &server_start))
+               goto err;
+
        filenames = fn_glist;
        while (filenames != NULL) {
-               const char *hostname;
-               char *typeentry;
-               gint port;
-               int type;
-
                ui.job_files = realloc(ui.job_files, (ui.nr_job_files + 1) * sizeof(char *));
                ui.job_files[ui.nr_job_files] = strdup(filenames->data);
                ui.nr_job_files++;
 
-               hostname = gtk_entry_get_text(GTK_ENTRY(ui.hostname_entry));
-               port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ui.port_button));
-               typeentry = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(ui.hostname_combo_box));
-               if (!typeentry || !strncmp(typeentry, "IPv4", 4))
-                       type = Fio_client_ipv4;
-               else if (!strncmp(typeentry, "IPv6", 4))
-                       type = Fio_client_ipv6;
-               else
-                       type = Fio_client_socket;
-               g_free(typeentry);
-
-               ui.client = fio_client_add_explicit(hostname, type, port);
-               ui.client->client_data = &ui;
-#if 0
-               if (error) {
+               ui.client = fio_client_add_explicit(&gfio_client_ops, host, type, port);
+               if (!ui.client) {
+                       GError *error;
+
+                       error = g_error_new(g_quark_from_string("fio"), 1,
+                                       "Failed to add client %s", host);
                        report_error(error);
                        g_error_free(error);
-                       error = NULL;
                }
-#endif
+               ui.client->client_data = &ui;
                        
                g_free(filenames->data);
                filenames = g_slist_next(filenames);
        }
+       free(host);
+err:
        g_slist_free(fn_glist);
-       gtk_widget_destroy(dialog);
 }
 
 static void file_save(GtkWidget *w, gpointer data)
@@ -505,6 +1072,49 @@ static void file_save(GtkWidget *w, gpointer data)
        gtk_widget_destroy(dialog);
 }
 
+static void preferences(GtkWidget *w, gpointer data)
+{
+       GtkWidget *dialog, *frame, *box, **buttons;
+       int i;
+
+       dialog = gtk_dialog_new_with_buttons("Preferences",
+               GTK_WINDOW(ui.window),
+               GTK_DIALOG_DESTROY_WITH_PARENT,
+               GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+               NULL);
+
+       frame = gtk_frame_new("Debug logging");
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+       box = gtk_hbox_new(FALSE, 6);
+       gtk_container_add(GTK_CONTAINER(frame), box);
+
+       buttons = malloc(sizeof(GtkWidget *) * FD_DEBUG_MAX);
+
+       for (i = 0; i < FD_DEBUG_MAX; i++) {
+               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);
+       }
+
+       gtk_widget_show_all(dialog);
+
+       if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
+               gtk_widget_destroy(dialog);
+               return;
+       }
+
+       for (i = 0; i < FD_DEBUG_MAX; i++) {
+               int set;
+
+               set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[i]));
+               if (set)
+                       fio_debug |= (1UL << i);
+       }
+
+       gtk_widget_destroy(dialog);
+}
+
 static void about_dialog(GtkWidget *w, gpointer data)
 {
        gtk_show_about_dialog(NULL,
@@ -520,12 +1130,13 @@ static void about_dialog(GtkWidget *w, gpointer data)
 }
 
 static GtkActionEntry menu_items[] = {
-        { "FileMenuAction", GTK_STOCK_FILE, "File", NULL, NULL, NULL},
-        { "HelpMenuAction", GTK_STOCK_HELP, "Help", NULL, NULL, NULL},
-       { "OpenFile",       GTK_STOCK_OPEN, NULL,   "<Control>O", NULL, G_CALLBACK(file_open) },
-        { "SaveFile",       GTK_STOCK_SAVE, NULL,   "<Control>S", NULL, G_CALLBACK(file_save) },
-        { "Quit",           GTK_STOCK_QUIT, NULL,   "<Control>Q", NULL, G_CALLBACK(quit_clicked) },
-       { "About",          GTK_STOCK_ABOUT, NULL,  NULL, NULL, G_CALLBACK(about_dialog) },
+       { "FileMenuAction", GTK_STOCK_FILE, "File", NULL, NULL, NULL},
+       { "HelpMenuAction", GTK_STOCK_HELP, "Help", NULL, NULL, NULL},
+       { "OpenFile", GTK_STOCK_OPEN, NULL,   "<Control>O", NULL, G_CALLBACK(file_open) },
+       { "SaveFile", GTK_STOCK_SAVE, NULL,   "<Control>S", NULL, G_CALLBACK(file_save) },
+       { "Preferences", GTK_STOCK_PREFERENCES, NULL, "<Control>p", NULL, G_CALLBACK(preferences) },
+       { "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]);
 
@@ -536,6 +1147,8 @@ static const gchar *ui_string = " \
                                <menuitem name=\"Open\" action=\"OpenFile\" /> \
                                <menuitem name=\"Save\" action=\"SaveFile\" /> \
                                <separator name=\"Separator\"/> \
+                               <menuitem name=\"Preferences\" action=\"Preferences\" /> \
+                               <separator name=\"Separator2\"/> \
                                <menuitem name=\"Quit\" action=\"Quit\" /> \
                        </menu> \
                        <menu name=\"Help\" action=\"HelpMenuAction\"> \
@@ -566,53 +1179,6 @@ void gfio_ui_setup(GtkSettings *settings, GtkWidget *menubar,
         gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
 }
 
-static GtkWidget *new_info_label_in_frame(GtkWidget *box, const char *label)
-{
-       GtkWidget *label_widget;
-       GtkWidget *frame;
-
-       frame = gtk_frame_new(label);
-       label_widget = gtk_label_new(NULL);
-       gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 3);
-       gtk_container_add(GTK_CONTAINER(frame), label_widget);
-
-       return label_widget;
-}
-
-static GtkWidget *create_text_entry(GtkWidget *hbox, GtkWidget *label, const char *defval)
-{
-       GtkWidget *text, *box;
-
-       gtk_container_add(GTK_CONTAINER(hbox), label);
-
-       box = gtk_hbox_new(FALSE, 3);
-       gtk_container_add(GTK_CONTAINER(hbox), box);
-
-       text = gtk_entry_new();
-       gtk_box_pack_start(GTK_BOX(box), text, TRUE, TRUE, 0);
-       gtk_entry_set_text(GTK_ENTRY(text), "localhost");
-
-       return text;
-}
-
-static GtkWidget *create_spinbutton(GtkWidget *hbox, GtkWidget *label, double min, double max, double defval)
-{
-       GtkWidget *button, *box;
-
-       gtk_container_add(GTK_CONTAINER(hbox), label);
-
-       box = gtk_hbox_new(FALSE, 3);
-       gtk_container_add(GTK_CONTAINER(hbox), box);
-
-       button = gtk_spin_button_new_with_range(min, max, 1.0);
-       gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
-
-       gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(button), GTK_UPDATE_IF_VALID);
-       gtk_spin_button_set_value(GTK_SPIN_BUTTON(button), defval);
-
-       return button;
-}
-
 static void init_ui(int *argc, char **argv[], struct gui *ui)
 {
        GtkSettings *settings;
@@ -625,7 +1191,7 @@ 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 (!g_thread_supported ())
+       if (!g_thread_supported())
                g_thread_init(NULL);
        gdk_threads_init();
 
@@ -657,29 +1223,6 @@ static void init_ui(int *argc, char **argv[], struct gui *ui)
        gtk_container_add(GTK_CONTAINER(ui->topalign), ui->topvbox);
        gtk_box_pack_start(GTK_BOX(ui->vbox), ui->topalign, FALSE, FALSE, 0);
 
-       /*
-        * Set up hostname label + entry, port label + entry,
-        */
-       ui->hostname_hbox = gtk_hbox_new(FALSE, 0);
-
-       ui->hostname_label = gtk_label_new("Hostname:");
-       ui->hostname_entry = create_text_entry(ui->hostname_hbox, ui->hostname_label, "localhost");
-
-       ui->port_label = gtk_label_new("Port:");
-       ui->port_button = create_spinbutton(ui->hostname_hbox, ui->port_label, 1, 65535, FIO_NET_PORT);
-
-       /*
-        * Set up combo box for address type
-        */
-       ui->hostname_combo_box = gtk_combo_box_text_new();
-       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ui->hostname_combo_box), "IPv4");
-       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ui->hostname_combo_box), "IPv6");
-       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ui->hostname_combo_box), "local socket");
-       gtk_combo_box_set_active(GTK_COMBO_BOX(ui->hostname_combo_box), 0);
-
-       gtk_container_add(GTK_CONTAINER(ui->hostname_hbox), ui->hostname_combo_box);
-       gtk_container_add(GTK_CONTAINER(ui->topvbox), ui->hostname_hbox);
-
        probe = gtk_frame_new("Job");
        gtk_box_pack_start(GTK_BOX(ui->topvbox), probe, TRUE, FALSE, 3);
        probe_frame = gtk_vbox_new(FALSE, 3);
@@ -694,22 +1237,34 @@ static void init_ui(int *argc, char **argv[], struct gui *ui)
 
        probe_box = gtk_hbox_new(FALSE, 3);
        gtk_box_pack_start(GTK_BOX(probe_frame), probe_box, TRUE, FALSE, 3);
-       ui->eta.jobs = new_info_label_in_frame(probe_box, "Jobs");
-       ui->eta.files = new_info_label_in_frame(probe_box, "Open files");
+
+       ui->eta.name = new_info_entry_in_frame(probe_box, "Name");
+       ui->eta.iotype = new_info_entry_in_frame(probe_box, "IO");
+       ui->eta.ioengine = new_info_entry_in_frame(probe_box, "IO Engine");
+       ui->eta.iodepth = new_info_entry_in_frame(probe_box, "IO Depth");
+       ui->eta.jobs = new_info_entry_in_frame(probe_box, "Jobs");
+       ui->eta.files = new_info_entry_in_frame(probe_box, "Open files");
 
        probe_box = gtk_hbox_new(FALSE, 3);
        gtk_box_pack_start(GTK_BOX(probe_frame), probe_box, TRUE, FALSE, 3);
-       ui->eta.read_bw = new_info_label_in_frame(probe_box, "Read BW");
-       ui->eta.read_iops = new_info_label_in_frame(probe_box, "IOPS");
-       ui->eta.cr_bw = new_info_label_in_frame(probe_box, "Commit BW");
-       ui->eta.cr_iops = new_info_label_in_frame(probe_box, "Commit IOPS");
+       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");
 
+       /*
+        * Only add this if we have a commit rate
+        */
+#if 0
        probe_box = gtk_hbox_new(FALSE, 3);
        gtk_box_pack_start(GTK_BOX(probe_frame), probe_box, TRUE, FALSE, 3);
-       ui->eta.write_bw = new_info_label_in_frame(probe_box, "Write BW");
-       ui->eta.write_iops = new_info_label_in_frame(probe_box, "IOPS");
+
+       ui->eta.cr_bw = new_info_label_in_frame(probe_box, "Commit BW");
+       ui->eta.cr_iops = new_info_label_in_frame(probe_box, "Commit IOPS");
+
        ui->eta.cw_bw = new_info_label_in_frame(probe_box, "Commit BW");
        ui->eta.cw_iops = new_info_label_in_frame(probe_box, "Commit IOPS");
+#endif
 
        /*
         * Add a text box for text op messages 
@@ -743,7 +1298,7 @@ static void init_ui(int *argc, char **argv[], struct gui *ui)
         */
        ui->thread_status_pb = gtk_progress_bar_new();
        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ui->thread_status_pb), 0.0);
-       gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ui->thread_status_pb), "No jobs running");
+       gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ui->thread_status_pb), "No connections");
        gtk_container_add(GTK_CONTAINER(ui->buttonbox), ui->thread_status_pb);
 
 
@@ -757,7 +1312,6 @@ int main(int argc, char *argv[], char *envp[])
        if (fio_init_options())
                return 1;
 
-       fio_debug = ~0UL;
        init_ui(&argc, &argv, &ui);
 
        gdk_threads_enter();