output_buffer: only realloc once, and memset just what we need
[fio.git] / client.c
index 52440f067aed33cd9b03876a385e0ebe0ca1b7e6..db472c4cb0b4cb1d87368358b8bb34d65f78d94c 100644 (file)
--- a/client.c
+++ b/client.c
@@ -62,6 +62,8 @@ static struct json_object *root = NULL;
 static struct json_array *clients_array = NULL;
 static struct json_array *du_array = NULL;
 
+static int error_clients;
+
 #define FIO_CLIENT_HASH_BITS   7
 #define FIO_CLIENT_HASH_SZ     (1 << FIO_CLIENT_HASH_BITS)
 #define FIO_CLIENT_HASH_MASK   (FIO_CLIENT_HASH_SZ - 1)
@@ -115,7 +117,7 @@ static int read_data(int fd, void *data, size_t size)
 
 static void fio_client_json_init(void)
 {
-       if (output_format != FIO_OUTPUT_JSON)
+       if (!(output_format & FIO_OUTPUT_JSON))
                return;
        root = json_create_object();
        json_object_add_value_string(root, "fio version", fio_version_string);
@@ -127,9 +129,9 @@ static void fio_client_json_init(void)
 
 static void fio_client_json_fini(void)
 {
-       if (output_format != FIO_OUTPUT_JSON)
+       if (!(output_format & FIO_OUTPUT_JSON))
                return;
-       json_print_object(root);
+       json_print_object(root, NULL);
        log_info("\n");
        json_free_object(root);
        root = NULL;
@@ -176,9 +178,23 @@ void fio_put_client(struct fio_client *client)
        if (!client->did_stat)
                sum_stat_clients--;
 
+       if (client->error)
+               error_clients++;
+
        free(client);
 }
 
+static int fio_client_dec_jobs_eta(struct client_eta *eta, client_eta_op eta_fn)
+{
+       if (!--eta->pending) {
+               eta_fn(&eta->eta);
+               free(eta);
+               return 0;
+       }
+
+       return 1;
+}
+
 static void remove_client(struct fio_client *client)
 {
        assert(client->refs);
@@ -380,6 +396,7 @@ static const char *server_name(struct fio_client *client, char *buf,
 static void probe_client(struct fio_client *client)
 {
        struct cmd_client_probe_pdu pdu;
+       const char *sname;
        uint64_t tag;
        char buf[64];
 
@@ -391,7 +408,9 @@ static void probe_client(struct fio_client *client)
        pdu.flags = 0;
 #endif
 
-       strcpy((char *) pdu.server, server_name(client, buf, sizeof(buf)));
+       sname = server_name(client, buf, sizeof(buf));
+       memset(pdu.server, 0, sizeof(pdu.server));
+       strncpy((char *) pdu.server, sname, sizeof(pdu.server) - 1);
 
        fio_net_send_cmd(client->fd, FIO_NET_CMD_PROBE, &pdu, sizeof(pdu), &tag, &client->cmd_list);
 }
@@ -515,11 +534,6 @@ static void sig_int(int sig)
        fio_clients_terminate();
 }
 
-static void sig_show_status(int sig)
-{
-       show_running_run_stats();
-}
-
 static void client_signal_handler(void)
 {
        struct sigaction act;
@@ -883,6 +897,10 @@ static void convert_ts(struct thread_stat *dst, struct thread_stat *src)
        dst->latency_target     = le64_to_cpu(src->latency_target);
        dst->latency_window     = le64_to_cpu(src->latency_window);
        dst->latency_percentile.u.f = fio_uint64_to_double(le64_to_cpu(src->latency_percentile.u.i));
+
+       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]);
 }
 
 static void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
@@ -918,7 +936,7 @@ static void handle_ts(struct fio_client *client, struct fio_net_cmd *cmd)
        struct cmd_ts_pdu *p = (struct cmd_ts_pdu *) cmd->payload;
        struct json_object *tsobj;
 
-       tsobj = show_thread_status(&p->ts, &p->rs);
+       tsobj = show_thread_status(&p->ts, &p->rs, NULL);
        client->did_stat = 1;
        if (tsobj) {
                json_object_add_client_info(tsobj, client);
@@ -938,7 +956,7 @@ static void handle_ts(struct fio_client *client, struct fio_net_cmd *cmd)
 
        if (++sum_stat_nr == sum_stat_clients) {
                strcpy(client_ts.name, "All clients");
-               tsobj = show_thread_status(&client_ts, &client_gs);
+               tsobj = show_thread_status(&client_ts, &client_gs, NULL);
                if (tsobj) {
                        json_object_add_client_info(tsobj, client);
                        json_array_add_value_object(clients_array, tsobj);
@@ -950,7 +968,7 @@ static void handle_gs(struct fio_client *client, struct fio_net_cmd *cmd)
 {
        struct group_run_stats *gs = (struct group_run_stats *) cmd->payload;
 
-       show_group_stats(gs);
+       show_group_stats(gs, NULL);
 }
 
 static void handle_text(struct fio_client *client, struct fio_net_cmd *cmd)
@@ -974,14 +992,14 @@ static void convert_agg(struct disk_util_agg *agg)
        int i;
 
        for (i = 0; i < 2; i++) {
-               agg->ios[i]     = le32_to_cpu(agg->ios[i]);
-               agg->merges[i]  = le32_to_cpu(agg->merges[i]);
+               agg->ios[i]     = le64_to_cpu(agg->ios[i]);
+               agg->merges[i]  = le64_to_cpu(agg->merges[i]);
                agg->sectors[i] = le64_to_cpu(agg->sectors[i]);
-               agg->ticks[i]   = le32_to_cpu(agg->ticks[i]);
+               agg->ticks[i]   = le64_to_cpu(agg->ticks[i]);
        }
 
-       agg->io_ticks           = le32_to_cpu(agg->io_ticks);
-       agg->time_in_queue      = le32_to_cpu(agg->time_in_queue);
+       agg->io_ticks           = le64_to_cpu(agg->io_ticks);
+       agg->time_in_queue      = le64_to_cpu(agg->time_in_queue);
        agg->slavecount         = le32_to_cpu(agg->slavecount);
        agg->max_util.u.f       = fio_uint64_to_double(le64_to_cpu(agg->max_util.u.i));
 }
@@ -991,14 +1009,14 @@ static void convert_dus(struct disk_util_stat *dus)
        int i;
 
        for (i = 0; i < 2; i++) {
-               dus->s.ios[i]           = le32_to_cpu(dus->s.ios[i]);
-               dus->s.merges[i]        = le32_to_cpu(dus->s.merges[i]);
+               dus->s.ios[i]           = le64_to_cpu(dus->s.ios[i]);
+               dus->s.merges[i]        = le64_to_cpu(dus->s.merges[i]);
                dus->s.sectors[i]       = le64_to_cpu(dus->s.sectors[i]);
-               dus->s.ticks[i]         = le32_to_cpu(dus->s.ticks[i]);
+               dus->s.ticks[i]         = le64_to_cpu(dus->s.ticks[i]);
        }
 
-       dus->s.io_ticks         = le32_to_cpu(dus->s.io_ticks);
-       dus->s.time_in_queue    = le32_to_cpu(dus->s.time_in_queue);
+       dus->s.io_ticks         = le64_to_cpu(dus->s.io_ticks);
+       dus->s.time_in_queue    = le64_to_cpu(dus->s.time_in_queue);
        dus->s.msec             = le64_to_cpu(dus->s.msec);
 }
 
@@ -1011,13 +1029,16 @@ static void handle_du(struct fio_client *client, struct fio_net_cmd *cmd)
                log_info("\nDisk stats (read/write):\n");
        }
 
-       if (output_format == FIO_OUTPUT_JSON) {
+       if (output_format & FIO_OUTPUT_JSON) {
                struct json_object *duobj;
                json_array_add_disk_util(&du->dus, &du->agg, du_array);
                duobj = json_array_last_value_object(du_array);
                json_object_add_client_info(duobj, client);
-       } else
-               print_disk_util(&du->dus, &du->agg, output_format == FIO_OUTPUT_TERSE);
+       }
+       if (output_format & FIO_OUTPUT_TERSE)
+               print_disk_util(&du->dus, &du->agg, 1, NULL);
+       if (output_format & FIO_OUTPUT_NORMAL)
+               print_disk_util(&du->dus, &du->agg, 0, NULL);
 }
 
 static void convert_jobs_eta(struct jobs_eta *je)
@@ -1079,14 +1100,6 @@ void fio_client_sum_jobs_eta(struct jobs_eta *dst, struct jobs_eta *je)
        strcpy((char *) dst->run_str, (char *) je->run_str);
 }
 
-void fio_client_dec_jobs_eta(struct client_eta *eta, client_eta_op eta_fn)
-{
-       if (!--eta->pending) {
-               eta_fn(&eta->eta);
-               free(eta);
-       }
-}
-
 static void remove_reply_cmd(struct fio_client *client, struct fio_net_cmd *cmd)
 {
        struct fio_net_cmd_reply *reply = NULL;
@@ -1482,9 +1495,16 @@ int fio_handle_client(struct fio_client *client)
                break;
        case FIO_NET_CMD_VTRIGGER: {
                struct all_io_list *pdu = (struct all_io_list *) cmd->payload;
-               char buf[64];
+               char buf[128];
+               int off = 0;
 
-               __verify_save_state(pdu, server_name(client, buf, sizeof(buf)));
+               if (aux_path) {
+                       strcpy(buf, aux_path);
+                       off = strlen(buf);
+               }
+
+               __verify_save_state(pdu, server_name(client, &buf[off], sizeof(buf) - off));
+               exec_trigger(trigger_cmd);
                break;
                }
        case FIO_NET_CMD_SENDFILE: {
@@ -1560,8 +1580,10 @@ static void request_client_etas(struct client_ops *ops)
                                        (uintptr_t) eta, &client->cmd_list);
        }
 
-       while (skipped--)
-               fio_client_dec_jobs_eta(eta, ops->eta);
+       while (skipped--) {
+               if (!fio_client_dec_jobs_eta(eta, ops->eta))
+                       break;
+       }
 
        dprint(FD_NET, "client: requested eta tag %p\n", eta);
 }
@@ -1612,6 +1634,7 @@ static int fio_check_clients_timed_out(void)
                else
                        log_err("fio: client %s timed out\n", client->hostname);
 
+               client->error = ETIMEDOUT;
                remove_client(client);
                ret = 1;
        }
@@ -1705,5 +1728,5 @@ int fio_handle_clients(struct client_ops *ops)
        fio_client_json_fini();
 
        free(pfds);
-       return retval;
+       return retval || error_clients;
 }