X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=server.c;h=077dce5c349f67efec5c76a6371e89e2a2a4724f;hp=dc70616a0826572efc79f4d0fcb35b8e2cc67f03;hb=9c0f3f3279985b724c2f1358bb05cc2c795f2265;hpb=a2879fea33ee8c701da766e2def867f7fb2d052e diff --git a/server.c b/server.c index dc70616a..077dce5c 100644 --- a/server.c +++ b/server.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -68,7 +67,7 @@ static const char *fio_server_ops[FIO_NET_CMD_NR] = { "DISK_UTIL", "SERVER_START", "ADD_JOB", - "CMD_RUN" + "CMD_RUN", "CMD_IOLOG", }; @@ -209,7 +208,7 @@ static int verify_convert_cmd(struct fio_net_cmd *cmd) */ struct fio_net_cmd *fio_net_recv_cmd(int sk) { - struct fio_net_cmd cmd, *cmdret = NULL; + struct fio_net_cmd cmd, *tmp, *cmdret = NULL; size_t cmd_size = 0, pdu_offset = 0; uint16_t crc; int ret, first = 1; @@ -232,7 +231,19 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk) } else cmd_size += cmd.pdu_len; - cmdret = realloc(cmdret, cmd_size); + if (cmd_size / 1024 > FIO_SERVER_MAX_CMD_MB * 1024) { + log_err("fio: cmd+pdu too large (%llu)\n", (unsigned long long) cmd_size); + ret = 1; + break; + } + + tmp = realloc(cmdret, cmd_size); + if (!tmp) { + log_err("fio: server failed allocating cmd\n"); + ret = 1; + break; + } + cmdret = tmp; if (first) memcpy(cmdret, &cmd, sizeof(cmd)); @@ -843,14 +854,12 @@ static int accept_loop(int listen_sk) struct sockaddr_in6 addr6; socklen_t len = use_ipv6 ? sizeof(addr6) : sizeof(addr); struct pollfd pfd; - int ret = 0, sk, flags, exitval = 0; + int ret = 0, sk, exitval = 0; FLIST_HEAD(conn_list); dprint(FD_NET, "server enter accept loop\n"); - flags = fcntl(listen_sk, F_GETFL); - flags |= O_NONBLOCK; - fcntl(listen_sk, F_SETFL, flags); + fio_set_fd_nonblocking(listen_sk, "server"); while (!exit_backend) { const char *from; @@ -987,9 +996,9 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) memset(&p, 0, sizeof(p)); - strcpy(p.ts.name, ts->name); - strcpy(p.ts.verror, ts->verror); - strcpy(p.ts.description, ts->description); + 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); p.ts.error = cpu_to_le32(ts->error); p.ts.thread_number = cpu_to_le32(ts->thread_number); @@ -1095,18 +1104,19 @@ static void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src) { int i; - strcpy((char *) dst->name, (char *) src->name); + dst->name[FIO_DU_NAME_SZ - 1] = '\0'; + strncpy((char *) dst->name, (char *) src->name, FIO_DU_NAME_SZ - 1); for (i = 0; i < 2; i++) { - dst->ios[i] = cpu_to_le32(src->ios[i]); - dst->merges[i] = cpu_to_le32(src->merges[i]); - dst->sectors[i] = cpu_to_le64(src->sectors[i]); - dst->ticks[i] = cpu_to_le32(src->ticks[i]); + dst->s.ios[i] = cpu_to_le32(src->s.ios[i]); + dst->s.merges[i] = cpu_to_le32(src->s.merges[i]); + dst->s.sectors[i] = cpu_to_le64(src->s.sectors[i]); + dst->s.ticks[i] = cpu_to_le32(src->s.ticks[i]); } - dst->io_ticks = cpu_to_le32(src->io_ticks); - dst->time_in_queue = cpu_to_le32(src->time_in_queue); - dst->msec = cpu_to_le64(src->msec); + dst->s.io_ticks = cpu_to_le32(src->s.io_ticks); + dst->s.time_in_queue = cpu_to_le32(src->s.time_in_queue); + dst->s.msec = cpu_to_le64(src->s.msec); } void fio_server_send_du(void) @@ -1215,7 +1225,9 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) pdu.nr_samples = __cpu_to_le32(log->nr_samples); pdu.log_type = cpu_to_le32(log->log_type); pdu.compressed = cpu_to_le32(use_zlib); - strcpy((char *) pdu.name, name); + + strncpy((char *) pdu.name, name, FIO_NET_NAME_MAX); + pdu.name[FIO_NET_NAME_MAX - 1] = '\0'; for (i = 0; i < log->nr_samples; i++) { struct io_sample *s = &log->log[i]; @@ -1267,6 +1279,8 @@ static int fio_init_server_ip(void) { struct sockaddr *addr; socklen_t socklen; + char buf[80]; + const char *str; int sk, opt; if (use_ipv6) @@ -1294,17 +1308,24 @@ static int fio_init_server_ip(void) #endif if (use_ipv6) { + const 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; + addr = (struct sockaddr *) &saddr_in; socklen = sizeof(saddr_in); saddr_in.sin_family = AF_INET; + str = inet_ntop(AF_INET, src, buf, sizeof(buf)); } if (bind(sk, addr, socklen) < 0) { log_err("fio: bind: %s\n", strerror(errno)); + log_info("fio: failed with IPv%c %s\n", use_ipv6 ? '6' : '4', str); close(sk); return -1; } @@ -1329,8 +1350,7 @@ static int fio_init_server_sock(void) memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, bind_sock); - unlink(bind_sock); + strncpy(addr.sun_path, bind_sock, sizeof(addr.sun_path) - 1); len = sizeof(addr.sun_family) + strlen(bind_sock) + 1; @@ -1359,6 +1379,8 @@ static int fio_init_server_connection(void) if (sk < 0) return sk; + memset(bind_str, 0, sizeof(bind_str)); + if (!bind_sock) { char *p, port[16]; const void *src; @@ -1378,14 +1400,15 @@ static int fio_init_server_connection(void) if (p) strcat(p, port); else - strcpy(bind_str, port); + strncpy(bind_str, port, sizeof(bind_str) - 1); } else - strcpy(bind_str, bind_sock); + strncpy(bind_str, bind_sock, sizeof(bind_str) - 1); log_info("fio: server listening on %s\n", bind_str); if (listen(sk, 0) < 0) { log_err("fio: listen: %s\n", strerror(errno)); + close(sk); return -1; } @@ -1485,7 +1508,7 @@ int fio_server_parse_string(const char *str, char **ptr, int *is_sock, } /* - * If no port seen yet, check if there's a last ':' at the end + * If no port seen yet, check if there's a last ',' at the end */ if (!lport) { portp = strchr(host, ','); @@ -1558,6 +1581,22 @@ out: return ret; } +static void sig_int(int sig) +{ + if (bind_sock) + unlink(bind_sock); +} + +static void set_sig_handlers(void) +{ + struct sigaction act; + + memset(&act, 0, sizeof(act)); + act.sa_handler = sig_int; + act.sa_flags = SA_RESTART; + sigaction(SIGINT, &act, NULL); +} + static int fio_server(void) { int sk, ret; @@ -1571,6 +1610,8 @@ static int fio_server(void) if (sk < 0) return -1; + set_sig_handlers(); + ret = accept_loop(sk); close(sk); @@ -1656,6 +1697,7 @@ int fio_start_server(char *pidfile) if (check_existing_pidfile(pidfile)) { log_err("fio: pidfile %s exists and server appears alive\n", pidfile); + free(pidfile); return -1; } @@ -1667,6 +1709,7 @@ int fio_start_server(char *pidfile) } else if (pid) { int ret = write_pid(pid, pidfile); + free(pidfile); exit(ret); }