server: convert iolog in place instead of copy allocating it
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/client.c b/client.c
index c49e9a1..f7b050b 100644
--- a/client.c
+++ b/client.c
@@ -963,6 +963,7 @@
unsigned long total;
z_stream stream;
void *p;
+ int i;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
@@ -974,17 +975,20 @@
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);
- stream.avail_in = cmd->pdu_len - sizeof(pdu->nr_samples);
- stream.next_in = (void *) pdu + sizeof(pdu->nr_samples);
+ p = (void *) ret + sizeof(*pdu);
+
+ 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 @@
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 @@
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 88adbf7..7b212bb 100644
--- a/iolog.c
+++ b/iolog.c
@@ -536,10 +536,12 @@
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)
diff --git a/server.c b/server.c
index 4e1f39b..b57c8b2 100644
--- a/server.c
+++ b/server.c
@@ -853,27 +853,23 @@
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 @@
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 @@
fio_send_data(server_fd, out_pdu, this_len);
} while (stream.avail_in);
- free(pdu);
free(out_pdu);
deflateEnd(&stream);
return 0;