X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=server.c;h=c2cf2ddd9d557e7e915083be0f10c8aaf46963de;hp=832454305d1f5f65e01fedfd13bc1785caad3282;hb=dacbbb8875c09e982d59e1c1a40879af81842a42;hpb=6348b5dee54f24f2e78872948653942336f4c14e diff --git a/server.c b/server.c index 83245430..c2cf2ddd 100644 --- a/server.c +++ b/server.c @@ -840,7 +840,8 @@ static int handle_connection(int sk) static int accept_loop(int listen_sk) { struct sockaddr_in addr; - socklen_t len = sizeof(addr); + struct sockaddr_in6 addr6; + socklen_t len = use_ipv6 ? sizeof(addr6) : sizeof(addr); struct pollfd pfd; int ret = 0, sk, flags, exitval = 0; FLIST_HEAD(conn_list); @@ -852,6 +853,8 @@ static int accept_loop(int listen_sk) fcntl(listen_sk, F_SETFL, flags); while (!exit_backend) { + const char *from; + char buf[64]; pid_t pid; pfd.fd = listen_sk; @@ -882,13 +885,22 @@ static int accept_loop(int listen_sk) if (exit_backend || ret < 0) break; - sk = accept(listen_sk, (struct sockaddr *) &addr, &len); + if (use_ipv6) + sk = accept(listen_sk, (struct sockaddr *) &addr6, &len); + else + sk = accept(listen_sk, (struct sockaddr *) &addr, &len); + if (sk < 0) { log_err("fio: accept: %s\n", strerror(errno)); return -1; } - dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr)); + if (use_ipv6) + from = inet_ntop(AF_INET6, (struct sockaddr *) &addr6.sin6_addr, buf, sizeof(buf)); + else + from = inet_ntop(AF_INET, (struct sockaddr *) &addr.sin_addr, buf, sizeof(buf)); + + dprint(FD_NET, "server: connect from %s\n", from); pid = fork(); if (pid) { @@ -975,9 +987,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); @@ -1042,6 +1054,11 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) p.ts.kb_base = cpu_to_le32(ts->kb_base); p.ts.unit_base = cpu_to_le32(ts->unit_base); + p.ts.latency_depth = cpu_to_le32(ts->latency_depth); + p.ts.latency_target = cpu_to_le64(ts->latency_target); + p.ts.latency_window = cpu_to_le64(ts->latency_window); + p.ts.latency_percentile.u.i = __cpu_to_le64(fio_double_to_uint64(ts->latency_percentile.u.f)); + convert_gs(&p.rs, rs); fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), NULL, NULL); @@ -1078,18 +1095,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) @@ -1121,7 +1139,7 @@ static int fio_send_cmd_ext_pdu(int sk, uint16_t opcode, const void *buf, struct fio_net_cmd cmd; struct iovec iov[2]; - iov[0].iov_base = &cmd; + iov[0].iov_base = (void *) &cmd; iov[0].iov_len = sizeof(cmd); iov[1].iov_base = (void *) buf; iov[1].iov_len = size; @@ -1250,6 +1268,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) @@ -1277,17 +1297,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; } @@ -1313,7 +1340,6 @@ 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); len = sizeof(addr.sun_family) + strlen(bind_sock) + 1; @@ -1369,47 +1395,45 @@ static int fio_init_server_connection(void) if (listen(sk, 0) < 0) { log_err("fio: listen: %s\n", strerror(errno)); + close(sk); return -1; } return sk; } -int fio_server_parse_host(const char *host, int *ipv6, struct in_addr *inp, +int fio_server_parse_host(const char *host, int ipv6, struct in_addr *inp, struct in6_addr *inp6) { int ret = 0; - if (*ipv6) + if (ipv6) ret = inet_pton(AF_INET6, host, inp6); else ret = inet_pton(AF_INET, host, inp); if (ret != 1) { - struct hostent *hent; + struct addrinfo hints, *res; - hent = gethostbyname(host); - if (!hent) { - log_err("fio: failed to resolve <%s>\n", host); - return 0; - } + memset(&hints, 0, sizeof(hints)); + hints.ai_family = ipv6 ? AF_INET6 : AF_INET; + hints.ai_socktype = SOCK_STREAM; - if (*ipv6) { - if (hent->h_addrtype != AF_INET6) { - log_info("fio: falling back to IPv4\n"); - *ipv6 = 0; - } else - memcpy(inp6, hent->h_addr_list[0], 16); - } - if (!*ipv6) { - if (hent->h_addrtype != AF_INET) { - log_err("fio: lookup type mismatch\n"); - return 0; - } - memcpy(inp, hent->h_addr_list[0], 4); + ret = getaddrinfo(host, NULL, &hints, &res); + if (ret) { + log_err("fio: failed to resolve <%s> (%s)\n", host, + gai_strerror(ret)); + return 1; } + + if (ipv6) + memcpy(inp6, &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr, sizeof(*inp6)); + else + memcpy(inp, &((struct sockaddr_in *) res->ai_addr)->sin_addr, sizeof(*inp)); + ret = 1; + freeaddrinfo(res); } return !(ret == 1); @@ -1471,7 +1495,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, ','); @@ -1494,7 +1518,7 @@ int fio_server_parse_string(const char *str, char **ptr, int *is_sock, *ptr = strdup(host); - if (fio_server_parse_host(*ptr, ipv6, inp, inp6)) { + if (fio_server_parse_host(*ptr, *ipv6, inp, inp6)) { free(*ptr); *ptr = NULL; return 1; @@ -1544,6 +1568,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; @@ -1557,6 +1597,8 @@ static int fio_server(void) if (sk < 0) return -1; + set_sig_handlers(); + ret = accept_loop(sk); close(sk); @@ -1642,6 +1684,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; } @@ -1653,6 +1696,7 @@ int fio_start_server(char *pidfile) } else if (pid) { int ret = write_pid(pid, pidfile); + free(pidfile); exit(ret); }