Optimize the code that copies strings
[fio.git] / server.c
index 6f85810963e694129656a7640749cb52a0ed04a6..e7846227f2b19bebbb569d40676a9b288c696b2f 100644 (file)
--- a/server.c
+++ b/server.c
@@ -2,7 +2,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/socket.h>
@@ -28,7 +28,7 @@
 
 int fio_net_port = FIO_NET_PORT;
 
-int exit_backend = 0;
+bool exit_backend = false;
 
 enum {
        SK_F_FREE       = 1,
@@ -296,6 +296,8 @@ static int verify_convert_cmd(struct fio_net_cmd *cmd)
        if (crc != cmd->cmd_crc16) {
                log_err("fio: server bad crc on command (got %x, wanted %x)\n",
                                cmd->cmd_crc16, crc);
+               fprintf(f_err, "fio: server bad crc on command (got %x, wanted %x)\n",
+                               cmd->cmd_crc16, crc);
                return 1;
        }
 
@@ -310,6 +312,8 @@ static int verify_convert_cmd(struct fio_net_cmd *cmd)
                break;
        default:
                log_err("fio: bad server cmd version %d\n", cmd->version);
+               fprintf(f_err, "fio: client/server version mismatch (%d != %d)\n",
+                               cmd->version, FIO_SERVER_VER);
                return 1;
        }
 
@@ -526,6 +530,9 @@ static struct sk_entry *fio_net_prep_cmd(uint16_t opcode, void *buf,
        struct sk_entry *entry;
 
        entry = smalloc(sizeof(*entry));
+       if (!entry)
+               return NULL;
+
        INIT_FLIST_HEAD(&entry->next);
        entry->opcode = opcode;
        if (flags & SK_F_COPY) {
@@ -614,7 +621,7 @@ static int fio_net_queue_quit(void)
 {
        dprint(FD_NET, "server: sending quit\n");
 
-       return fio_net_queue_cmd(FIO_NET_CMD_QUIT, NULL, 0, NULL, SK_F_SIMPLE | SK_F_INLINE);
+       return fio_net_queue_cmd(FIO_NET_CMD_QUIT, NULL, 0, NULL, SK_F_SIMPLE);
 }
 
 int fio_net_send_quit(int sk)
@@ -634,7 +641,7 @@ static int fio_net_send_ack(struct fio_net_cmd *cmd, int error, int signal)
 
        epdu.error = __cpu_to_le32(error);
        epdu.signal = __cpu_to_le32(signal);
-       return fio_net_queue_cmd(FIO_NET_CMD_STOP, &epdu, sizeof(epdu), &tag, SK_F_COPY | SK_F_INLINE);
+       return fio_net_queue_cmd(FIO_NET_CMD_STOP, &epdu, sizeof(epdu), &tag, SK_F_COPY);
 }
 
 static int fio_net_queue_stop(int error, int signal)
@@ -858,7 +865,8 @@ static int handle_probe_cmd(struct fio_net_cmd *cmd)
        strcpy(me, (char *) pdu->server);
 
        gethostname((char *) probe.hostname, sizeof(probe.hostname));
-       strncpy((char *) probe.fio_version, fio_version_string, sizeof(probe.fio_version) - 1);
+       snprintf((char *) probe.fio_version, sizeof(probe.fio_version), "%s",
+                fio_version_string);
 
        /*
         * If the client supports compression and we do too, then enable it
@@ -988,7 +996,7 @@ static int handle_command(struct sk_out *sk_out, struct flist_head *job_list,
                ret = 0;
                break;
        case FIO_NET_CMD_EXIT:
-               exit_backend = 1;
+               exit_backend = true;
                return -1;
        case FIO_NET_CMD_LOAD_FILE:
                ret = handle_load_file_cmd(cmd);
@@ -1196,7 +1204,6 @@ static int handle_connection(struct sk_out *sk_out)
                        .events = POLLIN,
                };
 
-               ret = 0;
                do {
                        int timeout = 1000;
 
@@ -1356,7 +1363,12 @@ static int accept_loop(int listen_sk)
 
                dprint(FD_NET, "server: connect from %s\n", from);
 
-               sk_out = smalloc(sizeof(*sk_out));
+               sk_out = scalloc(1, sizeof(*sk_out));
+               if (!sk_out) {
+                       close(sk);
+                       return -1;
+               }
+
                sk_out->sk = sk;
                INIT_FLIST_HEAD(&sk_out->list);
                __fio_sem_init(&sk_out->lock, FIO_SEM_UNLOCKED);
@@ -1459,9 +1471,10 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
 
        memset(&p, 0, sizeof(p));
 
-       strncpy(p.ts.name, ts->name, FIO_JOBNAME_SIZE - 1);
-       strncpy(p.ts.verror, ts->verror, FIO_VERROR_SIZE - 1);
-       strncpy(p.ts.description, ts->description, FIO_JOBDESC_SIZE - 1);
+       snprintf(p.ts.name, sizeof(p.ts.name), "%s", ts->name);
+       snprintf(p.ts.verror, sizeof(p.ts.verror), "%s", ts->verror);
+       snprintf(p.ts.description, sizeof(p.ts.description), "%s",
+                ts->description);
 
        p.ts.error              = cpu_to_le32(ts->error);
        p.ts.thread_number      = cpu_to_le32(ts->thread_number);
@@ -1519,6 +1532,7 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
 
        p.ts.total_submit       = cpu_to_le64(ts->total_submit);
        p.ts.total_complete     = cpu_to_le64(ts->total_complete);
+       p.ts.nr_zone_resets     = cpu_to_le64(ts->nr_zone_resets);
 
        for (i = 0; i < DDIR_RWDIR_CNT; i++) {
                p.ts.io_bytes[i]        = cpu_to_le64(ts->io_bytes[i]);
@@ -1551,6 +1565,9 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
        p.ts.ss_deviation.u.i   = cpu_to_le64(fio_double_to_uint64(ts->ss_deviation.u.f));
        p.ts.ss_criterion.u.i   = cpu_to_le64(fio_double_to_uint64(ts->ss_criterion.u.f));
 
+       p.ts.cachehit           = cpu_to_le64(ts->cachehit);
+       p.ts.cachemiss          = cpu_to_le64(ts->cachemiss);
+
        convert_gs(&p.rs, rs);
 
        dprint(FD_NET, "ts->ss_state = %d\n", ts->ss_state);
@@ -1587,7 +1604,7 @@ void fio_server_send_gs(struct group_run_stats *rs)
 }
 
 void fio_server_send_job_options(struct flist_head *opt_list,
-                                unsigned int groupid)
+                                unsigned int gid)
 {
        struct cmd_job_option pdu;
        struct flist_head *entry;
@@ -1602,12 +1619,12 @@ void fio_server_send_job_options(struct flist_head *opt_list,
                p = flist_entry(entry, struct print_option, list);
                memset(&pdu, 0, sizeof(pdu));
 
-               if (groupid == -1U) {
+               if (gid == -1U) {
                        pdu.global = __cpu_to_le16(1);
                        pdu.groupid = 0;
                } else {
                        pdu.global = 0;
-                       pdu.groupid = cpu_to_le32(groupid);
+                       pdu.groupid = cpu_to_le32(gid);
                }
                len = strlen(p->name);
                if (len >= sizeof(pdu.name)) {
@@ -1648,8 +1665,7 @@ static void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src)
 {
        int i;
 
-       dst->name[FIO_DU_NAME_SZ - 1] = '\0';
-       strncpy((char *) dst->name, (char *) src->name, FIO_DU_NAME_SZ - 1);
+       snprintf((char *) dst->name, sizeof(dst->name), "%s", src->name);
 
        for (i = 0; i < 2; i++) {
                dst->s.ios[i]           = cpu_to_le64(src->s.ios[i]);
@@ -1693,8 +1709,8 @@ static inline void __fio_net_prep_tail(z_stream *stream, void *out_pdu,
 
        *last_entry = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, out_pdu, this_len,
                                 NULL, SK_F_VEC | SK_F_INLINE | SK_F_FREE);
-       flist_add_tail(&(*last_entry)->list, &first->next);
-
+       if (*last_entry)
+               flist_add_tail(&(*last_entry)->list, &first->next);
 }
 
 /*
@@ -1710,9 +1726,10 @@ static int __deflate_pdu_buffer(void *next_in, unsigned int next_sz, void **out_
        stream->next_in = next_in;
        stream->avail_in = next_sz;
        do {
-               if (! stream->avail_out) {
-
+               if (!stream->avail_out) {
                        __fio_net_prep_tail(stream, *out_pdu, last_entry, first);
+                       if (*last_entry == NULL)
+                               return 1;
 
                        *out_pdu = malloc(FIO_SERVER_MAX_FRAGMENT_PDU);
 
@@ -1776,8 +1793,7 @@ static int __fio_append_iolog_gz_hist(struct sk_entry *first, struct io_log *log
        }
 
        __fio_net_prep_tail(stream, out_pdu, &entry, first);
-
-       return 0;
+       return entry == NULL;
 }
 
 static int __fio_append_iolog_gz(struct sk_entry *first, struct io_log *log,
@@ -1816,6 +1832,10 @@ static int __fio_append_iolog_gz(struct sk_entry *first, struct io_log *log,
 
                entry = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, out_pdu, this_len,
                                         NULL, SK_F_VEC | SK_F_INLINE | SK_F_FREE);
+               if (!entry) {
+                       free(out_pdu);
+                       return 1;
+               }
                flist_add_tail(&entry->list, &first->next);
        } while (stream->avail_in);
 
@@ -1867,6 +1887,10 @@ static int fio_append_iolog_gz(struct sk_entry *first, struct io_log *log)
 
                entry = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, out_pdu, this_len,
                                         NULL, SK_F_VEC | SK_F_INLINE | SK_F_FREE);
+               if (!entry) {
+                       free(out_pdu);
+                       break;
+               }
                flist_add_tail(&entry->list, &first->next);
        } while (ret != Z_STREAM_END);
 
@@ -1887,6 +1911,7 @@ static int fio_append_gz_chunks(struct sk_entry *first, struct io_log *log)
 {
        struct sk_entry *entry;
        struct flist_head *node;
+       int ret = 0;
 
        pthread_mutex_lock(&log->chunk_lock);
        flist_for_each(node, &log->chunk_list) {
@@ -1895,16 +1920,20 @@ static int fio_append_gz_chunks(struct sk_entry *first, struct io_log *log)
                c = flist_entry(node, struct iolog_compress, list);
                entry = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, c->buf, c->len,
                                                NULL, SK_F_VEC | SK_F_INLINE);
+               if (!entry) {
+                       ret = 1;
+                       break;
+               }
                flist_add_tail(&entry->list, &first->next);
        }
        pthread_mutex_unlock(&log->chunk_lock);
-
-       return 0;
+       return ret;
 }
 
 static int fio_append_text_log(struct sk_entry *first, struct io_log *log)
 {
        struct sk_entry *entry;
+       int ret = 0;
 
        while (!flist_empty(&log->io_logs)) {
                struct io_logs *cur_log;
@@ -1917,10 +1946,14 @@ static int fio_append_text_log(struct sk_entry *first, struct io_log *log)
 
                entry = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, cur_log->log, size,
                                                NULL, SK_F_VEC | SK_F_INLINE);
+               if (!entry) {
+                       ret = 1;
+                       break;
+               }
                flist_add_tail(&entry->list, &first->next);
        }
 
-       return 0;
+       return ret;
 }
 
 int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
@@ -1942,8 +1975,7 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
        else
                pdu.compressed = 0;
 
-       strncpy((char *) pdu.name, name, FIO_NET_NAME_MAX);
-       pdu.name[FIO_NET_NAME_MAX - 1] = '\0';
+       snprintf((char *) pdu.name, sizeof(pdu.name), "%s", name);
 
        /*
         * We can't do this for a pre-compressed log, but for that case,
@@ -1961,7 +1993,7 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
                        s->time         = cpu_to_le64(s->time);
                        s->data.val     = cpu_to_le64(s->data.val);
                        s->__ddir       = cpu_to_le32(s->__ddir);
-                       s->bs           = cpu_to_le32(s->bs);
+                       s->bs           = cpu_to_le64(s->bs);
 
                        if (log->log_offset) {
                                struct io_sample_offset *so = (void *) s;
@@ -1975,6 +2007,8 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
         * Assemble header entry first
         */
        first = fio_net_prep_cmd(FIO_NET_CMD_IOLOG, &pdu, sizeof(pdu), NULL, SK_F_VEC | SK_F_INLINE | SK_F_COPY);
+       if (!first)
+               return 1;
 
        /*
         * Now append actual log entries. If log compression was enabled on
@@ -2118,14 +2152,14 @@ static int fio_init_server_ip(void)
 #endif
 
        if (use_ipv6) {
-               const void *src = &saddr_in6.sin6_addr;
+               void *src = &saddr_in6.sin6_addr;
 
                addr = (struct sockaddr *) &saddr_in6;
                socklen = sizeof(saddr_in6);
                saddr_in6.sin6_family = AF_INET6;
                str = inet_ntop(AF_INET6, src, buf, sizeof(buf));
        } else {
-               const void *src = &saddr_in.sin_addr;
+               void *src = &saddr_in.sin_addr;
 
                addr = (struct sockaddr *) &saddr_in;
                socklen = sizeof(saddr_in);
@@ -2158,9 +2192,8 @@ static int fio_init_server_sock(void)
 
        mode = umask(000);
 
-       memset(&addr, 0, sizeof(addr));
        addr.sun_family = AF_UNIX;
-       strncpy(addr.sun_path, bind_sock, sizeof(addr.sun_path) - 1);
+       snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", bind_sock);
 
        len = sizeof(addr.sun_family) + strlen(bind_sock) + 1;
 
@@ -2193,7 +2226,7 @@ static int fio_init_server_connection(void)
 
        if (!bind_sock) {
                char *p, port[16];
-               const void *src;
+               void *src;
                int af;
 
                if (use_ipv6) {
@@ -2210,9 +2243,9 @@ static int fio_init_server_connection(void)
                if (p)
                        strcat(p, port);
                else
-                       strncpy(bind_str, port, sizeof(bind_str) - 1);
+                       snprintf(bind_str, sizeof(bind_str), "%s", port);
        } else
-               strncpy(bind_str, bind_sock, sizeof(bind_str) - 1);
+               snprintf(bind_str, sizeof(bind_str), "%s", bind_sock);
 
        log_info("fio: server listening on %s\n", bind_str);
 
@@ -2462,7 +2495,7 @@ void fio_server_got_signal(int signal)
                sk_out->sk = -1;
        else {
                log_info("\nfio: terminating on signal %d\n", signal);
-               exit_backend = 1;
+               exit_backend = true;
        }
 }
 
@@ -2544,7 +2577,7 @@ int fio_start_server(char *pidfile)
 
        setsid();
        openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
-       log_syslog = 1;
+       log_syslog = true;
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);