lib/pattern: include oslib/strcasestr.h
[fio.git] / client.c
index f4b95d325d9f83839ce951da4967390d0f0932b8..6c2a1ef3989e54ad39a41918c870bad301d9bc39 100644 (file)
--- 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);
@@ -1224,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;
@@ -1364,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;
 
@@ -1394,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;
@@ -1421,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;
@@ -1550,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);
@@ -1577,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: {