gfio: start of being able to update options
authorJens Axboe <axboe@kernel.dk>
Tue, 27 Mar 2012 14:03:04 +0000 (16:03 +0200)
committerJens Axboe <axboe@kernel.dk>
Tue, 27 Mar 2012 14:03:04 +0000 (16:03 +0200)
Not quite done yet, but it's a start.

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

index d1357cbbd28c11508b99e123ca057c5ee2e0343b..fe1f32bf57432e6155b3bf9dd5369eb4bcd2b375 100644 (file)
--- a/client.c
+++ b/client.c
@@ -459,7 +459,7 @@ static int send_client_cmd_line(struct fio_client *client)
        free(lens);
        clp->lines = cpu_to_le16(client->argc);
        clp->client_type = __cpu_to_le16(client->type);
-       ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOBLINE, pdu, mem, 0);
+       ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOBLINE, pdu, mem, NULL, NULL);
        free(pdu);
        return ret;
 }
@@ -585,7 +585,7 @@ static int __fio_client_send_ini(struct fio_client *client, const char *filename
        pdu->client_type = cpu_to_le32(client->type);
 
        client->sent_job = 1;
-       ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOB, pdu, p_size, 0);
+       ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOB, pdu, p_size, NULL, NULL);
        free(pdu);
        close(fd);
        return ret;
@@ -617,6 +617,18 @@ int fio_clients_send_ini(const char *filename)
        return !nr_clients;
 }
 
+int fio_client_update_options(struct fio_client *client,
+                             struct thread_options *o, uint64_t *tag)
+{
+       struct cmd_add_job_pdu pdu;
+
+       pdu.thread_number = cpu_to_le32(client->thread_number);
+       pdu.groupid = cpu_to_le32(client->groupid);
+       convert_thread_options_to_net(&pdu.top, o);
+       
+       return fio_net_send_cmd(client->fd, FIO_NET_CMD_UPDATE_JOB, &pdu, sizeof(pdu), tag, &client->cmd_list);
+}
+
 static void convert_io_stat(struct io_stat *dst, struct io_stat *src)
 {
        dst->max_val    = le64_to_cpu(src->max_val);
@@ -863,26 +875,50 @@ void fio_client_dec_jobs_eta(struct client_eta *eta, client_eta_op eta_fn)
 
 static void remove_reply_cmd(struct fio_client *client, struct fio_net_cmd *cmd)
 {
-       struct fio_net_int_cmd *icmd = NULL;
+       struct fio_net_cmd_reply *reply = NULL;
        struct flist_head *entry;
 
        flist_for_each(entry, &client->cmd_list) {
-               icmd = flist_entry(entry, struct fio_net_int_cmd, list);
+               reply = flist_entry(entry, struct fio_net_cmd_reply, list);
 
-               if (cmd->tag == (uintptr_t) icmd)
+               if (cmd->tag == (uintptr_t) reply)
                        break;
 
-               icmd = NULL;
+               reply = NULL;
        }
 
-       if (!icmd) {
-               log_err("fio: client: unable to find matching tag\n");
+       if (!reply) {
+               log_err("fio: client: unable to find matching tag (%lx)\n", cmd->tag);
                return;
        }
 
-       flist_del(&icmd->list);
-       cmd->tag = icmd->saved_tag;
-       free(icmd);
+       flist_del(&reply->list);
+       cmd->tag = reply->saved_tag;
+       free(reply);
+}
+
+int fio_client_wait_for_reply(struct fio_client *client, uint64_t tag)
+{
+       do {
+               struct fio_net_cmd_reply *reply = NULL;
+               struct flist_head *entry;
+
+               flist_for_each(entry, &client->cmd_list) {
+                       reply = flist_entry(entry, struct fio_net_cmd_reply, list);
+
+                       if (tag == (uintptr_t) reply)
+                               break;
+
+                       reply = NULL;
+               }
+
+               if (!reply)
+                       break;
+
+               usleep(1000);
+       } while (1);
+
+       return 0;
 }
 
 static void handle_eta(struct fio_client *client, struct fio_net_cmd *cmd)
@@ -1130,11 +1166,17 @@ int fio_handle_client(struct fio_client *client)
                free(cmd);
                break;
                }
-       case FIO_NET_CMD_ADD_JOB:
+       case FIO_NET_CMD_ADD_JOB: {
+               struct cmd_add_job_pdu *pdu = (struct cmd_add_job_pdu *) cmd->payload;
+
+               client->thread_number = le32_to_cpu(pdu->thread_number);
+               client->groupid = le32_to_cpu(pdu->groupid);
+
                if (ops->add_job)
                        ops->add_job(client, cmd);
                free(cmd);
                break;
+               }
        case FIO_NET_CMD_IOLOG:
                if (ops->iolog) {
                        struct cmd_iolog_pdu *pdu;
@@ -1144,6 +1186,11 @@ int fio_handle_client(struct fio_client *client)
                }
                free(cmd);
                break;
+       case FIO_NET_CMD_UPDATE_JOB:
+               remove_reply_cmd(client, cmd);
+               ops->update_job(client, cmd);
+               free(cmd);
+               break;
        default:
                log_err("fio: unknown client op: %s\n", fio_server_op(cmd->opcode));
                free(cmd);
@@ -1192,20 +1239,20 @@ static void request_client_etas(struct client_ops *ops)
 static int client_check_cmd_timeout(struct fio_client *client,
                                    struct timeval *now)
 {
-       struct fio_net_int_cmd *cmd;
+       struct fio_net_cmd_reply *reply;
        struct flist_head *entry, *tmp;
        int ret = 0;
 
        flist_for_each_safe(entry, tmp, &client->cmd_list) {
-               cmd = flist_entry(entry, struct fio_net_int_cmd, list);
+               reply = flist_entry(entry, struct fio_net_cmd_reply, list);
 
-               if (mtime_since(&cmd->tv, now) < FIO_NET_CLIENT_TIMEOUT)
+               if (mtime_since(&reply->tv, now) < FIO_NET_CLIENT_TIMEOUT)
                        continue;
 
                log_err("fio: client %s, timeout on cmd %s\n", client->hostname,
-                                               fio_server_op(cmd->cmd.opcode));
-               flist_del(&cmd->list);
-               free(cmd);
+                                               fio_server_op(reply->opcode));
+               flist_del(&reply->list);
+               free(reply);
                ret = 1;
        }
 
index a89afd8de8a664b5ad85cf14f8cb43317c3483da..acb5a88f59b415920a44200a740af2bc720065ca 100644 (file)
--- a/client.h
+++ b/client.h
@@ -48,6 +48,9 @@ struct fio_client {
        int sent_job;
        uint32_t type;
 
+       uint32_t thread_number;
+       uint32_t groupid;
+
        struct flist_head eta_list;
        struct client_eta *eta_in_flight;
 
@@ -77,6 +80,7 @@ struct client_ops {
        client_cmd_op           *probe;
        client_cmd_op           *quit;
        client_cmd_op           *add_job;
+       client_cmd_op           *update_job;
        client_timed_out_op     *timed_out;
        client_cmd_op           *stop;
        client_cmd_op           *start;
@@ -120,6 +124,8 @@ extern int fio_client_terminate(struct fio_client *);
 extern void fio_clients_terminate(void);
 extern struct fio_client *fio_get_client(struct fio_client *);
 extern void fio_put_client(struct fio_client *);
+extern int fio_client_update_options(struct fio_client *, struct thread_options *, uint64_t *);
+extern int fio_client_wait_for_reply(struct fio_client *, uint64_t);
 
 #define FIO_CLIENT_DEF_ETA_MSEC                900
 
index d551351a08d98743f5c90a489ec6b2d9514036df..4955ad4717bfceb6cfff76c81d2cb808210b34a6 100644 (file)
--- a/gclient.c
+++ b/gclient.c
@@ -620,6 +620,15 @@ static void gfio_add_job_op(struct fio_client *client, struct fio_net_cmd *cmd)
        gdk_threads_leave();
 }
 
+static void gfio_update_job_op(struct fio_client *client,
+                              struct fio_net_cmd *cmd)
+{
+       uint32_t *pdu_error = (uint32_t *) cmd->payload;
+       struct gfio_client *gc = client->client_data;
+
+       *pdu_error = le32_to_cpu(*pdu_error);
+}
+
 static void gfio_client_timed_out(struct fio_client *client)
 {
        struct gfio_client *gc = client->client_data;
@@ -1363,6 +1372,7 @@ struct client_ops gfio_client_ops = {
        .probe                  = gfio_probe_op,
        .quit                   = gfio_quit_op,
        .add_job                = gfio_add_job_op,
+       .update_job             = gfio_update_job_op,
        .timed_out              = gfio_client_timed_out,
        .stop                   = gfio_client_stop,
        .start                  = gfio_client_start,
index 87d92e696815bd00609ef7d8442eff9a97a49f54..d17653f4c5aa1070a01a90faa565c0dec9daf86b 100644 (file)
@@ -81,6 +81,8 @@ struct gopt_job_view {
        struct gopt_frame_widget g_widgets[__FIO_OPT_G_NR];
        GtkWidget *widgets[FIO_MAX_OPTS];
        GtkWidget *vboxes[__FIO_OPT_C_NR];
+       GtkWidget *dialog;
+       struct gfio_client *client;
        struct flist_head changed_list;
        struct thread_options *o;
 };
@@ -165,6 +167,15 @@ static void gopt_mark_index(struct gopt_job_view *gjv, struct gopt *gopt,
        gjv->widgets[idx] = gopt->box;
 }
 
+static void gopt_dialog_update_apply(struct gopt_job_view *gjv)
+{
+       GtkDialog *dialog = GTK_DIALOG(gjv->dialog);
+       gboolean set;
+
+       set = !flist_empty(&gjv->changed_list);
+       gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_APPLY, set);
+}
+
 static void gopt_changed(struct gopt *gopt)
 {
        struct gopt_job_view *gjv = gopt->gjv;
@@ -173,8 +184,10 @@ static void gopt_changed(struct gopt *gopt)
         * Add to changed list. This also prevents the option from being
         * freed when the widget is destroyed.
         */
-       if (flist_empty(&gopt->changed_list))
+       if (flist_empty(&gopt->changed_list)) {
                flist_add_tail(&gopt->changed_list, &gjv->changed_list);
+               gopt_dialog_update_apply(gjv);
+       }
 }
 
 static void gopt_str_changed(GtkEntry *entry, gpointer data)
@@ -1139,15 +1152,87 @@ static void gopt_handle_changed(struct gopt *gopt)
        g_object_unref(G_OBJECT(gopt->box));
 }
 
-static void gopt_handle_changed_options(struct gopt_job_view *gjv)
+static int gopt_handle_changed_options(struct gopt_job_view *gjv)
 {
+       struct gfio_client *gc = gjv->client;
+       uint64_t waitid = 0;
        struct gopt *gopt;
+       int ret;
 
        while (!flist_empty(&gjv->changed_list)) {
                gopt = flist_entry(gjv->changed_list.next, struct gopt, changed_list);
                flist_del(&gopt->changed_list);
                gopt_handle_changed(gopt);
        }
+
+       gopt_dialog_update_apply(gjv);
+
+       ret = fio_client_update_options(gc->client, gjv->o, &waitid);
+       if (ret)
+               return ret;
+
+       return fio_client_wait_for_reply(gc->client, waitid);
+}
+
+static gint gopt_dialog_cancel(gint response)
+{
+       switch (response) {
+       case GTK_RESPONSE_NONE:
+       case GTK_RESPONSE_REJECT:
+       case GTK_RESPONSE_DELETE_EVENT:
+       case GTK_RESPONSE_CANCEL:
+       case GTK_RESPONSE_NO:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static gint gopt_dialog_done(gint response)
+{
+       switch (response) {
+       case GTK_RESPONSE_ACCEPT:
+       case GTK_RESPONSE_OK:
+       case GTK_RESPONSE_YES:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+
+static void gopt_handle_option_dialog(GtkWidget *dialog,
+                                     struct flist_head *gjv_list)
+{
+       struct flist_head *entry;
+       struct gopt_job_view *gjv;
+       gint response;
+
+       do {
+               response = gtk_dialog_run(GTK_DIALOG(dialog));
+               if (gopt_dialog_cancel(response))
+                       break;
+               else if (gopt_dialog_done(response))
+                       break;
+
+               flist_for_each(entry, gjv_list) {
+                       gjv = flist_entry(gjv_list->next, struct gopt_job_view, list);
+
+                       gopt_handle_changed_options(gjv);
+               }
+       } while (1);
+
+       if (gopt_dialog_cancel(response))
+               return;
+
+       while (!flist_empty(gjv_list)) {
+               gjv = flist_entry(gjv_list->next, struct gopt_job_view, list);
+
+               gopt_handle_changed_options(gjv);
+
+               flist_del(&gjv->list);
+               free(gjv);
+       }
 }
 
 void gopt_get_options_window(GtkWidget *window, struct gfio_client *gc)
@@ -1169,6 +1254,7 @@ void gopt_get_options_window(GtkWidget *window, struct gfio_client *gc)
        dialog = gtk_dialog_new_with_buttons("Fio options",
                        GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT,
                        GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                       GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
                        GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
 
        gtk_widget_set_size_request(GTK_WIDGET(dialog), 1024, 768);
@@ -1199,23 +1285,17 @@ void gopt_get_options_window(GtkWidget *window, struct gfio_client *gc)
                INIT_FLIST_HEAD(&gjv->list);
                INIT_FLIST_HEAD(&gjv->changed_list);
                gjv->o = o;
+               gjv->dialog = dialog;
+               gjv->client = gc;
                flist_add_tail(&gjv->list, &gjv_list);
                gopt_add_group_tabs(notebook, gjv);
                gopt_add_options(gjv, o);
+               gopt_dialog_update_apply(gjv);
        }
 
        gtk_widget_show_all(dialog);
 
-       gtk_dialog_run(GTK_DIALOG(dialog));
-
-       while (!flist_empty(&gjv_list)) {
-               gjv = flist_entry(gjv_list.next, struct gopt_job_view, list);
-
-               gopt_handle_changed_options(gjv);
-
-               flist_del(&gjv->list);
-               free(gjv);
-       }
+       gopt_handle_option_dialog(dialog, &gjv_list);
 
        gtk_widget_destroy(dialog);
 }
index 6e736bba3850099d4910ebcee07ffb9cc22742f0..5f005500e7cb35fc3853ea259d4840be6c787d5f 100644 (file)
--- a/server.c
+++ b/server.c
@@ -293,6 +293,33 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk)
        return cmdret;
 }
 
+static void add_reply(uint64_t tag, struct flist_head *list)
+{
+       struct fio_net_cmd_reply *reply = (struct fio_net_cmd_reply *) tag;
+
+       flist_add_tail(&reply->list, list);
+}
+
+static uint64_t alloc_reply(uint64_t tag, uint16_t opcode)
+{
+       struct fio_net_cmd_reply *reply;
+
+       reply = calloc(1, sizeof(*reply));
+       INIT_FLIST_HEAD(&reply->list);
+       gettimeofday(&reply->tv, NULL);
+       reply->saved_tag = tag;
+       reply->opcode = opcode;
+
+       return (uintptr_t) reply;
+}
+
+static void free_reply(uint64_t tag)
+{
+       struct fio_net_cmd_reply *reply = (struct fio_net_cmd_reply *) tag;
+
+       free(reply);
+}
+
 void fio_net_cmd_crc_pdu(struct fio_net_cmd *cmd, const void *pdu)
 {
        uint32_t pdu_len;
@@ -309,12 +336,19 @@ void fio_net_cmd_crc(struct fio_net_cmd *cmd)
 }
 
 int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
-                    uint64_t tag)
+                    uint64_t *tagptr, struct flist_head *list)
 {
        struct fio_net_cmd *cmd = NULL;
        size_t this_len, cur_len = 0;
+       uint64_t tag;
        int ret;
 
+       if (list) {
+               assert(tagptr);
+               tag = *tagptr = alloc_reply(*tagptr, opcode);
+       } else
+               tag = tagptr ? *tagptr : 0;
+
        do {
                this_len = size;
                if (this_len > FIO_SERVER_MAX_FRAGMENT_PDU)
@@ -340,6 +374,13 @@ int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
                buf += this_len;
        } while (!ret && size);
 
+       if (list) {
+               if (ret)
+                       free_reply(tag);
+               else
+                       add_reply(tag, list);
+       }
+
        if (cmd)
                free(cmd);
 
@@ -363,28 +404,22 @@ static int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag)
 int fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag,
                            struct flist_head *list)
 {
-       struct fio_net_int_cmd *cmd;
        int ret;
 
-       if (!list)
-               return fio_net_send_simple_stack_cmd(sk, opcode, tag);
-
-       cmd = malloc(sizeof(*cmd));
-
-       fio_init_net_cmd(&cmd->cmd, opcode, NULL, 0, (uintptr_t) cmd);
-       fio_net_cmd_crc(&cmd->cmd);
-
-       INIT_FLIST_HEAD(&cmd->list);
-       gettimeofday(&cmd->tv, NULL);
-       cmd->saved_tag = tag;
+       if (list)
+               tag = alloc_reply(tag, opcode);
 
-       ret = fio_send_data(sk, &cmd->cmd, sizeof(cmd->cmd));
+       ret = fio_net_send_simple_stack_cmd(sk, opcode, tag);
        if (ret) {
-               free(cmd);
+               if (list)
+                       free_reply(tag);
+
                return ret;
        }
 
-       flist_add_tail(&cmd->list, list);
+       if (list)
+               add_reply(tag, list);
+
        return 0;
 }
 
@@ -406,7 +441,7 @@ static int fio_net_send_ack(int sk, struct fio_net_cmd *cmd, int error,
 
        epdu.error = __cpu_to_le32(error);
        epdu.signal = __cpu_to_le32(signal);
-       return fio_net_send_cmd(sk, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), tag);
+       return fio_net_send_cmd(sk, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), &tag, NULL);
 }
 
 int fio_net_send_stop(int sk, int error, int signal)
@@ -533,7 +568,7 @@ static int handle_job_cmd(struct fio_net_cmd *cmd)
        }
 
        spdu.jobs = cpu_to_le32(thread_number);
-       fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), NULL, NULL);
        return 0;
 }
 
@@ -572,13 +607,14 @@ static int handle_jobline_cmd(struct fio_net_cmd *cmd)
        free(argv);
 
        spdu.jobs = cpu_to_le32(thread_number);
-       fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), NULL, NULL);
        return 0;
 }
 
 static int handle_probe_cmd(struct fio_net_cmd *cmd)
 {
        struct cmd_probe_pdu probe;
+       uint64_t tag = cmd->tag;
 
        dprint(FD_NET, "server: sending probe reply\n");
 
@@ -596,13 +632,14 @@ static int handle_probe_cmd(struct fio_net_cmd *cmd)
 
        probe.bpp       = sizeof(void *);
 
-       return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), cmd->tag);
+       return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), &tag, NULL);
 }
 
 static int handle_send_eta_cmd(struct fio_net_cmd *cmd)
 {
        struct jobs_eta *je;
        size_t size;
+       uint64_t tag = cmd->tag;
        int i;
 
        if (!thread_number)
@@ -637,11 +674,20 @@ static int handle_send_eta_cmd(struct fio_net_cmd *cmd)
        je->eta_sec             = cpu_to_le64(je->eta_sec);
        je->nr_threads          = cpu_to_le32(je->nr_threads);
 
-       fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, cmd->tag);
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, &tag, NULL);
        free(je);
        return 0;
 }
 
+static int send_update_job_reply(int fd, uint64_t __tag, int error)
+{
+       uint64_t tag = __tag;
+       uint32_t pdu_error;
+
+       pdu_error = __cpu_to_le32(error);
+       return fio_net_send_cmd(fd, FIO_NET_CMD_UPDATE_JOB, &pdu_error, sizeof(pdu_error), &tag, NULL);
+}
+
 static int handle_update_job_cmd(struct fio_net_cmd *cmd)
 {
        struct cmd_add_job_pdu *pdu = (struct cmd_add_job_pdu *) cmd->payload;
@@ -653,13 +699,13 @@ static int handle_update_job_cmd(struct fio_net_cmd *cmd)
        dprint(FD_NET, "server: updating options for job %u\n", tnumber);
 
        if (tnumber >= thread_number) {
-               fio_net_send_ack(server_fd, cmd, ENODEV, 0);
+               send_update_job_reply(server_fd, cmd->tag, ENODEV);
                return 0;
        }
 
        td = &threads[tnumber];
        convert_thread_options_to_cpu(&td->o, &pdu->top);
-       fio_net_send_ack(server_fd, cmd, 0, 0);
+       send_update_job_reply(server_fd, cmd->tag, 0);
        return 0;
 }
 
@@ -858,7 +904,7 @@ int fio_server_text_output(int level, const char *buf, size_t len)
 
        memcpy(pdu->buf, buf, len);
 
-       fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, pdu, tlen, 0);
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, pdu, tlen, NULL, NULL);
        free(pdu);
        return len;
 }
@@ -973,7 +1019,7 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
 
        convert_gs(&p.rs, rs);
 
-       fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0);
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), NULL, NULL);
 }
 
 void fio_server_send_gs(struct group_run_stats *rs)
@@ -983,7 +1029,7 @@ void fio_server_send_gs(struct group_run_stats *rs)
        dprint(FD_NET, "server sending group run stats\n");
 
        convert_gs(&gs, rs);
-       fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0);
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), NULL, NULL);
 }
 
 static void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src)
@@ -1037,7 +1083,7 @@ void fio_server_send_du(void)
                convert_dus(&pdu.dus, &du->dus);
                convert_agg(&pdu.agg, &du->agg);
 
-               fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), 0);
+               fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), NULL, NULL);
        }
 }
 
@@ -1148,7 +1194,7 @@ void fio_server_send_add_job(struct thread_data *td)
        pdu.groupid = cpu_to_le32(td->groupid);
        convert_thread_options_to_net(&pdu.top, &td->o);
 
-       fio_net_send_cmd(server_fd, FIO_NET_CMD_ADD_JOB, &pdu, sizeof(pdu), 0);
+       fio_net_send_cmd(server_fd, FIO_NET_CMD_ADD_JOB, &pdu, sizeof(pdu), NULL, NULL);
 }
 
 void fio_server_send_start(struct thread_data *td)
index dbe7cd4135e5bb4fe60743fbf6c6009789f4176c..d56d498a149903d50159da0552455d2a707f8201 100644 (file)
--- a/server.h
+++ b/server.h
@@ -30,11 +30,11 @@ struct fio_net_cmd {
        uint8_t payload[0];     /* payload */
 };
 
-struct fio_net_int_cmd {
-       struct fio_net_cmd cmd;
+struct fio_net_cmd_reply {
        struct flist_head list;
        struct timeval tv;
        uint64_t saved_tag;
+       uint16_t opcode;
 };
 
 enum {
@@ -144,7 +144,7 @@ struct cmd_iolog_pdu {
 
 extern int fio_start_server(char *);
 extern int fio_server_text_output(int, const char *, size_t);
-extern int fio_net_send_cmd(int, uint16_t, const void *, off_t, uint64_t);
+extern int fio_net_send_cmd(int, uint16_t, const void *, off_t, uint64_t *, struct flist_head *);
 extern int fio_net_send_simple_cmd(int, uint16_t, uint64_t, struct flist_head *);
 extern void fio_server_set_arg(const char *);
 extern int fio_server_parse_string(const char *, char **, int *, int *, struct in_addr *, struct in6_addr *, int *);