gfio.c revision 25927259f482b0288d962e36dbfd33ec90a69521
1/* 2 * gfio - gui front end for fio - the flexible io tester 3 * 4 * Copyright (C) 2012 Stephen M. Cameron <stephenmcameron@gmail.com> 5 * 6 * The license below covers all files distributed with fio unless otherwise 7 * noted in the file itself. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23#include <locale.h> 24 25#include <gtk/gtk.h> 26 27#include "fio_initialization.h" 28#include "fio.h" 29 30#define ARRAYSIZE(x) (sizeof((x)) / (sizeof((x)[0]))) 31 32typedef void (*clickfunction)(GtkWidget *widget, gpointer data); 33 34static void quit_clicked(GtkWidget *widget, gpointer data); 35static void start_job_clicked(GtkWidget *widget, gpointer data); 36 37static struct button_spec { 38 const char *buttontext; 39 clickfunction f; 40 const char *tooltiptext; 41} buttonspeclist[] = { 42#define START_JOB_BUTTON 0 43 { "Start Job", 44 start_job_clicked, 45 "Send current fio job to fio server to be executed" }, 46#define QUIT_BUTTON 1 47 { "Quit", quit_clicked, "Quit gfio" }, 48}; 49 50struct gui { 51 GtkWidget *window; 52 GtkWidget *buttonbox; 53 GtkWidget *button[ARRAYSIZE(buttonspeclist)]; 54 pthread_t t; 55}; 56 57static void gfio_text_op(struct fio_client *client, 58 FILE *f, __u16 pdu_len, const char *buf) 59{ 60 printf("gfio_text_op called\n"); 61 fio_client_ops.text_op(client, f, pdu_len, buf); 62} 63 64static void gfio_disk_util_op(struct fio_client *client, struct fio_net_cmd *cmd) 65{ 66 printf("gfio_disk_util_op called\n"); 67 fio_client_ops.disk_util(client, cmd); 68} 69 70static void gfio_thread_status_op(struct fio_net_cmd *cmd) 71{ 72 printf("gfio_thread_status_op called\n"); 73 fio_client_ops.thread_status(cmd); 74} 75 76static void gfio_group_stats_op(struct fio_net_cmd *cmd) 77{ 78 printf("gfio_group_stats_op called\n"); 79 fio_client_ops.group_stats(cmd); 80} 81 82static void gfio_eta_op(struct fio_client *client, struct fio_net_cmd *cmd) 83{ 84 printf("gfio_eta_op called\n"); 85 fio_client_ops.eta(client, cmd); 86} 87 88static void gfio_probe_op(struct fio_client *client, struct fio_net_cmd *cmd) 89{ 90 printf("gfio_probe_op called\n"); 91 fio_client_ops.probe(client, cmd); 92} 93 94struct client_ops gfio_client_ops = { 95 gfio_text_op, 96 gfio_disk_util_op, 97 gfio_thread_status_op, 98 gfio_group_stats_op, 99 gfio_eta_op, 100 gfio_probe_op, 101}; 102 103static void quit_clicked(__attribute__((unused)) GtkWidget *widget, 104 __attribute__((unused)) gpointer data) 105{ 106 gtk_main_quit(); 107} 108 109static void *job_thread(void *arg) 110{ 111 struct gui *ui = arg; 112 113 fio_handle_clients(&gfio_client_ops); 114 gtk_widget_set_sensitive(ui->button[START_JOB_BUTTON], 1); 115 return NULL; 116} 117 118static void start_job_thread(pthread_t *t, struct gui *ui) 119{ 120 pthread_create(t, NULL, job_thread, ui); 121} 122 123static void start_job_clicked(__attribute__((unused)) GtkWidget *widget, 124 gpointer data) 125{ 126 struct gui *ui = data; 127 128 printf("Start job button was clicked.\n"); 129 gtk_widget_set_sensitive(ui->button[START_JOB_BUTTON], 0); 130 start_job_thread(&ui->t, ui); 131} 132 133static void add_button(struct gui *ui, int i, GtkWidget *buttonbox, 134 struct button_spec *buttonspec) 135{ 136 ui->button[i] = gtk_button_new_with_label(buttonspec->buttontext); 137 g_signal_connect(ui->button[i], "clicked", G_CALLBACK (buttonspec->f), ui); 138 gtk_box_pack_start(GTK_BOX (ui->buttonbox), ui->button[i], TRUE, TRUE, 0); 139 gtk_widget_set_tooltip_text(ui->button[i], buttonspeclist[i].tooltiptext); 140} 141 142static void add_buttons(struct gui *ui, 143 struct button_spec *buttonlist, 144 int nbuttons) 145{ 146 int i; 147 148 ui->buttonbox = gtk_hbox_new(FALSE, 0); 149 gtk_container_add(GTK_CONTAINER (ui->window), ui->buttonbox); 150 for (i = 0; i < nbuttons; i++) 151 add_button(ui, i, ui->buttonbox, &buttonlist[i]); 152} 153 154static void init_ui(int *argc, char **argv[], struct gui *ui) 155{ 156 gtk_init(argc, argv); 157 158 ui->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 159 gtk_window_set_title(GTK_WINDOW(ui->window), "fio"); 160 gtk_window_set_default_size(GTK_WINDOW(ui->window), 700, 500); 161 162 g_signal_connect(ui->window, "delete-event", G_CALLBACK (quit_clicked), NULL); 163 g_signal_connect(ui->window, "destroy", G_CALLBACK (quit_clicked), NULL); 164 165 add_buttons(ui, buttonspeclist, ARRAYSIZE(buttonspeclist)); 166 gtk_widget_show_all(ui->window); 167} 168 169int main(int argc, char *argv[], char *envp[]) 170{ 171 struct gui ui; 172 173 if (initialize_fio(envp)) 174 return 1; 175 176 if (parse_options(argc, argv)) 177 return 1; 178 179 init_ui(&argc, &argv, &ui); 180 gtk_main(); 181 return 0; 182} 183