Fio 3.34
[fio.git] / client.c
index e8f6fd493121d6680df4bac67507b07b0d591fdc..51496c770248a2d67466a97ad7529d8d4ec68e82 100644 (file)
--- a/client.c
+++ b/client.c
@@ -284,9 +284,10 @@ static int fio_client_dec_jobs_eta(struct client_eta *eta, client_eta_op eta_fn)
 static void fio_drain_client_text(struct fio_client *client)
 {
        do {
-               struct fio_net_cmd *cmd;
+               struct fio_net_cmd *cmd = NULL;
 
-               cmd = fio_net_recv_cmd(client->fd, false);
+               if (fio_server_poll_fd(client->fd, POLLIN, 0))
+                       cmd = fio_net_recv_cmd(client->fd, false);
                if (!cmd)
                        break;
 
@@ -390,8 +391,6 @@ struct fio_client *fio_client_add_explicit(struct client_ops *ops,
 
        client = get_new_client();
 
-       client->hostname = strdup(hostname);
-
        if (type == Fio_client_socket)
                client->is_sock = true;
        else {
@@ -410,6 +409,7 @@ struct fio_client *fio_client_add_explicit(struct client_ops *ops,
        client->ops = ops;
        client->refs = 1;
        client->type = ops->client_type;
+       client->hostname = strdup(hostname);
 
        __fio_client_add_cmd_option(client, "fio");
 
@@ -471,8 +471,10 @@ int fio_client_add(struct client_ops *ops, const char *hostname, void **cookie)
                                        &client->is_sock, &client->port,
                                        &client->addr.sin_addr,
                                        &client->addr6.sin6_addr,
-                                       &client->ipv6))
+                                       &client->ipv6)) {
+               fio_put_client(client);
                return -1;
+       }
 
        client->fd = -1;
        client->ops = ops;
@@ -920,13 +922,20 @@ int fio_clients_send_ini(const char *filename)
 int fio_client_update_options(struct fio_client *client,
                              struct thread_options *o, uint64_t *tag)
 {
-       struct cmd_add_job_pdu pdu;
+       size_t cmd_sz = offsetof(struct cmd_add_job_pdu, top) +
+               thread_options_pack_size(o);
+       struct cmd_add_job_pdu *pdu;
+       int ret;
 
-       pdu.thread_number = cpu_to_le32(client->thread_number);
-       pdu.groupid = cpu_to_le32(client->groupid);
-       convert_thread_options_to_net(&pdu.top, o);
+       pdu = malloc(cmd_sz);
+       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);
+       ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_UPDATE_JOB, pdu,
+                              cmd_sz, tag, &client->cmd_list);
+       free(pdu);
+       return ret;
 }
 
 static void convert_io_stat(struct io_stat *dst, struct io_stat *src)
@@ -952,6 +961,8 @@ static void convert_ts(struct thread_stat *dst, struct thread_stat *src)
        dst->pid                = le32_to_cpu(src->pid);
        dst->members            = le32_to_cpu(src->members);
        dst->unified_rw_rep     = le32_to_cpu(src->unified_rw_rep);
+       dst->ioprio             = le32_to_cpu(src->ioprio);
+       dst->disable_prio_stat  = le32_to_cpu(src->disable_prio_stat);
 
        for (i = 0; i < DDIR_RWDIR_CNT; i++) {
                convert_io_stat(&dst->clat_stat[i], &src->clat_stat[i]);
@@ -1034,14 +1045,6 @@ static void convert_ts(struct thread_stat *dst, struct thread_stat *src)
        dst->nr_block_infos     = le64_to_cpu(src->nr_block_infos);
        for (i = 0; i < dst->nr_block_infos; i++)
                dst->block_infos[i] = le32_to_cpu(src->block_infos[i]);
-       for (i = 0; i < DDIR_RWDIR_CNT; i++) {
-               for (j = 0; j < FIO_IO_U_PLAT_NR; j++) {
-                       dst->io_u_plat_high_prio[i][j] = le64_to_cpu(src->io_u_plat_high_prio[i][j]);
-                       dst->io_u_plat_prio[i][j] = le64_to_cpu(src->io_u_plat_prio[i][j]);
-               }
-               convert_io_stat(&dst->clat_high_prio_stat[i], &src->clat_high_prio_stat[i]);
-               convert_io_stat(&dst->clat_prio_stat[i], &src->clat_prio_stat[i]);
-       }
 
        dst->ss_dur             = le64_to_cpu(src->ss_dur);
        dst->ss_state           = le32_to_cpu(src->ss_state);
@@ -1051,6 +1054,19 @@ static void convert_ts(struct thread_stat *dst, struct thread_stat *src)
        dst->ss_deviation.u.f   = fio_uint64_to_double(le64_to_cpu(src->ss_deviation.u.i));
        dst->ss_criterion.u.f   = fio_uint64_to_double(le64_to_cpu(src->ss_criterion.u.i));
 
+       for (i = 0; i < DDIR_RWDIR_CNT; i++) {
+               dst->nr_clat_prio[i] = le32_to_cpu(src->nr_clat_prio[i]);
+               for (j = 0; j < dst->nr_clat_prio[i]; j++) {
+                       for (k = 0; k < FIO_IO_U_PLAT_NR; k++)
+                               dst->clat_prio[i][j].io_u_plat[k] =
+                                       le64_to_cpu(src->clat_prio[i][j].io_u_plat[k]);
+                       convert_io_stat(&dst->clat_prio[i][j].clat_stat,
+                                       &src->clat_prio[i][j].clat_stat);
+                       dst->clat_prio[i][j].ioprio =
+                               le32_to_cpu(dst->clat_prio[i][j].ioprio);
+               }
+       }
+
        if (dst->ss_state & FIO_SS_DATA) {
                for (i = 0; i < dst->ss_dur; i++ ) {
                        dst->ss_iops_data[i] = le64_to_cpu(src->ss_iops_data[i]);
@@ -1110,7 +1126,7 @@ static void handle_ts(struct fio_client *client, struct fio_net_cmd *cmd)
        if (sum_stat_clients <= 1)
                return;
 
-       sum_thread_stats(&client_ts, &p->ts, sum_stat_nr == 1);
+       sum_thread_stats(&client_ts, &p->ts);
        sum_group_stats(&client_gs, &p->rs);
 
        client_ts.members++;
@@ -1140,37 +1156,27 @@ static void handle_gs(struct fio_client *client, struct fio_net_cmd *cmd)
 static void handle_job_opt(struct fio_client *client, struct fio_net_cmd *cmd)
 {
        struct cmd_job_option *pdu = (struct cmd_job_option *) cmd->payload;
-       struct print_option *p;
-
-       if (!job_opt_object)
-               return;
 
        pdu->global = le16_to_cpu(pdu->global);
        pdu->truncated = le16_to_cpu(pdu->truncated);
        pdu->groupid = le32_to_cpu(pdu->groupid);
 
-       p = malloc(sizeof(*p));
-       p->name = strdup((char *) pdu->name);
-       if (pdu->value[0] != '\0')
-               p->value = strdup((char *) pdu->value);
-       else
-               p->value = NULL;
-
        if (pdu->global) {
-               const char *pos = "";
-
-               if (p->value)
-                       pos = p->value;
+               if (!job_opt_object)
+                       return;
 
-               json_object_add_value_string(job_opt_object, p->name, pos);
+               json_object_add_value_string(job_opt_object,
+                                            (const char *)pdu->name,
+                                            (const char *)pdu->value);
        } else if (client->opt_lists) {
                struct flist_head *opt_list = &client->opt_lists[pdu->groupid];
+               struct print_option *p;
 
+               p = malloc(sizeof(*p));
+               p->name = strdup((const char *)pdu->name);
+               p->value = pdu->value[0] ? strdup((const char *)pdu->value) :
+                       NULL;
                flist_add_tail(&p->list, opt_list);
-       } else {
-               free(p->value);
-               free(p->name);
-               free(p);
        }
 }
 
@@ -1688,6 +1694,7 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd,
        ret->log_type           = le32_to_cpu(ret->log_type);
        ret->compressed         = le32_to_cpu(ret->compressed);
        ret->log_offset         = le32_to_cpu(ret->log_offset);
+       ret->log_prio           = le32_to_cpu(ret->log_prio);
        ret->log_hist_coarseness = le32_to_cpu(ret->log_hist_coarseness);
 
        if (*store_direct)
@@ -1702,9 +1709,11 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd,
                        s = (struct io_sample *)((char *)s + sizeof(struct io_u_plat_entry) * i);
 
                s->time         = le64_to_cpu(s->time);
-               s->data.val     = le64_to_cpu(s->data.val);
+               if (ret->log_type != IO_LOG_TYPE_HIST)
+                       s->data.val     = le64_to_cpu(s->data.val);
                s->__ddir       = __le32_to_cpu(s->__ddir);
                s->bs           = le64_to_cpu(s->bs);
+               s->priority     = le16_to_cpu(s->priority);
 
                if (ret->log_offset) {
                        struct io_sample_offset *so = (void *) s;
@@ -1767,7 +1776,6 @@ int fio_handle_client(struct fio_client *client)
 {
        struct client_ops *ops = client->ops;
        struct fio_net_cmd *cmd;
-       int size;
 
        dprint(FD_NET, "client: handle %s\n", client->hostname);
 
@@ -1801,14 +1809,26 @@ int fio_handle_client(struct fio_client *client)
                }
        case FIO_NET_CMD_TS: {
                struct cmd_ts_pdu *p = (struct cmd_ts_pdu *) cmd->payload;
+               uint64_t offset;
+               int i;
+
+               for (i = 0; i < DDIR_RWDIR_CNT; i++) {
+                       if (le32_to_cpu(p->ts.nr_clat_prio[i])) {
+                               offset = le64_to_cpu(p->ts.clat_prio_offset[i]);
+                               p->ts.clat_prio[i] =
+                                       (struct clat_prio_stat *)((char *)p + offset);
+                       }
+               }
 
                dprint(FD_NET, "client: ts->ss_state = %u\n", (unsigned int) le32_to_cpu(p->ts.ss_state));
                if (le32_to_cpu(p->ts.ss_state) & FIO_SS_DATA) {
                        dprint(FD_NET, "client: received steadystate ring buffers\n");
 
-                       size = le64_to_cpu(p->ts.ss_dur);
-                       p->ts.ss_iops_data = (uint64_t *) ((struct cmd_ts_pdu *)cmd->payload + 1);
-                       p->ts.ss_bw_data = p->ts.ss_iops_data + size;
+                       offset = le64_to_cpu(p->ts.ss_iops_data_offset);
+                       p->ts.ss_iops_data = (uint64_t *)((char *)p + offset);
+
+                       offset = le64_to_cpu(p->ts.ss_bw_data_offset);
+                       p->ts.ss_bw_data = (uint64_t *)((char *)p + offset);
                }
 
                convert_ts(&p->ts, &p->ts);
@@ -2159,6 +2179,7 @@ int fio_handle_clients(struct client_ops *ops)
 
        fio_client_json_fini();
 
+       free_clat_prio_stats(&client_ts);
        free(pfds);
        return retval || error_clients;
 }