Separate the act of adding and starting a job
authorJens Axboe <axboe@kernel.dk>
Thu, 8 Mar 2012 19:36:28 +0000 (20:36 +0100)
committerJens Axboe <axboe@kernel.dk>
Thu, 8 Mar 2012 19:36:28 +0000 (20:36 +0100)
CMD_JOB or CMD_JOB_LINE only adds the necessary jobs, which will
automatically return the job option info to the client. Let the
client do what it wants with the options, then have the client
send a CMD_RUN command to actually start the jobs.

Next we'll have a command for passing back edited options, so that
the client can update existing options.

This adds a new button to gfio, to note this split of add and run
as well.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
client.c
client.h
fio.c
gfio.c
server.c
server.h

index a77dc9350e0d1d57ffcc2c7f065204b3f9b5b254..10dc53be98f75663f92bd0ebc1a3543dbd67c7ea 100644 (file)
--- a/client.c
+++ b/client.c
@@ -40,15 +40,6 @@ struct client_ops fio_client_ops = {
 
 static struct timeval eta_tv;
 
-enum {
-       Client_created          = 0,
-       Client_connected        = 1,
-       Client_started          = 2,
-       Client_running          = 3,
-       Client_stopped          = 4,
-       Client_exited           = 5,
-};
-
 static FLIST_HEAD(client_list);
 static FLIST_HEAD(eta_list);
 
@@ -469,6 +460,33 @@ int fio_clients_connect(void)
        return !nr_clients;
 }
 
+int fio_start_client(struct fio_client *client)
+{
+       dprint(FD_NET, "client: start %s\n", client->hostname);
+       return fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_RUN, 0, NULL);
+}
+
+int fio_start_all_clients(void)
+{
+       struct fio_client *client;
+       struct flist_head *entry, *tmp;
+       int ret;
+
+       dprint(FD_NET, "client: start all\n");
+
+       flist_for_each_safe(entry, tmp, &client_list) {
+               client = flist_entry(entry, struct fio_client, list);
+
+               ret = fio_start_client(client);
+               if (ret) {
+                       remove_client(client);
+                       continue;
+               }
+       }
+
+       return flist_empty(&client_list);
+}
+
 /*
  * Send file contents to server backend. We could use sendfile(), but to remain
  * more portable lets just read/write the darn thing.
@@ -891,8 +909,8 @@ int fio_handle_client(struct fio_client *client)
        if (!cmd)
                return 0;
 
-       dprint(FD_NET, "client: got cmd op %s from %s\n",
-                               fio_server_op(cmd->opcode), client->hostname);
+       dprint(FD_NET, "client: got cmd op %s from %s (pdu=%u)\n",
+               fio_server_op(cmd->opcode), client->hostname, cmd->pdu_len);
 
        switch (cmd->opcode) {
        case FIO_NET_CMD_QUIT:
index eccac9228849b81161700ce193dbe84e31ceb1ae..9157affd294e21cff5e499efc6e3a4d3ea3bca12 100644 (file)
--- a/client.h
+++ b/client.h
 struct fio_net_cmd;
 struct client_ops;
 
+enum {
+       Client_created          = 0,
+       Client_connected        = 1,
+       Client_started          = 2,
+       Client_running          = 3,
+       Client_stopped          = 4,
+       Client_exited           = 5,
+};
+
 struct fio_client {
        struct flist_head list;
        struct flist_head hash_list;
@@ -93,6 +102,8 @@ enum {
 };
 
 extern int fio_clients_connect(void);
+extern int fio_start_client(struct fio_client *);
+extern int fio_start_all_clients(void);
 extern int fio_clients_send_ini(const char *);
 extern int fio_handle_clients(struct client_ops *);
 extern int fio_client_add(struct client_ops *, const char *, void **);
diff --git a/fio.c b/fio.c
index d628cfcd885d05958d477310661f41f5254446ac..9a6c31a65d912ba39a44f2cae1ce9ec8378146a6 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -45,8 +45,10 @@ int main(int argc, char *argv[], char *envp[])
        if (parse_options(argc, argv))
                return 1;
 
-       if (nr_clients)
+       if (nr_clients) {
+               if (fio_start_all_clients())
+                       return 1;
                return fio_handle_clients(&fio_client_ops);
-       else
+       else
                return fio_backend();
 }
diff --git a/gfio.c b/gfio.c
index 4521f75dfec68c07c54eb33bb80e441b5a55b853..877438a5b130bc330ece62409259b82f31dea450 100644 (file)
--- a/gfio.c
+++ b/gfio.c
@@ -44,6 +44,7 @@ typedef void (*clickfunction)(GtkWidget *widget, gpointer data);
 
 static void connect_clicked(GtkWidget *widget, gpointer data);
 static void start_job_clicked(GtkWidget *widget, gpointer data);
+static void send_clicked(GtkWidget *widget, gpointer data);
 
 static struct button_spec {
        const char *buttontext;
@@ -52,10 +53,11 @@ static struct button_spec {
        const int start_insensitive;
 } buttonspeclist[] = {
 #define CONNECT_BUTTON 0
-#define START_JOB_BUTTON 1
+#define SEND_BUTTON 1
+#define START_JOB_BUTTON 2
        { "Connect", connect_clicked, "Connect to host", 0 },
-       { "Start Job",
-               start_job_clicked,
+       { "Send", send_clicked, "Send job description to host", 1 },
+       { "Start Job", start_job_clicked,
                "Send current fio job to fio server to be executed", 1 },
 };
 
@@ -114,13 +116,14 @@ struct gui {
 
        struct graph *iops_graph;
        struct graph *bandwidth_graph;
-       struct fio_client *client;
+       struct gfio_client *client;
        int nr_job_files;
        char **job_files;
 } ui;
 
 struct gfio_client {
        struct gui *ui;
+       struct fio_client *client;
        GtkWidget *results_widget;
        GtkWidget *disk_util_frame;
        GtkWidget *err_entry;
@@ -223,13 +226,14 @@ static GtkWidget *create_spinbutton(GtkWidget *hbox, double min, double max, dou
 static void gfio_set_connected(struct gui *ui, int connected)
 {
        if (connected) {
-               gtk_widget_set_sensitive(ui->button[START_JOB_BUTTON], 1);
+               gtk_widget_set_sensitive(ui->button[SEND_BUTTON], 1);
                ui->connected = 1;
                gtk_button_set_label(GTK_BUTTON(ui->button[CONNECT_BUTTON]), "Disconnect");
                gtk_widget_set_sensitive(ui->button[CONNECT_BUTTON], 1);
        } else {
                ui->connected = 0;
                gtk_button_set_label(GTK_BUTTON(ui->button[CONNECT_BUTTON]), "Connect");
+               gtk_widget_set_sensitive(ui->button[SEND_BUTTON], 0);
                gtk_widget_set_sensitive(ui->button[START_JOB_BUTTON], 0);
                gtk_widget_set_sensitive(ui->button[CONNECT_BUTTON], 1);
        }
@@ -1321,15 +1325,6 @@ static int send_job_files(struct gui *ui)
        return ret;
 }
 
-static void start_job_thread(struct gui *ui)
-{
-       if (send_job_files(ui)) {
-               printf("Yeah, I didn't really like those options too much.\n");
-               gtk_widget_set_sensitive(ui->button[START_JOB_BUTTON], 1);
-               return;
-       }
-}
-
 static void *server_thread(void *arg)
 {
        is_backend = 1;
@@ -1352,9 +1347,10 @@ static void start_job_clicked(__attribute__((unused)) GtkWidget *widget,
                 gpointer data)
 {
        struct gui *ui = data;
+       struct gfio_client *gc = ui->client;
 
        gtk_widget_set_sensitive(ui->button[START_JOB_BUTTON], 0);
-       start_job_thread(ui);
+       fio_net_send_simple_cmd(gc->client->fd, FIO_NET_CMD_RUN, 0, NULL);
 }
 
 static void file_open(GtkWidget *w, gpointer data);
@@ -1371,6 +1367,7 @@ static void connect_clicked(GtkWidget *widget, gpointer data)
                if (!fio_clients_connect()) {
                        pthread_create(&ui->t, NULL, job_thread, NULL);
                        gtk_widget_set_sensitive(ui->button[CONNECT_BUTTON], 0);
+                       gtk_widget_set_sensitive(ui->button[SEND_BUTTON], 1);
                }
        } else {
                fio_clients_terminate();
@@ -1379,6 +1376,19 @@ static void connect_clicked(GtkWidget *widget, gpointer data)
        }
 }
 
+static void send_clicked(GtkWidget *widget, gpointer data)
+{
+       struct gui *ui = data;
+
+       if (send_job_files(ui)) {
+               printf("Yeah, I didn't really like those options too much.\n");
+               gtk_widget_set_sensitive(ui->button[START_JOB_BUTTON], 1);
+       }
+
+       gtk_widget_set_sensitive(ui->button[SEND_BUTTON], 0);
+       gtk_widget_set_sensitive(ui->button[START_JOB_BUTTON], 1);
+}
+
 static void add_button(struct gui *ui, int i, GtkWidget *buttonbox,
                        struct button_spec *buttonspec)
 {
@@ -1575,6 +1585,9 @@ static void gfio_client_added(struct gui *ui, struct fio_client *client)
        gc = malloc(sizeof(*gc));
        memset(gc, 0, sizeof(*gc));
        gc->ui = ui;
+       gc->client = client;
+
+       ui->client = gc;
 
        client->client_data = gc;
 }
index dfbe3377de92d520ed25a278f41318e27578b52f..10851805a42bb87b95f35aa598fe398d76075ac1 100644 (file)
--- a/server.c
+++ b/server.c
@@ -51,8 +51,9 @@ static const char *fio_server_ops[FIO_NET_CMD_NR] = {
        "START",
        "STOP",
        "DISK_UTIL",
-       "RUN",
+       "SERVER_START",
        "ADD_JOB",
+       "CMD_RUN"
 };
 
 const char *fio_server_op(unsigned int op)
@@ -68,7 +69,7 @@ const char *fio_server_op(unsigned int op)
 
 int fio_send_data(int sk, const void *p, unsigned int len)
 {
-       assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU);
+       assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_FRAGMENT_PDU);
 
        do {
                int ret = send(sk, p, len, 0);
@@ -146,7 +147,7 @@ static int verify_convert_cmd(struct fio_net_cmd *cmd)
                return 1;
        }
 
-       if (cmd->pdu_len > FIO_SERVER_MAX_PDU) {
+       if (cmd->pdu_len > FIO_SERVER_MAX_FRAGMENT_PDU) {
                log_err("fio: command payload too large: %u\n", cmd->pdu_len);
                return 1;
        }
@@ -262,8 +263,8 @@ int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
 
        do {
                this_len = size;
-               if (this_len > FIO_SERVER_MAX_PDU)
-                       this_len = FIO_SERVER_MAX_PDU;
+               if (this_len > FIO_SERVER_MAX_FRAGMENT_PDU)
+                       this_len = FIO_SERVER_MAX_FRAGMENT_PDU;
 
                if (!cmd || cur_len < sizeof(*cmd) + this_len) {
                        if (cmd)
@@ -339,21 +340,11 @@ static int fio_server_send_quit_cmd(void)
        return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0, NULL);
 }
 
-static int handle_job_cmd(struct fio_net_cmd *cmd)
+static int handle_run_cmd(struct fio_net_cmd *cmd)
 {
-       char *buf = (char *) cmd->payload;
-       struct cmd_start_pdu spdu;
        struct cmd_end_pdu epdu;
        int ret;
 
-       if (parse_jobs_ini(buf, 1, 0)) {
-               fio_server_send_quit_cmd();
-               return -1;
-       }
-
-       spdu.jobs = cpu_to_le32(thread_number);
-       fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
-
        ret = fio_backend();
 
        epdu.error = ret;
@@ -365,14 +356,30 @@ static int handle_job_cmd(struct fio_net_cmd *cmd)
        return ret;
 }
 
+static int handle_job_cmd(struct fio_net_cmd *cmd)
+{
+       char *buf = (char *) cmd->payload;
+       struct cmd_start_pdu spdu;
+
+       if (parse_jobs_ini(buf, 1, 0)) {
+               fio_server_send_quit_cmd();
+               return -1;
+       }
+
+       spdu.jobs = cpu_to_le32(thread_number);
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
+       return 0;
+}
+
 static int handle_jobline_cmd(struct fio_net_cmd *cmd)
 {
        void *pdu = cmd->payload;
        struct cmd_single_line_pdu *cslp;
        struct cmd_line_pdu *clp;
        unsigned long offset;
+       struct cmd_start_pdu spdu;
        char **argv;
-       int ret, i;
+       int i;
 
        clp = pdu;
        clp->lines = le16_to_cpu(clp->lines);
@@ -397,13 +404,9 @@ static int handle_jobline_cmd(struct fio_net_cmd *cmd)
 
        free(argv);
 
-       fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0, NULL);
-
-       ret = fio_backend();
-       fio_server_send_quit_cmd();
-       reset_fio_state();
-       first_cmd_check = 0;
-       return ret;
+       spdu.jobs = cpu_to_le32(thread_number);
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
+       return 0;
 }
 
 static int handle_probe_cmd(struct fio_net_cmd *cmd)
@@ -498,6 +501,9 @@ static int handle_command(struct fio_net_cmd *cmd)
        case FIO_NET_CMD_SEND_ETA:
                ret = handle_send_eta_cmd(cmd);
                break;
+       case FIO_NET_CMD_RUN:
+               ret = handle_run_cmd(cmd);
+               break;
        default:
                log_err("fio: unknown opcode: %s\n",fio_server_op(cmd->opcode));
                ret = 1;
index bc044e9b4772eff159f34225f8019889b9c8a04c..7a801bf0a283235ebc72d50392d7fc99f87f4dc1 100644 (file)
--- a/server.h
+++ b/server.h
@@ -38,9 +38,9 @@ struct fio_net_int_cmd {
 };
 
 enum {
-       FIO_SERVER_VER                  = 9,
+       FIO_SERVER_VER                  = 10,
 
-       FIO_SERVER_MAX_PDU              = 1024,
+       FIO_SERVER_MAX_FRAGMENT_PDU     = 1024,
 
        FIO_NET_CMD_QUIT                = 1,
        FIO_NET_CMD_EXIT                = 2,
@@ -57,7 +57,8 @@ enum {
        FIO_NET_CMD_DU                  = 13,
        FIO_NET_CMD_SERVER_START        = 14,
        FIO_NET_CMD_ADD_JOB             = 15,
-       FIO_NET_CMD_NR                  = 16,
+       FIO_NET_CMD_RUN                 = 16,
+       FIO_NET_CMD_NR                  = 17,
 
        FIO_NET_CMD_F_MORE              = 1UL << 0,