X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=client.c;h=7c9910961e7dee6685cd473b5d2193c0cd8a0391;hb=ad9c0fbc7ce6d1bba089f543036c997cbad84d7b;hp=ace70d357b97a3e882bacfea811e265779a85b44;hpb=93bcfd20e37cef8cec350fe06d3a086724c9f257;p=fio.git diff --git a/client.c b/client.c index ace70d35..7c991096 100644 --- a/client.c +++ b/client.c @@ -37,6 +37,7 @@ struct fio_client { char *hostname; int port; int fd; + unsigned int refs; char *name; @@ -48,6 +49,7 @@ struct fio_client { unsigned int jobs; int error; int ipv6; + int sent_job; struct flist_head eta_list; struct client_eta *eta_in_flight; @@ -118,8 +120,10 @@ static struct fio_client *find_client_by_fd(int fd) flist_for_each(entry, &client_hash[bucket]) { client = flist_entry(entry, struct fio_client, hash_list); - if (client->fd == fd) + if (client->fd == fd) { + client->refs++; return client; + } } return NULL; @@ -127,6 +131,11 @@ static struct fio_client *find_client_by_fd(int fd) static void remove_client(struct fio_client *client) { + assert(client->refs); + + if (--client->refs) + return; + dprint(FD_NET, "client: removed <%s>\n", client->hostname); flist_del(&client->list); @@ -148,6 +157,11 @@ static void remove_client(struct fio_client *client) sum_stat_clients--; } +static void put_client(struct fio_client *client) +{ + remove_client(client); +} + static void __fio_client_add_cmd_option(struct fio_client *client, const char *opt) { @@ -214,6 +228,7 @@ int fio_client_add(const char *hostname, void **cookie) return -1; client->fd = -1; + client->refs = 1; __fio_client_add_cmd_option(client, "fio"); @@ -329,6 +344,11 @@ static void sig_int(int sig) fio_clients_terminate(); } +static void sig_show_status(int sig) +{ + show_running_run_stats(); +} + static void client_signal_handler(void) { struct sigaction act; @@ -342,6 +362,11 @@ static void client_signal_handler(void) act.sa_handler = sig_int; act.sa_flags = SA_RESTART; sigaction(SIGTERM, &act, NULL); + + memset(&act, 0, sizeof(act)); + act.sa_handler = sig_show_status; + act.sa_flags = SA_RESTART; + sigaction(SIGUSR1, &act, NULL); } static void probe_client(struct fio_client *client) @@ -481,6 +506,7 @@ static int fio_client_send_ini(struct fio_client *client, const char *filename) return 1; } + client->sent_job = 1; ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOB, buf, sb.st_size, 0); free(buf); close(fd); @@ -497,6 +523,8 @@ int fio_clients_send_ini(const char *filename) if (fio_client_send_ini(client, filename)) remove_client(client); + + client->sent_job = 1; } return !nr_clients; @@ -697,6 +725,7 @@ static void convert_jobs_eta(struct jobs_eta *je) je->elapsed_sec = le64_to_cpu(je->elapsed_sec); je->eta_sec = le64_to_cpu(je->eta_sec); + je->is_pow2 = le32_to_cpu(je->is_pow2); } static void sum_jobs_eta(struct jobs_eta *dst, struct jobs_eta *je) @@ -788,9 +817,9 @@ static void handle_probe(struct fio_client *client, struct fio_net_cmd *cmd) sprintf(bit, "%d-bit", probe->bpp * 8); - log_info("hostname=%s, be=%u, %s, os=%s, arch=%s, fio=%u.%u.%u\n", + log_info("hostname=%s, be=%u, %s, os=%s, arch=%s, fio=%s\n", probe->hostname, probe->bigendian, bit, os, arch, - probe->fio_major, probe->fio_minor, probe->fio_patch); + probe->fio_version); if (!client->name) client->name = strdup((char *) probe->hostname); @@ -978,8 +1007,6 @@ static int fio_client_timed_out(void) int fio_handle_clients(void) { - struct fio_client *client; - struct flist_head *entry; struct pollfd *pfds; int i, ret = 0, retval = 0; @@ -992,15 +1019,27 @@ int fio_handle_clients(void) init_group_run_stat(&client_gs); while (!exit_backend && nr_clients) { + struct flist_head *entry, *tmp; + struct fio_client *client; + i = 0; - flist_for_each(entry, &client_list) { + flist_for_each_safe(entry, tmp, &client_list) { client = flist_entry(entry, struct fio_client, list); + if (!client->sent_job && + flist_empty(&client->cmd_list)) { + remove_client(client); + continue; + } + pfds[i].fd = client->fd; pfds[i].events = POLLIN; i++; } + if (!nr_clients) + break; + assert(i == nr_clients); do { @@ -1041,6 +1080,7 @@ int fio_handle_clients(void) retval = 1; } else if (client->error) retval = 1; + put_client(client); } }