client/server: ensure we don't overrun memory for long option values
[fio.git] / server.c
index 6d96a66fa30262022851e6e14847a9fd013c735f..f11e97278b20f52614269087e37393b2e94b3bf1 100644 (file)
--- a/server.c
+++ b/server.c
@@ -1512,6 +1512,47 @@ void fio_server_send_gs(struct group_run_stats *rs)
        fio_net_queue_cmd(FIO_NET_CMD_GS, &gs, sizeof(gs), NULL, SK_F_COPY);
 }
 
+void fio_server_send_job_options(struct flist_head *opt_list,
+                                unsigned int groupid)
+{
+       struct cmd_job_option pdu;
+       struct flist_head *entry;
+
+       if (flist_empty(opt_list))
+               return;
+
+       flist_for_each(entry, opt_list) {
+               struct print_option *p;
+               size_t len;
+
+               p = flist_entry(entry, struct print_option, list);
+               memset(&pdu, 0, sizeof(pdu));
+
+               if (groupid == -1U) {
+                       pdu.global = __cpu_to_le16(1);
+                       pdu.groupid = 0;
+               } else {
+                       pdu.global = 0;
+                       pdu.groupid = cpu_to_le32(groupid);
+               }
+               len = strlen(p->name);
+               if (len >= sizeof(pdu.name)) {
+                       len = sizeof(pdu.name) - 1;
+                       pdu.truncated = __cpu_to_le16(1);
+               }
+               memcpy(pdu.name, p->name, len);
+               if (p->value) {
+                       len = strlen(p->value);
+                       if (len >= sizeof(pdu.value)) {
+                               len = sizeof(pdu.value) - 1;
+                               pdu.truncated = __cpu_to_le16(1);
+                       }
+                       memcpy(pdu.value, p->value, len);
+               }
+               fio_net_queue_cmd(FIO_NET_CMD_JOB_OPT, &pdu, sizeof(pdu), NULL, SK_F_COPY);
+       }
+}
+
 static void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src)
 {
        int i;
@@ -1889,7 +1930,7 @@ static int fio_init_server_connection(void)
 
        log_info("fio: server listening on %s\n", bind_str);
 
-       if (listen(sk, 0) < 0) {
+       if (listen(sk, 4) < 0) {
                log_err("fio: listen: %s\n", strerror(errno));
                close(sk);
                return -1;
@@ -2084,6 +2125,13 @@ static int fio_server(void)
 {
        int sk, ret;
 
+       if (pthread_key_create(&sk_out_key, NULL)) {
+               log_err("fio: can't create sk_out backend key\n");
+               return -1;
+       }
+
+       pthread_setspecific(sk_out_key, NULL);
+
        dprint(FD_NET, "starting server\n");
 
        if (fio_handle_server_arg())
@@ -2095,9 +2143,6 @@ static int fio_server(void)
 
        set_sig_handlers();
 
-       if (pthread_key_create(&sk_out_key, NULL))
-               log_err("fio: can't create sk_out backend key\n");
-
        ret = accept_loop(sk);
 
        close(sk);