X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=server.c;h=31f179493aabf949edb8870dff154f99afba19a1;hp=a8d4868fa1f30e75d2d4e42a6b2f1eeba9ee0c8d;hb=2a2804c95571c5bc9f3fc9e6e5b422fa90aa5670;hpb=9e31134635165bc4c64c18da5d9e8bb44987978d diff --git a/server.c b/server.c index a8d4868f..31f17949 100644 --- a/server.c +++ b/server.c @@ -21,6 +21,7 @@ #endif #include "fio.h" +#include "options.h" #include "server.h" #include "crc/crc16.h" #include "lib/ieee754.h" @@ -333,7 +334,7 @@ static uint64_t alloc_reply(uint64_t tag, uint16_t opcode) reply = calloc(1, sizeof(*reply)); INIT_FLIST_HEAD(&reply->list); - gettimeofday(&reply->tv, NULL); + fio_gettime(&reply->tv, NULL); reply->saved_tag = tag; reply->opcode = opcode; @@ -600,7 +601,7 @@ static int handle_run_cmd(struct flist_head *job_list, struct fio_net_cmd *cmd) return 0; } - ret = fio_backend(); + ret = fio_backend(NULL); free_threads_shm(); _exit(ret); } @@ -708,33 +709,39 @@ static int handle_send_eta_cmd(struct fio_net_cmd *cmd) size_t size; int i; - je = get_jobs_eta(1, &size); - if (!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->nr_setting_up = cpu_to_le32(je->nr_setting_up); - je->files_open = cpu_to_le32(je->files_open); + /* + * Fake ETA return if we don't have a local one, otherwise the client + * will end up timing out waiting for a response to the ETA request + */ + je = get_jobs_eta(true, &size); + if (!je) { + size = sizeof(*je); + je = calloc(1, size); + } else { + 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->nr_setting_up = cpu_to_le32(je->nr_setting_up); + je->files_open = cpu_to_le32(je->files_open); + + for (i = 0; i < DDIR_RWDIR_CNT; i++) { + je->m_rate[i] = cpu_to_le32(je->m_rate[i]); + je->t_rate[i] = cpu_to_le32(je->t_rate[i]); + je->m_iops[i] = cpu_to_le32(je->m_iops[i]); + je->t_iops[i] = cpu_to_le32(je->t_iops[i]); + je->rate[i] = cpu_to_le32(je->rate[i]); + je->iops[i] = cpu_to_le32(je->iops[i]); + } - for (i = 0; i < DDIR_RWDIR_CNT; i++) { - je->m_rate[i] = cpu_to_le32(je->m_rate[i]); - je->t_rate[i] = cpu_to_le32(je->t_rate[i]); - je->m_iops[i] = cpu_to_le32(je->m_iops[i]); - je->t_iops[i] = cpu_to_le32(je->t_iops[i]); - je->rate[i] = cpu_to_le32(je->rate[i]); - je->iops[i] = cpu_to_le32(je->iops[i]); + je->elapsed_sec = cpu_to_le64(je->elapsed_sec); + je->eta_sec = cpu_to_le64(je->eta_sec); + je->nr_threads = cpu_to_le32(je->nr_threads); + je->is_pow2 = cpu_to_le32(je->is_pow2); + je->unit_base = cpu_to_le32(je->unit_base); } - je->elapsed_sec = cpu_to_le64(je->elapsed_sec); - je->eta_sec = cpu_to_le64(je->eta_sec); - je->nr_threads = cpu_to_le32(je->nr_threads); - je->is_pow2 = cpu_to_le32(je->is_pow2); - je->unit_base = cpu_to_le32(je->unit_base); - fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, &tag, NULL); free(je); return 0; @@ -936,6 +943,39 @@ static int handle_connection(int sk) _exit(ret); } +/* get the address on this host bound by the input socket, + * whether it is ipv6 or ipv4 */ + +int get_my_addr_str( int sk ) +{ + int ret; + struct sockaddr * sockaddr_p; + struct sockaddr_in myaddr4 = {0}; + struct sockaddr_in6 myaddr6 = {0}; + char * net_addr; + socklen_t len = use_ipv6 ? sizeof(myaddr6) : sizeof(myaddr4); + + if (use_ipv6) + sockaddr_p = (struct sockaddr * )&myaddr6; + else + sockaddr_p = (struct sockaddr * )&myaddr4; + ret = getsockname(sk, sockaddr_p, &len); + if (ret) { + log_err("fio: getsockaddr: %s\n", strerror(errno)); + return -1; + } + if (use_ipv6) + net_addr = (char * )&myaddr6.sin6_addr; + else + net_addr = (char * )&myaddr4.sin_addr; + if (NULL == inet_ntop(use_ipv6?AF_INET6:AF_INET, net_addr, client_sockaddr_str, INET6_ADDRSTRLEN-1)) { + log_err("inet_ntop: failed to convert addr to string\n"); + return -1; + } + dprint(FD_NET, "fio server bound to addr %s\n", client_sockaddr_str); + return 0; +} + static int accept_loop(int listen_sk) { struct sockaddr_in addr; @@ -1007,6 +1047,7 @@ static int accept_loop(int listen_sk) } /* exits */ + get_my_addr_str(sk); /* if error, it's already logged, non-fatal */ handle_connection(sk); } @@ -1158,6 +1199,10 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) 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)); + p.ts.nr_block_infos = le64_to_cpu(ts->nr_block_infos); + for (i = 0; i < p.ts.nr_block_infos; i++) + p.ts.block_infos[i] = le32_to_cpu(ts->block_infos[i]); + convert_gs(&p.rs, rs); fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), NULL, NULL); @@ -1178,14 +1223,14 @@ static void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src) int i; 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->ios[i] = cpu_to_le64(src->ios[i]); + dst->merges[i] = cpu_to_le64(src->merges[i]); dst->sectors[i] = cpu_to_le64(src->sectors[i]); - dst->ticks[i] = cpu_to_le32(src->ticks[i]); + dst->ticks[i] = cpu_to_le64(src->ticks[i]); } - dst->io_ticks = cpu_to_le32(src->io_ticks); - dst->time_in_queue = cpu_to_le32(src->time_in_queue); + dst->io_ticks = cpu_to_le64(src->io_ticks); + dst->time_in_queue = cpu_to_le64(src->time_in_queue); dst->slavecount = cpu_to_le32(src->slavecount); dst->max_util.u.i = cpu_to_le64(fio_double_to_uint64(src->max_util.u.f)); } @@ -1198,14 +1243,14 @@ static void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src) strncpy((char *) dst->name, (char *) src->name, FIO_DU_NAME_SZ - 1); for (i = 0; i < 2; 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.ios[i] = cpu_to_le64(src->s.ios[i]); + dst->s.merges[i] = cpu_to_le64(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->s.ticks[i] = cpu_to_le64(src->s.ticks[i]); } - 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.io_ticks = cpu_to_le64(src->s.io_ticks); + dst->s.time_in_queue = cpu_to_le64(src->s.time_in_queue); dst->s.msec = cpu_to_le64(src->s.msec); } @@ -1371,7 +1416,7 @@ void fio_server_send_start(struct thread_data *td) } int fio_server_get_verify_state(const char *name, int threadnumber, - void **datap) + void **datap, int *version) { struct thread_io_list *s; struct cmd_sendfile out; @@ -1391,7 +1436,8 @@ int fio_server_get_verify_state(const char *name, int threadnumber, rep->data = NULL; rep->error = 0; - verify_state_gen_name((char *) out.path, name, me, threadnumber); + verify_state_gen_name((char *) out.path, sizeof(out.path), name, me, + threadnumber); tag = (uint64_t) (uintptr_t) rep; fio_net_send_cmd(server_fd, FIO_NET_CMD_SENDFILE, &out, sizeof(out), &tag, NULL); @@ -1399,7 +1445,7 @@ int fio_server_get_verify_state(const char *name, int threadnumber, /* * Wait for the backend to receive the reply */ - if (fio_mutex_down_timeout(&rep->lock, 10)) { + if (fio_mutex_down_timeout(&rep->lock, 10000)) { log_err("fio: timed out waiting for reply\n"); goto fail; } @@ -1418,7 +1464,7 @@ fail: * the header, and the thread_io_list checksum */ s = rep->data + sizeof(struct verify_state_hdr); - if (verify_state_hdr(rep->data, s)) + if (verify_state_hdr(rep->data, s, version)) goto fail; /* @@ -1430,6 +1476,7 @@ fail: *datap = data; sfree(rep->data); + __fio_mutex_remove(&rep->lock); sfree(rep); return 0; } @@ -1454,13 +1501,13 @@ static int fio_init_server_ip(void) opt = 1; if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt)) < 0) { - log_err("fio: setsockopt: %s\n", strerror(errno)); + log_err("fio: setsockopt(REUSEADDR): %s\n", strerror(errno)); close(sk); return -1; } #ifdef SO_REUSEPORT if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { - log_err("fio: setsockopt: %s\n", strerror(errno)); + log_err("fio: setsockopt(REUSEPORT): %s\n", strerror(errno)); close(sk); return -1; }