X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=client.c;h=6c2a1ef3989e54ad39a41918c870bad301d9bc39;hp=366db71615306a98b6303b2f468682444b71f815;hb=a328eb9a738110546671242f04c1b1c63caa19ac;hpb=0279b88017b5d21f0fcbb1b57481339735c41797 diff --git a/client.c b/client.c index 366db716..6c2a1ef3 100644 --- a/client.c +++ b/client.c @@ -70,6 +70,8 @@ static int error_clients; #define FIO_CLIENT_HASH_MASK (FIO_CLIENT_HASH_SZ - 1) static struct flist_head client_hash[FIO_CLIENT_HASH_SZ]; +static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *, bool *); + static void fio_client_add_hash(struct fio_client *client) { int bucket = hash_long(client->fd, FIO_CLIENT_HASH_BITS); @@ -999,8 +1001,12 @@ 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->groupid = le16_to_cpu(pdu->groupid); + pdu->truncated = le16_to_cpu(pdu->truncated); + pdu->groupid = le32_to_cpu(pdu->groupid); p = malloc(sizeof(*p)); p->name = strdup((char *) pdu->name); @@ -1220,6 +1226,56 @@ static void handle_eta(struct fio_client *client, struct fio_net_cmd *cmd) fio_client_dec_jobs_eta(eta, client->ops->eta); } +static int fio_client_handle_iolog(struct fio_client *client, + struct fio_net_cmd *cmd) +{ + struct cmd_iolog_pdu *pdu; + bool store_direct; + + pdu = convert_iolog(cmd, &store_direct); + if (!pdu) { + log_err("fio: failed converting IO log\n"); + return 1; + } + + if (store_direct) { + ssize_t ret; + size_t sz; + int fd; + + fd = open((const char *) pdu->name, + O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) { + log_err("fio: open log: %s\n", strerror(errno)); + return 1; + } + + sz = cmd->pdu_len - sizeof(*pdu); + ret = write(fd, pdu->samples, sz); + close(fd); + + if (ret != sz) { + log_err("fio: short write on compressed log\n"); + return 1; + } + + return 0; + } else { + FILE *f; + + f = fopen((const char *) pdu->name, "w"); + if (!f) { + log_err("fio: fopen log: %s\n", strerror(errno)); + return 1; + } + + flush_samples(f, pdu->samples, + pdu->nr_samples * sizeof(struct io_sample)); + fclose(f); + return 0; + } +} + static void handle_probe(struct fio_client *client, struct fio_net_cmd *cmd) { struct cmd_probe_reply_pdu *probe = (struct cmd_probe_reply_pdu *) cmd->payload; @@ -1360,27 +1416,36 @@ err: * 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) +static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd, + bool *store_direct) { struct cmd_iolog_pdu *pdu = (struct cmd_iolog_pdu *) cmd->payload; struct cmd_iolog_pdu *ret; uint64_t i; + int compressed; void *samples; + *store_direct = false; + /* * Convert if compressed and we support it. If it's not * compressed, we need not do anything. */ - if (le32_to_cpu(pdu->compressed)) { + compressed = le32_to_cpu(pdu->compressed); + if (compressed == XMIT_COMPRESSED) { #ifndef CONFIG_ZLIB log_err("fio: server sent compressed data by mistake\n"); return NULL; #endif ret = convert_iolog_gz(cmd, pdu); + printf("compressed iolog, %p\n", ret); if (!ret) { log_err("fio: failed decompressing log\n"); return NULL; } + } else if (compressed == STORE_COMPRESSED) { + *store_direct = true; + ret = pdu; } else ret = pdu; @@ -1390,6 +1455,9 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) ret->compressed = le32_to_cpu(ret->compressed); ret->log_offset = le32_to_cpu(ret->log_offset); + if (*store_direct) + return ret; + samples = &ret->samples[0]; for (i = 0; i < ret->nr_samples; i++) { struct io_sample *s; @@ -1417,8 +1485,8 @@ static void sendfile_reply(int fd, struct cmd_sendfile_reply *rep, fio_net_send_cmd(fd, FIO_NET_CMD_SENDFILE, rep, size, &tag, NULL); } -static int send_file(struct fio_client *client, struct cmd_sendfile *pdu, - uint64_t tag) +static int fio_send_file(struct fio_client *client, struct cmd_sendfile *pdu, + uint64_t tag) { struct cmd_sendfile_reply *rep; struct stat sb; @@ -1546,12 +1614,7 @@ int fio_handle_client(struct fio_client *client) break; } case FIO_NET_CMD_IOLOG: - if (ops->iolog) { - struct cmd_iolog_pdu *pdu; - - pdu = convert_iolog(cmd); - ops->iolog(client, pdu); - } + fio_client_handle_iolog(client, cmd); break; case FIO_NET_CMD_UPDATE_JOB: ops->update_job(client, cmd); @@ -1573,7 +1636,7 @@ int fio_handle_client(struct fio_client *client) } case FIO_NET_CMD_SENDFILE: { struct cmd_sendfile *pdu = (struct cmd_sendfile *) cmd->payload; - send_file(client, pdu, cmd->tag); + fio_send_file(client, pdu, cmd->tag); break; } case FIO_NET_CMD_JOB_OPT: { @@ -1662,12 +1725,13 @@ static void request_client_etas(struct client_ops *ops) static int handle_cmd_timeout(struct fio_client *client, struct fio_net_cmd_reply *reply) { + flist_del(&reply->list); + free(reply); + if (reply->opcode != FIO_NET_CMD_SEND_ETA) return 1; log_info("client <%s>: timeout on SEND_ETA\n", client->hostname); - flist_del(&reply->list); - free(reply); flist_del_init(&client->eta_list); if (client->eta_in_flight) { @@ -1702,8 +1766,6 @@ static int client_check_cmd_timeout(struct fio_client *client, log_err("fio: client %s, timeout on cmd %s\n", client->hostname, fio_server_op(reply->opcode)); - flist_del(&reply->list); - free(reply); ret = 1; }