X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=client.c;h=678a62753021035568cec1fb54ac1f23e8d7bcca;hb=284b1e65aa9b35c67d8392e2257fd53b310bb1a3;hp=6371c2be8d9e05592864ae8168af0571f470fe2f;hpb=46bcd498f7b3fb55f7f048bf299f36bd8c8f7db1;p=fio.git diff --git a/client.c b/client.c index 6371c2be..678a6275 100644 --- a/client.c +++ b/client.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "fio.h" #include "client.h" @@ -950,6 +951,82 @@ static void convert_text(struct fio_net_cmd *cmd) pdu->log_usec = le64_to_cpu(pdu->log_usec); } +/* + * This has been compressed on the server side, since it can be big. + * Uncompress here. + */ +static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) +{ + struct cmd_iolog_pdu *pdu = (struct cmd_iolog_pdu *) cmd->payload; + struct cmd_iolog_pdu *ret; + uint32_t nr_samples; + unsigned long total; + z_stream stream; + void *p; + int i; + + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = 0; + stream.next_in = Z_NULL; + + if (inflateInit(&stream) != Z_OK) + return NULL; + + /* + * Get header first, it's not compressed + */ + nr_samples = le32_to_cpu(pdu->nr_samples); + + total = nr_samples * sizeof(struct io_sample); + ret = malloc(total + sizeof(*pdu)); + ret->nr_samples = 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); + stream.next_in = (void *) pdu + sizeof(*pdu); + while (stream.avail_in) { + unsigned int this_chunk = 65536; + unsigned int this_len; + int err; + + if (this_chunk > total) + this_chunk = total; + + stream.avail_out = this_chunk; + stream.next_out = p; + err = inflate(&stream, Z_NO_FLUSH); + /* may be Z_OK, or Z_STREAM_END */ + if (err < 0) { + log_err("fio: inflate error %d\n", err); + free(ret); + ret = NULL; + goto out; + } + + this_len = this_chunk - stream.avail_out; + p += this_len; + total -= this_len; + } + + 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; +} + int fio_handle_client(struct fio_client *client) { struct client_ops *ops = client->ops; @@ -1048,6 +1125,15 @@ int fio_handle_client(struct fio_client *client) ops->add_job(client, cmd); free(cmd); break; + case FIO_NET_CMD_IOLOG: + if (ops->iolog) { + struct cmd_iolog_pdu *pdu; + + pdu = convert_iolog(cmd); + ops->iolog(client, pdu); + } + free(cmd); + break; default: log_err("fio: unknown client op: %s\n", fio_server_op(cmd->opcode)); free(cmd);