X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=server.c;h=5afd8d455f72c3178f9b9560719bd8e982cfca31;hb=af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07f;hp=c1a2824c12ad5675eda66a457de22811d85095ad;hpb=b94cba47cfdf96e72ec894080b3a7bf645a86e9c;p=fio.git diff --git a/server.c b/server.c index c1a2824c..5afd8d45 100644 --- a/server.c +++ b/server.c @@ -22,6 +22,8 @@ #include "crc/crc16.h" #include "ieee754.h" +#include "fio_version.h" + int fio_net_port = 8765; int exit_backend = 0; @@ -96,11 +98,11 @@ static int verify_convert_cmd(struct fio_net_cmd *cmd) cmd->version = le16_to_cpu(cmd->version); cmd->opcode = le16_to_cpu(cmd->opcode); cmd->flags = le32_to_cpu(cmd->flags); - cmd->serial = le64_to_cpu(cmd->serial); + cmd->tag = le64_to_cpu(cmd->tag); cmd->pdu_len = le32_to_cpu(cmd->pdu_len); switch (cmd->version) { - case FIO_SERVER_VER2: + case FIO_SERVER_VER: break; default: log_err("fio: bad server cmd version %d\n", cmd->version); @@ -203,7 +205,8 @@ void fio_net_cmd_crc(struct fio_net_cmd *cmd) cmd->pdu_crc16 = __cpu_to_le16(crc16(cmd->payload, pdu_len)); } -int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size) +int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size, + uint64_t tag) { struct fio_net_cmd *cmd; size_t this_len; @@ -216,7 +219,7 @@ int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size) cmd = malloc(sizeof(*cmd) + this_len); - fio_init_net_cmd(cmd, opcode, buf, this_len); + fio_init_net_cmd(cmd, opcode, buf, this_len, tag); if (this_len < size) cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE); @@ -232,11 +235,11 @@ int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size) return ret; } -int fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t serial) +int fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag) { struct fio_net_cmd cmd; - fio_init_net_cmd(&cmd, opcode, NULL, 0); + fio_init_net_cmd(&cmd, opcode, NULL, 0, tag); fio_net_cmd_crc(&cmd); return fio_send_data(sk, &cmd, sizeof(cmd)); @@ -268,24 +271,36 @@ static int handle_job_cmd(struct fio_net_cmd *cmd) static int handle_jobline_cmd(struct fio_net_cmd *cmd) { - struct cmd_line_pdu *pdu = (struct cmd_line_pdu *) cmd->payload; - char *argv[FIO_NET_CMD_JOBLINE_ARGV]; + void *pdu = cmd->payload; + struct cmd_single_line_pdu *cslp; + struct cmd_line_pdu *clp; + unsigned long offset; + char **argv; int ret, i; - pdu->argc = le16_to_cpu(pdu->argc); + clp = pdu; + clp->lines = le16_to_cpu(clp->lines); + argv = malloc(clp->lines * sizeof(char *)); + offset = sizeof(*clp); + + dprint(FD_NET, "server: %d command line args\n", clp->lines); - dprint(FD_NET, "server: %d command line args\n", pdu->argc); + for (i = 0; i < clp->lines; i++) { + cslp = pdu + offset; + argv[i] = (char *) cslp->text; - for (i = 0; i < pdu->argc; i++) { - argv[i] = (char *) pdu->argv[i]; + offset += sizeof(*cslp) + le16_to_cpu(cslp->len); dprint(FD_NET, "server: %d: %s\n", i, argv[i]); } - if (parse_cmd_line(pdu->argc, argv)) { + if (parse_cmd_line(clp->lines, argv)) { fio_server_send_quit_cmd(); + free(argv); return -1; } + free(argv); + fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0); ret = exec_run(); @@ -307,7 +322,51 @@ static int handle_probe_cmd(struct fio_net_cmd *cmd) probe.fio_minor = FIO_MINOR; probe.fio_patch = FIO_PATCH; - return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe)); + probe.os = FIO_OS; + probe.arch = FIO_ARCH; + + return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), 0); +} + +static int handle_send_eta_cmd(struct fio_net_cmd *cmd) +{ + struct jobs_eta *je; + size_t size; + void *buf; + int i; + + size = sizeof(*je) + thread_number * sizeof(char); + buf = malloc(size); + memset(buf, 0, size); + je = buf; + + if (!calc_thread_status(je, 1)) { + free(je); + return 0; + } + + dprint(FD_NET, "server sending status\n"); + + je->nr_running = cpu_to_le32(je->nr_running); + je->nr_ramp = cpu_to_le32(je->nr_ramp); + je->nr_pending = cpu_to_le32(je->nr_pending); + je->files_open = cpu_to_le32(je->files_open); + je->m_rate = cpu_to_le32(je->m_rate); + je->t_rate = cpu_to_le32(je->t_rate); + je->m_iops = cpu_to_le32(je->m_iops); + je->t_iops = cpu_to_le32(je->t_iops); + + for (i = 0; i < 2; i++) { + je->rate[i] = cpu_to_le32(je->rate[i]); + je->iops[i] = cpu_to_le32(je->iops[i]); + } + + je->elapsed_sec = cpu_to_le32(je->nr_running); + je->eta_sec = cpu_to_le64(je->eta_sec); + + fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, buf, size, cmd->tag); + free(je); + return 0; } static int handle_command(struct fio_net_cmd *cmd) @@ -332,6 +391,9 @@ static int handle_command(struct fio_net_cmd *cmd) case FIO_NET_CMD_PROBE: ret = handle_probe_cmd(cmd); break; + case FIO_NET_CMD_SEND_ETA: + ret = handle_send_eta_cmd(cmd); + break; default: log_err("fio: unknown opcode: %d\n", cmd->opcode); ret = 1; @@ -460,7 +522,7 @@ out: int fio_server_text_output(const char *buf, unsigned int len) { if (server_fd != -1) - return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len); + return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len, 0); return fwrite(buf, len, 1, f_err); } @@ -573,7 +635,7 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) convert_gs(&p.rs, rs); - fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p)); + fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0); } void fio_server_send_gs(struct group_run_stats *rs) @@ -583,47 +645,7 @@ void fio_server_send_gs(struct group_run_stats *rs) dprint(FD_NET, "server sending group run stats\n"); convert_gs(&gs, rs); - fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs)); -} - -void fio_server_send_status(void) -{ - struct jobs_eta *je; - size_t size; - void *buf; - int i; - - size = sizeof(*je) + thread_number * sizeof(char); - buf = malloc(size); - memset(buf, 0, size); - je = buf; - - if (!calc_thread_status(je)) { - free(je); - return; - } - - dprint(FD_NET, "server sending status\n"); - - je->nr_running = cpu_to_le32(je->nr_running); - je->nr_ramp = cpu_to_le32(je->nr_ramp); - je->nr_pending = cpu_to_le32(je->nr_pending); - je->files_open = cpu_to_le32(je->files_open); - je->m_rate = cpu_to_le32(je->m_rate); - je->t_rate = cpu_to_le32(je->t_rate); - je->m_iops = cpu_to_le32(je->m_iops); - je->t_iops = cpu_to_le32(je->t_iops); - - for (i = 0; i < 2; i++) { - je->rate[i] = cpu_to_le32(je->rate[i]); - je->iops[i] = cpu_to_le32(je->iops[i]); - } - - je->elapsed_sec = cpu_to_le32(je->nr_running); - je->eta_sec = cpu_to_le64(je->eta_sec); - - fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, buf, size); - free(je); + fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0); } int fio_server_log(const char *format, ...) @@ -666,7 +688,6 @@ static int fio_init_server_ip(void) #endif saddr_in.sin_family = AF_INET; - saddr_in.sin_port = htons(fio_net_port); if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) { log_err("fio: bind: %s\n", strerror(errno)); @@ -711,6 +732,7 @@ static int fio_init_server_sock(void) static int fio_init_server_connection(void) { + char bind_str[128]; int sk; dprint(FD_NET, "starting server\n"); @@ -723,6 +745,13 @@ static int fio_init_server_connection(void) if (sk < 0) return sk; + if (!bind_sock) + sprintf(bind_str, "%s:%u", inet_ntoa(saddr_in.sin_addr), fio_net_port); + else + strcpy(bind_str, bind_sock); + + log_info("fio: server listening on %s\n", bind_str); + if (listen(sk, 1) < 0) { log_err("fio: listen: %s\n", strerror(errno)); return -1; @@ -731,6 +760,80 @@ static int fio_init_server_connection(void) return sk; } +int fio_server_parse_string(const char *str, char **ptr, int *is_sock, + int *port, struct in_addr *inp) +{ + *ptr = NULL; + *is_sock = 0; + *port = fio_net_port; + + if (!strncmp(str, "sock:", 5)) { + *ptr = strdup(str + 5); + *is_sock = 1; + } else { + const char *host = str; + char *portp; + int lport = 0; + + /* + * Is it ip::port + */ + if (!strncmp(host, "ip:", 3)) + host += 3; + else if (host[0] == ':') { + /* String is :port */ + host++; + lport = atoi(host); + if (!lport || lport > 65535) { + log_err("fio: bad server port %u\n", port); + return 1; + } + /* no hostname given, we are done */ + *port = lport; + return 0; + } + + /* + * If no port seen yet, check if there's a last ':' at the end + */ + if (!lport) { + portp = strchr(host, ':'); + if (portp) { + *portp = '\0'; + portp++; + lport = atoi(portp); + if (!lport || lport > 65535) { + log_err("fio: bad server port %u\n", port); + return 1; + } + } + } + + if (lport) + *port = lport; + + *ptr = strdup(host); + + if (inet_aton(host, inp) != 1) { + struct hostent *hent; + + hent = gethostbyname(host); + if (!hent) { + free(*ptr); + *ptr = NULL; + return 1; + } + + memcpy(inp, hent->h_addr, 4); + } + } + + if (*port == 0) + *port = fio_net_port; + + return 0; +} + /* * Server arg should be one of: * @@ -745,28 +848,26 @@ static int fio_init_server_connection(void) */ static int fio_handle_server_arg(void) { + int port = fio_net_port; + int is_sock, ret = 0; + saddr_in.sin_addr.s_addr = htonl(INADDR_ANY); if (!fio_server_arg) - return 0; - if (!strncmp(fio_server_arg, "sock:", 5)) { - bind_sock = fio_server_arg += 5; - return 0; - } else { - char *host = fio_server_arg; + goto out; - if (!strncmp(host, "ip:", 3)) - host += 3; + ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock, + &port, &saddr_in.sin_addr); - if (inet_aton(host, &saddr_in.sin_addr) != 1) { - struct hostent *hent; - - hent = gethostbyname(host); - if (hent) - memcpy(&saddr_in.sin_addr, hent->h_addr, 4); - } - return 0; + if (!is_sock && bind_sock) { + free(bind_sock); + bind_sock = NULL; } + +out: + fio_net_port = port; + saddr_in.sin_port = htons(port); + return ret; } static int fio_server(void) @@ -790,6 +891,8 @@ static int fio_server(void) free(fio_server_arg); fio_server_arg = NULL; } + if (bind_sock) + free(bind_sock); return ret; } @@ -842,7 +945,7 @@ int fio_start_server(int daemonize) return fio_server(); } -void fio_server_add_arg(const char *arg) +void fio_server_set_arg(const char *arg) { fio_server_arg = strdup(arg); }