server: convert iolog in place instead of copy allocating it
authorJens Axboe <axboe@kernel.dk>
Wed, 14 Mar 2012 15:28:07 +0000 (16:28 +0100)
committerJens Axboe <axboe@kernel.dk>
Wed, 14 Mar 2012 15:28:07 +0000 (16:28 +0100)
Signed-off-by: Jens Axboe <axboe@kernel.dk>
client.c
iolog.c
server.c

index c49e9a198455d72fabe318841f0f8022add89a1e..f7b050b0253dc2a644898326cce6e50ab4658063 100644 (file)
--- a/client.c
+++ b/client.c
@@ -963,6 +963,7 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd)
        unsigned long total;
        z_stream stream;
        void *p;
+       int i;
 
        stream.zalloc = Z_NULL;
        stream.zfree = Z_NULL;
@@ -974,17 +975,20 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd)
                return NULL;
 
        /*
-        * Everything beyond the first entry is compressed.
+        * Get header first, it's not compressed
         */
        nr_samples = le32_to_cpu(pdu->nr_samples);
 
-       total = sizeof(*pdu) + nr_samples * sizeof(struct io_sample);
-       ret = malloc(total);
+       total = nr_samples * sizeof(struct io_sample);
+       ret = malloc(total + sizeof(*pdu));
        ret->nr_samples = nr_samples;
-       p = (void *) ret + sizeof(pdu->nr_samples);
+       ret->log_type = le32_to_cpu(pdu->log_type);
+       strcpy((char *) ret->name, (char *) pdu->name);
+
+       p = (void *) ret + sizeof(*pdu);
 
-       stream.avail_in = cmd->pdu_len - sizeof(pdu->nr_samples);
-       stream.next_in = (void *) pdu + sizeof(pdu->nr_samples);
+       stream.avail_in = cmd->pdu_len - sizeof(*pdu);
+       stream.next_in = (void *) pdu + sizeof(*pdu);
        while (stream.avail_in) {
                unsigned int this_chunk = 65536;
                unsigned int this_len;
@@ -998,6 +1002,8 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd)
                err = inflate(&stream, Z_NO_FLUSH);
                if (err != Z_OK) {
                        log_err("fio: inflate error %d\n", err);
+                       free(ret);
+                       ret = NULL;
                        goto out;
                }
 
@@ -1006,7 +1012,15 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd)
                total -= this_len;
        }
 
-       ret->log_type = cpu_to_le32(ret->log_type);
+       for (i = 0; i < ret->nr_samples; i++) {
+               struct io_sample *s = &ret->samples[i];
+
+               s->time = le64_to_cpu(s->time);
+               s->val  = le64_to_cpu(s->val);
+               s->ddir = le32_to_cpu(s->ddir);
+               s->bs   = le32_to_cpu(s->bs);
+       }
+
 out:
        inflateEnd(&stream);
        return ret;
diff --git a/iolog.c b/iolog.c
index 88adbf7fb62720224fa6b0dd566067e77cb6855d..7b212bb598f124c3ce745e8f08918d4d0efd4f4d 100644 (file)
--- a/iolog.c
+++ b/iolog.c
@@ -536,10 +536,12 @@ void finish_log_named(struct thread_data *td, struct io_log *log,
        snprintf(file_name, 200, "%s_%s.log", prefix, postfix);
        p = basename(file_name);
 
-       if (td->client_type == FIO_CLIENT_TYPE_GUI)
+       if (td->client_type == FIO_CLIENT_TYPE_GUI) {
                fio_send_iolog(td, log, p);
-
-       __finish_log(log, p);
+               free(log->log);
+               free(log);
+       } else
+               __finish_log(log, p);
 }
 
 void finish_log(struct thread_data *td, struct io_log *log, const char *name)
index 4e1f39be52568ae3f55ff7f8d7913a125b5e50dd..b57c8b2cb408d2dcd72575c10962a2c3f1e285f3 100644 (file)
--- a/server.c
+++ b/server.c
@@ -853,27 +853,23 @@ void fio_server_send_du(void)
 
 int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
 {
-       struct cmd_iolog_pdu *pdu;
+       struct cmd_iolog_pdu pdu;
        struct fio_net_cmd cmd;
        z_stream stream;
        void *out_pdu;
-       size_t p_size;
        int i;
 
-       p_size = sizeof(*pdu) + log->nr_samples * sizeof(struct io_sample);
-       pdu = malloc(p_size);
-
-       pdu->nr_samples = __cpu_to_le32(log->nr_samples);
-       pdu->log_type = cpu_to_le32(log->log_type);
-       strcpy((char *) pdu->name, name);
+       pdu.nr_samples = __cpu_to_le32(log->nr_samples);
+       pdu.log_type = cpu_to_le32(log->log_type);
+       strcpy((char *) pdu.name, name);
 
        for (i = 0; i < log->nr_samples; i++) {
-               struct io_sample *s = &pdu->samples[i];
+               struct io_sample *s = &log->log[i];
 
-               s->time = cpu_to_le64(log->log[i].time);
-               s->val  = cpu_to_le64(log->log[i].val);
-               s->ddir = cpu_to_le32(log->log[i].ddir);
-               s->bs   = cpu_to_le32(log->log[i].bs);
+               s->time = cpu_to_le64(s->time);
+               s->val  = cpu_to_le64(s->val);
+               s->ddir = cpu_to_le32(s->ddir);
+               s->bs   = cpu_to_le32(s->bs);
        }
 
        /*
@@ -889,29 +885,27 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
 
        if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
                free(out_pdu);
-               free(pdu);
                return 1;
        }
 
        /*
-        * Don't compress the nr samples entry, we want to know on the
-        * client side how much data to allocate before starting inflate.
+        * Send header first, it's not compressed.
         */
-       __fio_init_net_cmd(&cmd, FIO_NET_CMD_IOLOG, sizeof(pdu->nr_samples), 0);
+       __fio_init_net_cmd(&cmd, FIO_NET_CMD_IOLOG, sizeof(pdu), 0);
        cmd.flags = __cpu_to_le32(FIO_NET_CMD_F_MORE);
-       fio_net_cmd_crc_pdu(&cmd, pdu);
+       fio_net_cmd_crc_pdu(&cmd, &pdu);
        fio_send_data(server_fd, &cmd, sizeof(cmd));
-       fio_send_data(server_fd, pdu, sizeof(pdu->nr_samples));
+       fio_send_data(server_fd, &pdu, sizeof(pdu));
 
-       stream.next_in = (void *) pdu + sizeof(pdu->nr_samples);
-       stream.avail_in = p_size - sizeof(pdu->nr_samples);
+       stream.next_in = (void *) log->log;
+       stream.avail_in = log->nr_samples * sizeof(struct io_sample);
 
        do {
                unsigned int this_len;
 
                stream.avail_out = FIO_SERVER_MAX_FRAGMENT_PDU;
                stream.next_out = out_pdu;
-               deflate(&stream, Z_FINISH);
+               assert(deflate(&stream, Z_FINISH) == Z_OK);
 
                this_len = FIO_SERVER_MAX_FRAGMENT_PDU - stream.avail_out;
 
@@ -926,7 +920,6 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
                fio_send_data(server_fd, out_pdu, this_len);
        } while (stream.avail_in);
 
-       free(pdu);
        free(out_pdu);
        deflateEnd(&stream);
        return 0;