client.c revision 5fd0acbd212296542d396b07e1873b9e3093b76f
1132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <stdio.h>
2132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <stdlib.h>
3132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <unistd.h>
4132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <limits.h>
5132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <errno.h>
6132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <fcntl.h>
7132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <sys/poll.h>
8132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <sys/types.h>
9132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <sys/stat.h>
10132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <sys/wait.h>
11d05c4a03365f1b677c05840865e67ffaf2c5b05bJens Axboe#include <sys/socket.h>
1287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/un.h>
13132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <netinet/in.h>
14132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <arpa/inet.h>
15132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include <netdb.h>
169e22ecb0271038f61e00e448d8839f0c1bf6017eJens Axboe#include <signal.h>
17132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
18132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "fio.h"
19132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h"
20b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe#include "flist.h"
213c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#include "hash.h"
22132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
2382c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboestruct client_eta {
2482c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	struct jobs_eta eta;
2582c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	unsigned int pending;
2682c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe};
2782c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
28b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestruct fio_client {
29b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct flist_head list;
30bebe639808147d587bbe776566d390b9ff98773fJens Axboe	struct flist_head hash_list;
313f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	struct flist_head arg_list;
32b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct sockaddr_in addr;
3387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un addr_un;
34b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	char *hostname;
35bebe639808147d587bbe776566d390b9ff98773fJens Axboe	int port;
36b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	int fd;
3781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
38b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe	char *name;
39b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe
4081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	int state;
41af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
4217dd17648d337479104cbdbe177214ddb69a18ceJens Axboe	int skip_newline;
4387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int is_sock;
4482c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
4582c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	struct flist_head eta_list;
4682c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	struct client_eta *eta_in_flight;
4781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
4889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct flist_head cmd_list;
4989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
5081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	uint16_t argc;
5181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	char **argv;
5281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe};
5381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
54af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic struct timeval eta_tv;
5548fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
5681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboeenum {
575c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe	Client_created		= 0,
5881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	Client_connected	= 1,
5981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	Client_started		= 2,
6081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	Client_stopped		= 3,
615c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe	Client_exited		= 4,
62b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe};
63b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
64b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestatic FLIST_HEAD(client_list);
6582c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboestatic FLIST_HEAD(eta_list);
66b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
673f3a4542887ba038231144be08b2c36d7cc83424Jens Axboestatic FLIST_HEAD(arg_list);
683f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe
6937f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboestatic struct thread_stat client_ts;
7037f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboestatic struct group_run_stats client_gs;
7137f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboestatic int sum_stat_clients;
7237f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboestatic int sum_stat_nr;
7337f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
743c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#define FIO_CLIENT_HASH_BITS	7
753c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#define FIO_CLIENT_HASH_SZ	(1 << FIO_CLIENT_HASH_BITS)
763c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#define FIO_CLIENT_HASH_MASK	(FIO_CLIENT_HASH_SZ - 1)
77bebe639808147d587bbe776566d390b9ff98773fJens Axboestatic struct flist_head client_hash[FIO_CLIENT_HASH_SZ];
783c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
79e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestatic int handle_client(struct fio_client *client);
8082c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboestatic void dec_jobs_eta(struct client_eta *eta);
810b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
82bebe639808147d587bbe776566d390b9ff98773fJens Axboestatic void fio_client_add_hash(struct fio_client *client)
833c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe{
843c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	int bucket = hash_long(client->fd, FIO_CLIENT_HASH_BITS);
853c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
863c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	bucket &= FIO_CLIENT_HASH_MASK;
87bebe639808147d587bbe776566d390b9ff98773fJens Axboe	flist_add(&client->hash_list, &client_hash[bucket]);
883c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe}
893c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
90bebe639808147d587bbe776566d390b9ff98773fJens Axboestatic void fio_client_remove_hash(struct fio_client *client)
913c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe{
92bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!flist_empty(&client->hash_list))
93bebe639808147d587bbe776566d390b9ff98773fJens Axboe		flist_del_init(&client->hash_list);
943c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe}
953c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
963c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboestatic void fio_init fio_client_hash_init(void)
973c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe{
983c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	int i;
993c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
100bebe639808147d587bbe776566d390b9ff98773fJens Axboe	for (i = 0; i < FIO_CLIENT_HASH_SZ; i++)
101bebe639808147d587bbe776566d390b9ff98773fJens Axboe		INIT_FLIST_HEAD(&client_hash[i]);
1023c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe}
1033c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
104b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestatic struct fio_client *find_client_by_fd(int fd)
105b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe{
1063c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	int bucket = hash_long(fd, FIO_CLIENT_HASH_BITS) & FIO_CLIENT_HASH_MASK;
107b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct fio_client *client;
108b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct flist_head *entry;
109b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
110bebe639808147d587bbe776566d390b9ff98773fJens Axboe	flist_for_each(entry, &client_hash[bucket]) {
111bebe639808147d587bbe776566d390b9ff98773fJens Axboe		client = flist_entry(entry, struct fio_client, hash_list);
112b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
113b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe		if (client->fd == fd)
114b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			return client;
115b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	}
116b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
117b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	return NULL;
118b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe}
119b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
120b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestatic void remove_client(struct fio_client *client)
121b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe{
12239e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	dprint(FD_NET, "client: removed <%s>\n", client->hostname);
123b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	flist_del(&client->list);
1243c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
125bebe639808147d587bbe776566d390b9ff98773fJens Axboe	fio_client_remove_hash(client);
12681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
12782c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	if (!flist_empty(&client->eta_list)) {
12882c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		flist_del_init(&client->eta_list);
12982c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		dec_jobs_eta(client->eta_in_flight);
13082c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	}
131af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
132b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	free(client->hostname);
13381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (client->argv)
13481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		free(client->argv);
135b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe	if (client->name)
136b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe		free(client->name);
13781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
138b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	free(client);
1393c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	nr_clients--;
1405fd0acbd212296542d396b07e1873b9e3093b76fJens Axboe	sum_stat_clients--;
141b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe}
142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
143fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboestatic void __fio_client_add_cmd_option(struct fio_client *client,
144fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe					const char *opt)
14581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
14639e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	int index;
14739e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe
14839e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	index = client->argc++;
14981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	client->argv = realloc(client->argv, sizeof(char *) * client->argc);
15039e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	client->argv[index] = strdup(opt);
15139e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	dprint(FD_NET, "client: add cmd %d: %s\n", index, opt);
15281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
15381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
154fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboevoid fio_client_add_cmd_option(void *cookie, const char *opt)
15581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
156bebe639808147d587bbe776566d390b9ff98773fJens Axboe	struct fio_client *client = cookie;
1573f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	struct flist_head *entry;
15881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
159bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!client || !opt)
160fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		return;
16181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
162fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	__fio_client_add_cmd_option(client, opt);
1633f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe
1643f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	/*
1653f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	 * Duplicate arguments to shared client group
1663f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	 */
1673f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	flist_for_each(entry, &arg_list) {
1683f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		client = flist_entry(entry, struct fio_client, arg_list);
1693f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe
1703f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		__fio_client_add_cmd_option(client, opt);
1713f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	}
17281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
17381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
174bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_client_add(const char *hostname, void **cookie)
175132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
1763f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	struct fio_client *existing = *cookie;
177b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct fio_client *client;
178132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1793f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	if (existing) {
1803f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		/*
1813f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		 * We always add our "exec" name as the option, hence 1
1823f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		 * means empty.
1833f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		 */
1843f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		if (existing->argc == 1)
1853f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe			flist_add_tail(&existing->arg_list, &arg_list);
1863f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		else {
1873f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe			while (!flist_empty(&arg_list))
1883f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe				flist_del_init(arg_list.next);
1893f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		}
1903f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	}
1913f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe
192b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	client = malloc(sizeof(*client));
193a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	memset(client, 0, sizeof(*client));
19481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1953c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	INIT_FLIST_HEAD(&client->list);
196bebe639808147d587bbe776566d390b9ff98773fJens Axboe	INIT_FLIST_HEAD(&client->hash_list);
1973f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	INIT_FLIST_HEAD(&client->arg_list);
19882c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	INIT_FLIST_HEAD(&client->eta_list);
19989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	INIT_FLIST_HEAD(&client->cmd_list);
2003c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
201bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (fio_server_parse_string(hostname, &client->hostname,
202bebe639808147d587bbe776566d390b9ff98773fJens Axboe					&client->is_sock, &client->port,
203bebe639808147d587bbe776566d390b9ff98773fJens Axboe					&client->addr.sin_addr))
204bebe639808147d587bbe776566d390b9ff98773fJens Axboe		return -1;
20587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
206bebe639808147d587bbe776566d390b9ff98773fJens Axboe	client->fd = -1;
2073c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
20881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	__fio_client_add_cmd_option(client, "fio");
20981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
210a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	flist_add(&client->list, &client_list);
211a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	nr_clients++;
212bebe639808147d587bbe776566d390b9ff98773fJens Axboe	dprint(FD_NET, "client: added <%s>\n", client->hostname);
213bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*cookie = client;
214bebe639808147d587bbe776566d390b9ff98773fJens Axboe	return 0;
215a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe}
216a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
21787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_client_connect_ip(struct fio_client *client)
218a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe{
219a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	int fd;
220132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
221b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	client->addr.sin_family = AF_INET;
222bebe639808147d587bbe776566d390b9ff98773fJens Axboe	client->addr.sin_port = htons(client->port);
223132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
224132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fd = socket(AF_INET, SOCK_STREAM, 0);
225132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fd < 0) {
226132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
22787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
228132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
229132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
230b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	if (connect(fd, (struct sockaddr *) &client->addr, sizeof(client->addr)) < 0) {
231132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: connect: %s\n", strerror(errno));
232a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe		log_err("fio: failed to connect to %s:%u\n", client->hostname,
233a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe								client->port);
234b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
23587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
23687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
23787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
23887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return fd;
23987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
24087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
24187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_client_connect_sock(struct fio_client *client)
24287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
24387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un *addr = &client->addr_un;
24487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_socklen_t len;
24587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int fd;
24687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
24787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	memset(addr, 0, sizeof(*addr));
24887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	addr->sun_family = AF_UNIX;
24987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	strcpy(addr->sun_path, client->hostname);
25087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
25187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fd = socket(AF_UNIX, SOCK_STREAM, 0);
25287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fd < 0) {
25387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: socket: %s\n", strerror(errno));
25487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
25587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
25687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
25787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1;
25887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (connect(fd, (struct sockaddr *) addr, len) < 0) {
25987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: connect; %s\n", strerror(errno));
260b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
26187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
262132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
263132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
26487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return fd;
26587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
26687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
26787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_client_connect(struct fio_client *client)
26887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
26987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int fd;
27087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
27187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "client: connect to host %s\n", client->hostname);
27287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
27387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (client->is_sock)
27487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fd = fio_client_connect_sock(client);
27587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	else
27687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fd = fio_client_connect_ip(client);
27787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
27889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "client: %s connected %d\n", client->hostname, fd);
27989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
28087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fd < 0)
28187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return 1;
28287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
283b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	client->fd = fd;
284bebe639808147d587bbe776566d390b9ff98773fJens Axboe	fio_client_add_hash(client);
28581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	client->state = Client_connected;
286132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
288132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
289cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_clients_terminate(void)
290cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{
291cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	struct flist_head *entry;
292cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	struct fio_client *client;
293cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
29460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "client: terminate clients\n");
29560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
296cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	flist_for_each(entry, &client_list) {
297cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe		client = flist_entry(entry, struct fio_client, list);
298cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
29989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_QUIT, 0, NULL);
300cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	}
301cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
302cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
303cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboestatic void sig_int(int sig)
304cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{
305bebe639808147d587bbe776566d390b9ff98773fJens Axboe	dprint(FD_NET, "client: got signal %d\n", sig);
306cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	fio_clients_terminate();
307cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
308cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
309cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboestatic void client_signal_handler(void)
310cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{
311cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	struct sigaction act;
312cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
313cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	memset(&act, 0, sizeof(act));
314cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	act.sa_handler = sig_int;
315cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	act.sa_flags = SA_RESTART;
316cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	sigaction(SIGINT, &act, NULL);
317cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
318cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	memset(&act, 0, sizeof(act));
319cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	act.sa_handler = sig_int;
320cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	act.sa_flags = SA_RESTART;
321cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	sigaction(SIGTERM, &act, NULL);
322cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
323cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
3240b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboestatic void probe_client(struct fio_client *client)
3250b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe{
32660efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "client: send probe\n");
32760efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
32889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_PROBE, 0, &client->cmd_list);
3290b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe}
3300b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
33181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int send_client_cmd_line(struct fio_client *client)
33281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
333fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_single_line_pdu *cslp;
334fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_line_pdu *clp;
335fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	unsigned long offset;
3367f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	unsigned int *lens;
337fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	void *pdu;
338fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	size_t mem;
33981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	int i, ret;
34081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
34139e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	dprint(FD_NET, "client: send cmdline %d\n", client->argc);
34260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
3437f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	lens = malloc(client->argc * sizeof(unsigned int));
3447f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
345fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	/*
346fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	 * Find out how much mem we need
347fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	 */
3487f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	for (i = 0, mem = 0; i < client->argc; i++) {
3497f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		lens[i] = strlen(client->argv[i]) + 1;
3507f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		mem += lens[i];
3517f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	}
352fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
353fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	/*
354fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	 * We need one cmd_line_pdu, and argc number of cmd_single_line_pdu
355fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	 */
356fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	mem += sizeof(*clp) + (client->argc * sizeof(*cslp));
357fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
358fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	pdu = malloc(mem);
359fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp = pdu;
360fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	offset = sizeof(*clp);
361fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
362fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	for (i = 0; i < client->argc; i++) {
3637f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		uint16_t arg_len = lens[i];
364fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
365fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp = pdu + offset;
366fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		strcpy((char *) cslp->text, client->argv[i]);
367fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp->len = cpu_to_le16(arg_len);
368fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		offset += sizeof(*cslp) + arg_len;
369fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	}
37081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
3717f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	free(lens);
372fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp->lines = cpu_to_le16(client->argc);
373af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOBLINE, pdu, mem, 0);
37481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	free(pdu);
37581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
37681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
37781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
378a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboeint fio_clients_connect(void)
379a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe{
380a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	struct fio_client *client;
381a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	struct flist_head *entry, *tmp;
382a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	int ret;
383a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
38460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "client: connect all\n");
38560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
386cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	client_signal_handler();
387cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
388a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	flist_for_each_safe(entry, tmp, &client_list) {
389a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe		client = flist_entry(entry, struct fio_client, list);
390a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
391a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe		ret = fio_client_connect(client);
3920b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (ret) {
393a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe			remove_client(client);
3940b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			continue;
3950b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		}
3960b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
3970b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		probe_client(client);
39881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
39981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		if (client->argc > 1)
40081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe			send_client_cmd_line(client);
401a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	}
402a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
403a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	return !nr_clients;
404a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe}
405a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
406132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe/*
407132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * Send file contents to server backend. We could use sendfile(), but to remain
408132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * more portable lets just read/write the darn thing.
409132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe */
410a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboestatic int fio_client_send_ini(struct fio_client *client, const char *filename)
411132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
412132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct stat sb;
413132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	char *p, *buf;
414132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	off_t len;
415132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int fd, ret;
416132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
41746c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "send ini %s to %s\n", filename, client->hostname);
41846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
419132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fd = open(filename, O_RDONLY);
420132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fd < 0) {
421e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		log_err("fio: job file <%s> open: %s\n", filename, strerror(errno));
422132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
423132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
424132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
425132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fstat(fd, &sb) < 0) {
426132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: job file stat: %s\n", strerror(errno));
427b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
428132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
429132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
430132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
431132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	buf = malloc(sb.st_size);
432132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
433132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	len = sb.st_size;
434132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	p = buf;
435132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
436132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = read(fd, p, len);
437132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
438132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
439132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
440132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
441132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
442132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
443132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
444132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
445132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
446132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
447132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (1);
448132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
4490b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	if (len) {
4500b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		log_err("fio: failed reading job file %s\n", filename);
451b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
452c524ef72414f227ae4fcbfc95b832b3e6a95ae51Jens Axboe		free(buf);
4530b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		return 1;
4540b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	}
4550b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
456af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOB, buf, sb.st_size, 0);
457132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	free(buf);
458b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe	close(fd);
459132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
460132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
46137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
462a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboeint fio_clients_send_ini(const char *filename)
463a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe{
464a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	struct fio_client *client;
465a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	struct flist_head *entry, *tmp;
466a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
467a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	flist_for_each_safe(entry, tmp, &client_list) {
468a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe		client = flist_entry(entry, struct fio_client, list);
469a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
470a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe		if (fio_client_send_ini(client, filename))
471a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe			remove_client(client);
472a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	}
473a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
474a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	return !nr_clients;
475a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe}
476a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
477a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src)
478a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
479a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->max_val	= le64_to_cpu(src->max_val);
480a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->min_val	= le64_to_cpu(src->min_val);
481a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->samples	= le64_to_cpu(src->samples);
482802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
483802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	/*
484802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 * Floats arrive as IEEE 754 encoded uint64_t, convert back to double
485802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 */
486802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->mean.u.f	= fio_uint64_to_double(le64_to_cpu(dst->mean.u.i));
487802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->S.u.f	= fio_uint64_to_double(le64_to_cpu(dst->S.u.i));
488a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
489a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
490a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_ts(struct thread_stat *dst, struct thread_stat *src)
491a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
492a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i, j;
493a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
494a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->error	= le32_to_cpu(src->error);
495a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= le32_to_cpu(src->groupid);
496a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->pid	= le32_to_cpu(src->pid);
497a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->members	= le32_to_cpu(src->members);
498a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
499a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
500a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&dst->clat_stat[i], &src->clat_stat[i]);
501a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&dst->slat_stat[i], &src->slat_stat[i]);
502a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&dst->lat_stat[i], &src->lat_stat[i]);
503a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&dst->bw_stat[i], &src->bw_stat[i]);
504a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
505a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
506a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->usr_time		= le64_to_cpu(src->usr_time);
507a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->sys_time		= le64_to_cpu(src->sys_time);
508a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->ctx		= le64_to_cpu(src->ctx);
509a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->minf		= le64_to_cpu(src->minf);
510a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->majf		= le64_to_cpu(src->majf);
511a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->clat_percentiles	= le64_to_cpu(src->clat_percentiles);
512802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
513802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
514802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe		fio_fp64_t *fps = &src->percentile_list[i];
515802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe		fio_fp64_t *fpd = &dst->percentile_list[i];
516802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
517802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe		fpd->u.f = fio_uint64_to_double(le64_to_cpu(fps->u.i));
518802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	}
519a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
520a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
521a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_map[i]	= le32_to_cpu(src->io_u_map[i]);
522a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_submit[i]	= le32_to_cpu(src->io_u_submit[i]);
523a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_complete[i]	= le32_to_cpu(src->io_u_complete[i]);
524a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
525a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
526a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
527a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_lat_u[i]	= le32_to_cpu(src->io_u_lat_u[i]);
528a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_lat_m[i]	= le32_to_cpu(src->io_u_lat_m[i]);
529a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
530a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
531a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++)
532a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
533a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			dst->io_u_plat[i][j] = le32_to_cpu(src->io_u_plat[i][j]);
534a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
535a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 3; i++) {
536a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->total_io_u[i]	= le64_to_cpu(src->total_io_u[i]);
53793eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe		dst->short_io_u[i]	= le64_to_cpu(src->short_io_u[i]);
538a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
539a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
540a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->total_submit	= le64_to_cpu(src->total_submit);
541a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->total_complete	= le64_to_cpu(src->total_complete);
542a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
543a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
544a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_bytes[i]	= le64_to_cpu(src->io_bytes[i]);
545a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->runtime[i]		= le64_to_cpu(src->runtime[i]);
546a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
547a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
548a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->total_run_time	= le64_to_cpu(src->total_run_time);
549a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->continue_on_error	= le16_to_cpu(src->continue_on_error);
550a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->total_err_count	= le64_to_cpu(src->total_err_count);
551ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	dst->first_error	= le32_to_cpu(src->first_error);
552ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	dst->kb_base		= le32_to_cpu(src->kb_base);
553a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
554a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
555a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
556a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
557a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i;
558a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
559a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
560a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_run[i]		= le64_to_cpu(src->max_run[i]);
561a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_run[i]		= le64_to_cpu(src->min_run[i]);
562a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_bw[i]		= le64_to_cpu(src->max_bw[i]);
563a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_bw[i]		= le64_to_cpu(src->min_bw[i]);
564a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_kb[i]		= le64_to_cpu(src->io_kb[i]);
565a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->agg[i]		= le64_to_cpu(src->agg[i]);
566a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
567a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
568a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->kb_base	= le32_to_cpu(src->kb_base);
569a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= le32_to_cpu(src->groupid);
570a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
571a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
572a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void handle_ts(struct fio_net_cmd *cmd)
573a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
574a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct cmd_ts_pdu *p = (struct cmd_ts_pdu *) cmd->payload;
575a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
576a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_ts(&p->ts, &p->ts);
577a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&p->rs, &p->rs);
578a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
579a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	show_thread_status(&p->ts, &p->rs);
58037f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
58137f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	if (sum_stat_clients == 1)
58237f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe		return;
58337f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
58437f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	sum_thread_stats(&client_ts, &p->ts, sum_stat_nr);
58537f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	sum_group_stats(&client_gs, &p->rs);
58637f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
58737f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	client_ts.members++;
58837f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	client_ts.groupid = p->ts.groupid;
58937f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
59037f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	if (++sum_stat_nr == sum_stat_clients) {
59137f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe		strcpy(client_ts.name, "All clients");
59237f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe		show_thread_status(&client_ts, &client_gs);
59337f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	}
594a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
595a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
596a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void handle_gs(struct fio_net_cmd *cmd)
597a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
598a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct group_run_stats *gs = (struct group_run_stats *) cmd->payload;
599a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
600a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(gs, gs);
601a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	show_group_stats(gs);
602a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
603a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
60448fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboestatic void convert_jobs_eta(struct jobs_eta *je)
605cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe{
606cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	int i;
607cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
608cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->nr_running		= le32_to_cpu(je->nr_running);
609cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->nr_ramp		= le32_to_cpu(je->nr_ramp);
610cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->nr_pending		= le32_to_cpu(je->nr_pending);
611cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->files_open		= le32_to_cpu(je->files_open);
612cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->m_rate		= le32_to_cpu(je->m_rate);
613cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->t_rate		= le32_to_cpu(je->t_rate);
614cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->m_iops		= le32_to_cpu(je->m_iops);
615cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->t_iops		= le32_to_cpu(je->t_iops);
616cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
617cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	for (i = 0; i < 2; i++) {
618cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe		je->rate[i]	= le32_to_cpu(je->rate[i]);
619cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe		je->iops[i]	= le32_to_cpu(je->iops[i]);
620cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	}
621cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
622b51eedb75e3f1a9db33fa488ff7d9cc0a956b8eeJens Axboe	je->elapsed_sec		= le64_to_cpu(je->elapsed_sec);
623cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->eta_sec		= le64_to_cpu(je->eta_sec);
62448fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe}
62548fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
626af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic void sum_jobs_eta(struct jobs_eta *dst, struct jobs_eta *je)
62748fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe{
62848fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	int i;
62948fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
63048fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->nr_running		+= je->nr_running;
63148fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->nr_ramp		+= je->nr_ramp;
63248fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->nr_pending		+= je->nr_pending;
63348fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->files_open		+= je->files_open;
63448fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->m_rate		+= je->m_rate;
63548fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->t_rate		+= je->t_rate;
63648fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->m_iops		+= je->m_iops;
63748fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->t_iops		+= je->t_iops;
63848fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
63948fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	for (i = 0; i < 2; i++) {
64048fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe		dst->rate[i]	+= je->rate[i];
64148fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe		dst->iops[i]	+= je->iops[i];
64248fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	}
64348fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
64448fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->elapsed_sec	+= je->elapsed_sec;
64548fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
64648fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	if (je->eta_sec > dst->eta_sec)
64748fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe		dst->eta_sec = je->eta_sec;
64848fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe}
64948fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
65082c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboestatic void dec_jobs_eta(struct client_eta *eta)
65182c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe{
65282c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	if (!--eta->pending) {
65382c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		display_thread_status(&eta->eta);
65482c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		free(eta);
65582c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	}
65682c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe}
65782c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
65889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic void remove_reply_cmd(struct fio_client *client, struct fio_net_cmd *cmd)
65989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
66089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct fio_net_int_cmd *icmd = NULL;
66189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct flist_head *entry;
66289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
66389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_for_each(entry, &client->cmd_list) {
66489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		icmd = flist_entry(entry, struct fio_net_int_cmd, list);
66589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
66689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		if (cmd->tag == (uint64_t) icmd)
66789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			break;
66889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
66989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		icmd = NULL;
67089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
67189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
67289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (!icmd) {
67389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		log_err("fio: client: unable to find matching tag\n");
67489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return;
67589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
67689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
67789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_del(&icmd->list);
67889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	cmd->tag = icmd->saved_tag;
67989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	free(icmd);
68089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
68189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
68282c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboestatic void handle_eta(struct fio_client *client, struct fio_net_cmd *cmd)
68348fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe{
68448fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	struct jobs_eta *je = (struct jobs_eta *) cmd->payload;
685af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct client_eta *eta = (struct client_eta *) cmd->tag;
686af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
687af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "client: got eta tag %p, %d\n", eta, eta->pending);
688cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
689f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe	assert(client->eta_in_flight == eta);
690f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe
691f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe	client->eta_in_flight = NULL;
69282c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	flist_del_init(&client->eta_list);
69382c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
69448fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	convert_jobs_eta(je);
695af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	sum_jobs_eta(&eta->eta, je);
69682c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	dec_jobs_eta(eta);
697cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe}
698cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
699b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboestatic void handle_probe(struct fio_client *client, struct fio_net_cmd *cmd)
7002e03b4b2a072b79946b0ee651dff38273868473aJens Axboe{
7012e03b4b2a072b79946b0ee651dff38273868473aJens Axboe	struct cmd_probe_pdu *probe = (struct cmd_probe_pdu *) cmd->payload;
702cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	const char *os, *arch;
7032e03b4b2a072b79946b0ee651dff38273868473aJens Axboe
704cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	os = fio_get_os_string(probe->os);
705cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	if (!os)
706cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe		os = "unknown";
707cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe
708cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	arch = fio_get_arch_string(probe->arch);
709cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	if (!arch)
710cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe		os = "unknown";
711cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe
712c71233ee4aa050efc8a099df1482238b12f826efJens Axboe	log_info("hostname=%s, be=%u, os=%s, arch=%s, fio=%u.%u.%u\n",
713cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe		probe->hostname, probe->bigendian, os, arch, probe->fio_major,
7146eb2479194603184f393057ea10326643edc7169Jens Axboe		probe->fio_minor, probe->fio_patch);
715b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe
716b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe	if (!client->name)
717b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe		client->name = strdup((char *) probe->hostname);
7182e03b4b2a072b79946b0ee651dff38273868473aJens Axboe}
7192e03b4b2a072b79946b0ee651dff38273868473aJens Axboe
720e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestatic int handle_client(struct fio_client *client)
72137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
72237db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	struct fio_net_cmd *cmd;
72337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
72460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "client: handle %s\n", client->hostname);
72560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
726e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	cmd = fio_net_recv_cmd(client->fd);
727e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	if (!cmd)
728e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		return 0;
729c2c9458515bda1f77e25f95122ef6ec8d8cc3ec7Jens Axboe
73089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "client: got cmd op %s from %s\n",
73189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe				fio_server_op(cmd->opcode), client->hostname);
73246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
733e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	switch (cmd->opcode) {
734e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_QUIT:
735e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		remove_client(client);
736e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
737e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
738e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_TEXT: {
739e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		const char *buf = (const char *) cmd->payload;
740b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe		const char *name;
741e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		int fio_unused ret;
742e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
743b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe		name = client->name ? client->name : client->hostname;
744b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe
745e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		if (!client->skip_newline)
746b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe			fprintf(f_out, "<%s> ", name);
747e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		ret = fwrite(buf, cmd->pdu_len, 1, f_out);
748e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		fflush(f_out);
749e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		client->skip_newline = strchr(buf, '\n') == NULL;
750e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
751e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
75237db14feece08eb6e43de87c404180650ed5aa6fJens Axboe		}
753e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_TS:
754e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		handle_ts(cmd);
755e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
756e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
757e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_GS:
758e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		handle_gs(cmd);
759e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
760e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
761e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_ETA:
76289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		remove_reply_cmd(client, cmd);
76382c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		handle_eta(client, cmd);
764e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
765e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
766e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_PROBE:
76789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		remove_reply_cmd(client, cmd);
768b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe		handle_probe(client, cmd);
769e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
770e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
771e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_START:
772e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		client->state = Client_started;
773e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
774e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
775e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_STOP:
776e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		client->state = Client_stopped;
777e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
778e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
779e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	default:
78089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		log_err("fio: unknown client op: %s\n", fio_server_op(cmd->opcode));
781e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
782e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
78337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	}
78437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
785e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	return 1;
78637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe}
787b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
788af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic void request_client_etas(void)
789af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{
790af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct fio_client *client;
791af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct flist_head *entry;
792af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct client_eta *eta;
79382c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	int skipped = 0;
794af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
795af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "client: request eta (%d)\n", nr_clients);
796af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
797af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	eta = malloc(sizeof(*eta));
798af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	memset(&eta->eta, 0, sizeof(eta->eta));
799af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	eta->pending = nr_clients;
800af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
801af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	flist_for_each(entry, &client_list) {
802af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		client = flist_entry(entry, struct fio_client, list);
803af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
80482c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		if (!flist_empty(&client->eta_list)) {
80582c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe			skipped++;
80682c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe			continue;
80782c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		}
80882c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
809f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe		assert(!client->eta_in_flight);
81082c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		flist_add_tail(&client->eta_list, &eta_list);
811f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe		client->eta_in_flight = eta;
812af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_SEND_ETA,
81389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe					(uint64_t) eta, &client->cmd_list);
814af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
815af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
81682c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	while (skipped--)
81782c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		dec_jobs_eta(eta);
81882c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
819af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "client: requested eta tag %p\n", eta);
820af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe}
821af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
82289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int client_check_cmd_timeout(struct fio_client *client,
82389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe				    struct timeval *now)
82489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
82589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct fio_net_int_cmd *cmd;
82689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct flist_head *entry, *tmp;
82789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret = 0;
82889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
82989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_for_each_safe(entry, tmp, &client->cmd_list) {
83089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		cmd = flist_entry(entry, struct fio_net_int_cmd, list);
83189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
83289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		if (mtime_since(&cmd->tv, now) < FIO_NET_CLIENT_TIMEOUT)
83389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			continue;
83489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
83589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		log_err("fio: client %s, timeout on cmd %s\n", client->hostname,
83689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe						fio_server_op(cmd->cmd.opcode));
83789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		flist_del(&cmd->list);
83889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		free(cmd);
83989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		ret = 1;
84089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
84189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
84289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return flist_empty(&client->cmd_list) && ret;
84389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
84489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
84589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int fio_client_timed_out(void)
84689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
84789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct fio_client *client;
84889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct flist_head *entry, *tmp;
84989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct timeval tv;
85089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret = 0;
85189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
85289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	gettimeofday(&tv, NULL);
85389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
85489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_for_each_safe(entry, tmp, &client_list) {
85589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		client = flist_entry(entry, struct fio_client, list);
85689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
85789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		if (flist_empty(&client->cmd_list))
85889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			continue;
85989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
86089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		if (!client_check_cmd_timeout(client, &tv))
86189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			continue;
86289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
86389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		log_err("fio: client %s timed out\n", client->hostname);
86489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		remove_client(client);
86589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		ret = 1;
86689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
86789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
86889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return ret;
86989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
87089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
871b66570dce15587a37a64685f8ab72c3018771b2bJens Axboeint fio_handle_clients(void)
872b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe{
873b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct fio_client *client;
874b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct flist_head *entry;
875b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct pollfd *pfds;
87682a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe	int i, ret = 0;
877b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
878af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	gettimeofday(&eta_tv, NULL);
879af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
880b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	pfds = malloc(nr_clients * sizeof(struct pollfd));
881b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
88237f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	sum_stat_clients = nr_clients;
88337f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	init_thread_stat(&client_ts);
88437f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	init_group_run_stat(&client_gs);
88537f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
88682a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe	while (!exit_backend && nr_clients) {
88782a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe		i = 0;
88882a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe		flist_for_each(entry, &client_list) {
88982a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe			client = flist_entry(entry, struct fio_client, list);
890b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
89182a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe			pfds[i].fd = client->fd;
89282a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe			pfds[i].events = POLLIN;
89382a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe			i++;
89482a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe		}
89582a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe
89682a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe		assert(i == nr_clients);
897b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
8985c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe		do {
899af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe			struct timeval tv;
900af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
901af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe			gettimeofday(&tv, NULL);
902af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe			if (mtime_since(&eta_tv, &tv) >= 900) {
903af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe				request_client_etas();
904af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe				memcpy(&eta_tv, &tv, sizeof(tv));
90589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
90689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe				if (fio_client_timed_out())
90789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe					break;
908af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe			}
909af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
9105c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe			ret = poll(pfds, nr_clients, 100);
9115c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe			if (ret < 0) {
9125c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe				if (errno == EINTR)
9135c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe					continue;
9145c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe				log_err("fio: poll clients: %s\n", strerror(errno));
9155c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe				break;
9165c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe			} else if (!ret)
917b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe				continue;
9185c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe		} while (ret <= 0);
919b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
920b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe		for (i = 0; i < nr_clients; i++) {
921b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			if (!(pfds[i].revents & POLLIN))
922b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe				continue;
923b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
924b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			client = find_client_by_fd(pfds[i].fd);
925b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			if (!client) {
9263c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe				log_err("fio: unknown client fd %d\n", pfds[i].fd);
927b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe				continue;
928b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			}
929e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (!handle_client(client)) {
93028d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe				log_info("client: host=%s disconnected\n",
93128d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe						client->hostname);
93228d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe				remove_client(client);
93328d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe			}
934b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe		}
935b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	}
936b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
937b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	free(pfds);
938b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	return 0;
939b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe}
940