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>
173989b14303458519192f4ace8caf091d587f5e6eJens Axboe#ifdef CONFIG_ZLIB
181b42725f06f8906b9b99381da3490484f59df28aJens Axboe#include <zlib.h>
193989b14303458519192f4ace8caf091d587f5e6eJens Axboe#endif
20132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
21132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "fio.h"
22dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameron#include "client.h"
23132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h"
24b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe#include "flist.h"
253c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#include "hash.h"
26132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
27dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameronstatic void handle_du(struct fio_client *client, struct fio_net_cmd *cmd);
2889e5fad91bc33f1687cca6b1bf5aa3084c424650Jens Axboestatic void handle_ts(struct fio_client *client, struct fio_net_cmd *cmd);
2989e5fad91bc33f1687cca6b1bf5aa3084c424650Jens Axboestatic void handle_gs(struct fio_client *client, struct fio_net_cmd *cmd);
30dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameronstatic void handle_probe(struct fio_client *client, struct fio_net_cmd *cmd);
31084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboestatic void handle_text(struct fio_client *client, struct fio_net_cmd *cmd);
326b79c80c14766df7b0507c4ec679507a315ad61aJens Axboestatic void handle_stop(struct fio_client *client, struct fio_net_cmd *cmd);
3385dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboestatic void handle_start(struct fio_client *client, struct fio_net_cmd *cmd);
34dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameron
35dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameronstruct client_ops fio_client_ops = {
3635c0ba7ff55bbd438cdc171945c61d501a4e693eJens Axboe	.text		= handle_text,
370420ba6a85617cb02e196ac92e519191dafc6c52Jens Axboe	.disk_util	= handle_du,
380420ba6a85617cb02e196ac92e519191dafc6c52Jens Axboe	.thread_status	= handle_ts,
390420ba6a85617cb02e196ac92e519191dafc6c52Jens Axboe	.group_stats	= handle_gs,
406b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe	.stop		= handle_stop,
4185dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboe	.start		= handle_start,
42a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe	.eta		= display_thread_status,
430420ba6a85617cb02e196ac92e519191dafc6c52Jens Axboe	.probe		= handle_probe,
446433ee054a5dc6533066e105baee4ff85197d392Jens Axboe	.eta_msec	= FIO_CLIENT_DEF_ETA_MSEC,
4546bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	.client_type	= FIO_CLIENT_TYPE_CLI,
46dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameron};
47dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameron
48af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic struct timeval eta_tv;
4948fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
50b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestatic FLIST_HEAD(client_list);
5182c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboestatic FLIST_HEAD(eta_list);
52b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
533f3a4542887ba038231144be08b2c36d7cc83424Jens Axboestatic FLIST_HEAD(arg_list);
543f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe
553650a3ca2ccbfefe7564d6ebde03bf7f89255e89Jens Axboestruct thread_stat client_ts;
563650a3ca2ccbfefe7564d6ebde03bf7f89255e89Jens Axboestruct group_run_stats client_gs;
573650a3ca2ccbfefe7564d6ebde03bf7f89255e89Jens Axboeint sum_stat_clients;
583650a3ca2ccbfefe7564d6ebde03bf7f89255e89Jens Axboe
5937f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboestatic int sum_stat_nr;
60952b05e00103bf45576e1860cde0626bd42ed52aCastor Fustatic struct json_object *root = NULL;
61952b05e00103bf45576e1860cde0626bd42ed52aCastor Fustatic struct json_array *clients_array = NULL;
62952b05e00103bf45576e1860cde0626bd42ed52aCastor Fustatic struct json_array *du_array = NULL;
63108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboestatic int do_output_all_clients;
6437f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
653c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#define FIO_CLIENT_HASH_BITS	7
663c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#define FIO_CLIENT_HASH_SZ	(1 << FIO_CLIENT_HASH_BITS)
673c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe#define FIO_CLIENT_HASH_MASK	(FIO_CLIENT_HASH_SZ - 1)
68bebe639808147d587bbe776566d390b9ff98773fJens Axboestatic struct flist_head client_hash[FIO_CLIENT_HASH_SZ];
693c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
70bebe639808147d587bbe776566d390b9ff98773fJens Axboestatic void fio_client_add_hash(struct fio_client *client)
713c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe{
723c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	int bucket = hash_long(client->fd, FIO_CLIENT_HASH_BITS);
733c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
743c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	bucket &= FIO_CLIENT_HASH_MASK;
75bebe639808147d587bbe776566d390b9ff98773fJens Axboe	flist_add(&client->hash_list, &client_hash[bucket]);
763c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe}
773c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
78bebe639808147d587bbe776566d390b9ff98773fJens Axboestatic void fio_client_remove_hash(struct fio_client *client)
793c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe{
80bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!flist_empty(&client->hash_list))
81bebe639808147d587bbe776566d390b9ff98773fJens Axboe		flist_del_init(&client->hash_list);
823c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe}
833c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
843c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboestatic void fio_init fio_client_hash_init(void)
853c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe{
863c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	int i;
873c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
88bebe639808147d587bbe776566d390b9ff98773fJens Axboe	for (i = 0; i < FIO_CLIENT_HASH_SZ; i++)
89bebe639808147d587bbe776566d390b9ff98773fJens Axboe		INIT_FLIST_HEAD(&client_hash[i]);
903c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe}
913c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
92952b05e00103bf45576e1860cde0626bd42ed52aCastor Fustatic void fio_client_json_init(void)
93952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu{
94952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	if (output_format != FIO_OUTPUT_JSON)
95952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		return;
96952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	root = json_create_object();
97952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	json_object_add_value_string(root, "fio version", fio_version_string);
98952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	clients_array = json_create_array();
99952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	json_object_add_value_array(root, "client_stats", clients_array);
100952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	du_array = json_create_array();
101952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	json_object_add_value_array(root, "disk_util", du_array);
102952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu}
103952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu
104952b05e00103bf45576e1860cde0626bd42ed52aCastor Fustatic void fio_client_json_fini(void)
105952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu{
106952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	if (output_format != FIO_OUTPUT_JSON)
107952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		return;
108952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	json_print_object(root);
109952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	log_info("\n");
110952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	json_free_object(root);
111952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	root = NULL;
112952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	clients_array = NULL;
113952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	du_array = NULL;
114952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu}
115952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu
116b66570dce15587a37a64685f8ab72c3018771b2bJens Axboestatic struct fio_client *find_client_by_fd(int fd)
117b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe{
1183c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	int bucket = hash_long(fd, FIO_CLIENT_HASH_BITS) & FIO_CLIENT_HASH_MASK;
119b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct fio_client *client;
120b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct flist_head *entry;
121b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
122bebe639808147d587bbe776566d390b9ff98773fJens Axboe	flist_for_each(entry, &client_hash[bucket]) {
123bebe639808147d587bbe776566d390b9ff98773fJens Axboe		client = flist_entry(entry, struct fio_client, hash_list);
124b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
125e55f8f307385e77ea561e7bbf9c76842ead9d7a3Jens Axboe		if (client->fd == fd) {
126e55f8f307385e77ea561e7bbf9c76842ead9d7a3Jens Axboe			client->refs++;
127b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			return client;
128e55f8f307385e77ea561e7bbf9c76842ead9d7a3Jens Axboe		}
129b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	}
130b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
131b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	return NULL;
132b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe}
133b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
1343af452010d32267d085ba1612ebc0a40812c28a9Jens Axboevoid fio_put_client(struct fio_client *client)
135b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe{
1365121a9aa0299a2c23b3c50bf110ab4a05677c740Jens Axboe	if (--client->refs)
1375121a9aa0299a2c23b3c50bf110ab4a05677c740Jens Axboe		return;
1385121a9aa0299a2c23b3c50bf110ab4a05677c740Jens Axboe
1393af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe	free(client->hostname);
1403af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe	if (client->argv)
1413af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe		free(client->argv);
1423af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe	if (client->name)
1433af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe		free(client->name);
14414ea90edf265aae2b82f25418fde179c452909f9Jens Axboe	while (client->nr_ini_file)
14514ea90edf265aae2b82f25418fde179c452909f9Jens Axboe		free(client->ini_file[--client->nr_ini_file]);
14614ea90edf265aae2b82f25418fde179c452909f9Jens Axboe	if (client->ini_file)
14714ea90edf265aae2b82f25418fde179c452909f9Jens Axboe		free(client->ini_file);
1483af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe
149108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe	if (!client->did_stat)
150108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe		sum_stat_clients -= client->nr_stat;
151108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe
1523af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe	free(client);
1533af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe}
1543af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe
1553af452010d32267d085ba1612ebc0a40812c28a9Jens Axboestatic void remove_client(struct fio_client *client)
1563af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe{
1573af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe	assert(client->refs);
1583af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe
15939e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	dprint(FD_NET, "client: removed <%s>\n", client->hostname);
1603af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe
1613af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe	if (!flist_empty(&client->list))
1623af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe		flist_del_init(&client->list);
1633c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
164bebe639808147d587bbe776566d390b9ff98773fJens Axboe	fio_client_remove_hash(client);
16581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
16682c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	if (!flist_empty(&client->eta_list)) {
16782c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		flist_del_init(&client->eta_list);
168a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe		fio_client_dec_jobs_eta(client->eta_in_flight, client->ops->eta);
16982c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	}
170af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
1711e0c184e7cf03c8126e6e8dff4c45584283e6b9bJens Axboe	close(client->fd);
1721e0c184e7cf03c8126e6e8dff4c45584283e6b9bJens Axboe	client->fd = -1;
1731e0c184e7cf03c8126e6e8dff4c45584283e6b9bJens Axboe
1740cf3ece062d6856bd79b89770780296c99937a98Jens Axboe	if (client->ops->removed)
1750cf3ece062d6856bd79b89770780296c99937a98Jens Axboe		client->ops->removed(client);
1760cf3ece062d6856bd79b89770780296c99937a98Jens Axboe
1773c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	nr_clients--;
1783af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe	fio_put_client(client);
1795121a9aa0299a2c23b3c50bf110ab4a05677c740Jens Axboe}
1805121a9aa0299a2c23b3c50bf110ab4a05677c740Jens Axboe
181343cb4a98200757bdcb0c5203e9120bb777625a8Jens Axboestruct fio_client *fio_get_client(struct fio_client *client)
182343cb4a98200757bdcb0c5203e9120bb777625a8Jens Axboe{
183343cb4a98200757bdcb0c5203e9120bb777625a8Jens Axboe	client->refs++;
184343cb4a98200757bdcb0c5203e9120bb777625a8Jens Axboe	return client;
185343cb4a98200757bdcb0c5203e9120bb777625a8Jens Axboe}
186343cb4a98200757bdcb0c5203e9120bb777625a8Jens Axboe
187fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboestatic void __fio_client_add_cmd_option(struct fio_client *client,
188fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe					const char *opt)
18981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
19039e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	int index;
19139e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe
19239e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	index = client->argc++;
19381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	client->argv = realloc(client->argv, sizeof(char *) * client->argc);
19439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	client->argv[index] = strdup(opt);
19539e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	dprint(FD_NET, "client: add cmd %d: %s\n", index, opt);
19681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
19781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
198fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboevoid fio_client_add_cmd_option(void *cookie, const char *opt)
19981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
200bebe639808147d587bbe776566d390b9ff98773fJens Axboe	struct fio_client *client = cookie;
2013f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	struct flist_head *entry;
20281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
203bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!client || !opt)
204fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		return;
20581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
206fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	__fio_client_add_cmd_option(client, opt);
2073f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe
2083f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	/*
2093f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	 * Duplicate arguments to shared client group
2103f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	 */
2113f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	flist_for_each(entry, &arg_list) {
2123f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		client = flist_entry(entry, struct fio_client, arg_list);
2133f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe
2143f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		__fio_client_add_cmd_option(client, opt);
2153f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	}
21681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
21781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
218a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboestruct fio_client *fio_client_add_explicit(struct client_ops *ops,
219a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe					   const char *hostname, int type,
2203ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe					   int port)
2213ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe{
2223ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	struct fio_client *client;
2233ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
2243ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	client = malloc(sizeof(*client));
2253ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	memset(client, 0, sizeof(*client));
2263ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
2273ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	INIT_FLIST_HEAD(&client->list);
2283ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	INIT_FLIST_HEAD(&client->hash_list);
2293ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	INIT_FLIST_HEAD(&client->arg_list);
2303ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	INIT_FLIST_HEAD(&client->eta_list);
2313ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	INIT_FLIST_HEAD(&client->cmd_list);
2323ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
2333ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	client->hostname = strdup(hostname);
2343ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
2353ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	if (type == Fio_client_socket)
2363ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		client->is_sock = 1;
2373ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	else {
2383ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		int ipv6;
2393ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
2403ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ipv6 = type == Fio_client_ipv6;
2413aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboe		if (fio_server_parse_host(hostname, ipv6,
2423ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe						&client->addr.sin_addr,
2433ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe						&client->addr6.sin6_addr))
2443ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			goto err;
2453ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
2463ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		client->port = port;
2473ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	}
2483ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
2493ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	client->fd = -1;
250a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe	client->ops = ops;
2515121a9aa0299a2c23b3c50bf110ab4a05677c740Jens Axboe	client->refs = 1;
25246bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	client->type = ops->client_type;
2533ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
2543ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	__fio_client_add_cmd_option(client, "fio");
2553ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
2563ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	flist_add(&client->list, &client_list);
2573ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	nr_clients++;
2583ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	dprint(FD_NET, "client: added <%s>\n", client->hostname);
2593ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	return client;
2603ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboeerr:
2613ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	free(client);
2623ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	return NULL;
2633ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe}
2643ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
26514ea90edf265aae2b82f25418fde179c452909f9Jens Axboevoid fio_client_add_ini_file(void *cookie, const char *ini_file)
26614ea90edf265aae2b82f25418fde179c452909f9Jens Axboe{
26714ea90edf265aae2b82f25418fde179c452909f9Jens Axboe	struct fio_client *client = cookie;
26814ea90edf265aae2b82f25418fde179c452909f9Jens Axboe	size_t new_size;
26914ea90edf265aae2b82f25418fde179c452909f9Jens Axboe
27014ea90edf265aae2b82f25418fde179c452909f9Jens Axboe	dprint(FD_NET, "client <%s>: add ini %s\n", client->hostname, ini_file);
27114ea90edf265aae2b82f25418fde179c452909f9Jens Axboe
27214ea90edf265aae2b82f25418fde179c452909f9Jens Axboe	new_size = (client->nr_ini_file + 1) * sizeof(char *);
27314ea90edf265aae2b82f25418fde179c452909f9Jens Axboe	client->ini_file = realloc(client->ini_file, new_size);
27414ea90edf265aae2b82f25418fde179c452909f9Jens Axboe	client->ini_file[client->nr_ini_file] = strdup(ini_file);
27514ea90edf265aae2b82f25418fde179c452909f9Jens Axboe	client->nr_ini_file++;
27614ea90edf265aae2b82f25418fde179c452909f9Jens Axboe}
27714ea90edf265aae2b82f25418fde179c452909f9Jens Axboe
278a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboeint fio_client_add(struct client_ops *ops, const char *hostname, void **cookie)
279132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
2803f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	struct fio_client *existing = *cookie;
281b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct fio_client *client;
282132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
2833f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	if (existing) {
2843f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		/*
2853f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		 * We always add our "exec" name as the option, hence 1
2863f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		 * means empty.
2873f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		 */
2883f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		if (existing->argc == 1)
2893f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe			flist_add_tail(&existing->arg_list, &arg_list);
2903f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		else {
2913f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe			while (!flist_empty(&arg_list))
2923f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe				flist_del_init(arg_list.next);
2933f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe		}
2943f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	}
2953f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe
296b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	client = malloc(sizeof(*client));
297a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	memset(client, 0, sizeof(*client));
29881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
2993c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe	INIT_FLIST_HEAD(&client->list);
300bebe639808147d587bbe776566d390b9ff98773fJens Axboe	INIT_FLIST_HEAD(&client->hash_list);
3013f3a4542887ba038231144be08b2c36d7cc83424Jens Axboe	INIT_FLIST_HEAD(&client->arg_list);
30282c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	INIT_FLIST_HEAD(&client->eta_list);
30389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	INIT_FLIST_HEAD(&client->cmd_list);
3043c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
305bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (fio_server_parse_string(hostname, &client->hostname,
306bebe639808147d587bbe776566d390b9ff98773fJens Axboe					&client->is_sock, &client->port,
307811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&client->addr.sin_addr,
308811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&client->addr6.sin6_addr,
309811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&client->ipv6))
310bebe639808147d587bbe776566d390b9ff98773fJens Axboe		return -1;
31187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
312bebe639808147d587bbe776566d390b9ff98773fJens Axboe	client->fd = -1;
313a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe	client->ops = ops;
3145121a9aa0299a2c23b3c50bf110ab4a05677c740Jens Axboe	client->refs = 1;
31546bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	client->type = ops->client_type;
3163c5f57e36712decffa103c8a655b9a693c6d3d13Jens Axboe
31781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	__fio_client_add_cmd_option(client, "fio");
31881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
319a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	flist_add(&client->list, &client_list);
320a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	nr_clients++;
321bebe639808147d587bbe776566d390b9ff98773fJens Axboe	dprint(FD_NET, "client: added <%s>\n", client->hostname);
322bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*cookie = client;
323bebe639808147d587bbe776566d390b9ff98773fJens Axboe	return 0;
324a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe}
325a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
326d824c3b8b5847e8de80511f3aafda939a3f61bb8Jens Axboestatic void probe_client(struct fio_client *client)
327d824c3b8b5847e8de80511f3aafda939a3f61bb8Jens Axboe{
3283989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_client_probe_pdu pdu;
3293989b14303458519192f4ace8caf091d587f5e6eJens Axboe	uint64_t tag;
3303989b14303458519192f4ace8caf091d587f5e6eJens Axboe
331d824c3b8b5847e8de80511f3aafda939a3f61bb8Jens Axboe	dprint(FD_NET, "client: send probe\n");
332d824c3b8b5847e8de80511f3aafda939a3f61bb8Jens Axboe
3333989b14303458519192f4ace8caf091d587f5e6eJens Axboe#ifdef CONFIG_ZLIB
3343989b14303458519192f4ace8caf091d587f5e6eJens Axboe	pdu.flags = __le64_to_cpu(FIO_PROBE_FLAG_ZLIB);
3353989b14303458519192f4ace8caf091d587f5e6eJens Axboe#else
3363989b14303458519192f4ace8caf091d587f5e6eJens Axboe	pdu.flags = 0;
3373989b14303458519192f4ace8caf091d587f5e6eJens Axboe#endif
3383989b14303458519192f4ace8caf091d587f5e6eJens Axboe
3393989b14303458519192f4ace8caf091d587f5e6eJens Axboe	fio_net_send_cmd(client->fd, FIO_NET_CMD_PROBE, &pdu, sizeof(pdu), &tag, &client->cmd_list);
340d824c3b8b5847e8de80511f3aafda939a3f61bb8Jens Axboe}
341d824c3b8b5847e8de80511f3aafda939a3f61bb8Jens Axboe
34287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_client_connect_ip(struct fio_client *client)
343a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe{
344811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	struct sockaddr *addr;
34567bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	socklen_t socklen;
346811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	int fd, domain;
347811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
348811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (client->ipv6) {
349811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		client->addr6.sin6_family = AF_INET6;
350811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		client->addr6.sin6_port = htons(client->port);
351811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		domain = AF_INET6;
352811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &client->addr6;
353811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(client->addr6);
354811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else {
355811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		client->addr.sin_family = AF_INET;
356811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		client->addr.sin_port = htons(client->port);
357811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		domain = AF_INET;
358811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &client->addr;
359811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(client->addr);
360811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	}
361132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
362811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	fd = socket(domain, SOCK_STREAM, 0);
363132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fd < 0) {
36425095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		int ret = -errno;
36525095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe
366132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
36725095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		return ret;
368132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
369132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
370811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (connect(fd, addr, socklen) < 0) {
37125095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		int ret = -errno;
37225095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe
373132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: connect: %s\n", strerror(errno));
374a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe		log_err("fio: failed to connect to %s:%u\n", client->hostname,
375a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe								client->port);
376b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
37725095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		return ret;
37887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
37987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
38087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return fd;
38187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
38287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
38387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_client_connect_sock(struct fio_client *client)
38487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
38587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un *addr = &client->addr_un;
38667bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	socklen_t len;
38787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int fd;
38887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
38987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	memset(addr, 0, sizeof(*addr));
39087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	addr->sun_family = AF_UNIX;
3911cb964148482b2d50b1f82966f96545ebeec6428Jens Axboe	strncpy(addr->sun_path, client->hostname, sizeof(addr->sun_path) - 1);
39287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
39387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fd = socket(AF_UNIX, SOCK_STREAM, 0);
39487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fd < 0) {
39525095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		int ret = -errno;
39625095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe
39787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: socket: %s\n", strerror(errno));
39825095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		return ret;
39987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
40087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
40187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1;
40287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (connect(fd, (struct sockaddr *) addr, len) < 0) {
40325095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		int ret = -errno;
40425095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe
40587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: connect; %s\n", strerror(errno));
406b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
40725095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		return ret;
408132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
409132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
41087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return fd;
41187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
41287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
4132f99deb0895b2d0b618e6e72c74add7192b4d73fJens Axboeint fio_client_connect(struct fio_client *client)
41487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
41587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int fd;
41687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
41787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "client: connect to host %s\n", client->hostname);
41887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
41987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (client->is_sock)
42087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fd = fio_client_connect_sock(client);
42187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	else
42287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fd = fio_client_connect_ip(client);
42387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
42489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "client: %s connected %d\n", client->hostname, fd);
42589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
42687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fd < 0)
427a1a3ed5143e7fe153d114f9ff96bfbc5dc14a156Jens Axboe		return fd;
42887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
429b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	client->fd = fd;
430bebe639808147d587bbe776566d390b9ff98773fJens Axboe	fio_client_add_hash(client);
43181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	client->state = Client_connected;
432d824c3b8b5847e8de80511f3aafda939a3f61bb8Jens Axboe
433d824c3b8b5847e8de80511f3aafda939a3f61bb8Jens Axboe	probe_client(client);
434132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
435132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
436132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
4370cf3ece062d6856bd79b89770780296c99937a98Jens Axboeint fio_client_terminate(struct fio_client *client)
4382f99deb0895b2d0b618e6e72c74add7192b4d73fJens Axboe{
4390cf3ece062d6856bd79b89770780296c99937a98Jens Axboe	return fio_net_send_quit(client->fd);
4402f99deb0895b2d0b618e6e72c74add7192b4d73fJens Axboe}
4412f99deb0895b2d0b618e6e72c74add7192b4d73fJens Axboe
442cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_clients_terminate(void)
443cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{
444cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	struct flist_head *entry;
445cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	struct fio_client *client;
446cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
44760efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "client: terminate clients\n");
44860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
449cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	flist_for_each(entry, &client_list) {
450cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe		client = flist_entry(entry, struct fio_client, list);
4512f99deb0895b2d0b618e6e72c74add7192b4d73fJens Axboe		fio_client_terminate(client);
452cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	}
453cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
454cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
455cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboestatic void sig_int(int sig)
456cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{
457bebe639808147d587bbe776566d390b9ff98773fJens Axboe	dprint(FD_NET, "client: got signal %d\n", sig);
458cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	fio_clients_terminate();
459cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
460cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
461b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboestatic void sig_show_status(int sig)
462b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboe{
463b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboe	show_running_run_stats();
464b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboe}
465b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboe
466cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboestatic void client_signal_handler(void)
467cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{
468cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	struct sigaction act;
469cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
470cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	memset(&act, 0, sizeof(act));
471cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	act.sa_handler = sig_int;
472cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	act.sa_flags = SA_RESTART;
473cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	sigaction(SIGINT, &act, NULL);
474cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
475cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	memset(&act, 0, sizeof(act));
476cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	act.sa_handler = sig_int;
477cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	act.sa_flags = SA_RESTART;
478cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	sigaction(SIGTERM, &act, NULL);
479b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboe
4802f694507513e44e59139f57f28e08c5d0772880eBruce Cran/* Windows uses SIGBREAK as a quit signal from other applications */
4812f694507513e44e59139f57f28e08c5d0772880eBruce Cran#ifdef WIN32
4822f694507513e44e59139f57f28e08c5d0772880eBruce Cran	memset(&act, 0, sizeof(act));
4832f694507513e44e59139f57f28e08c5d0772880eBruce Cran	act.sa_handler = sig_int;
4842f694507513e44e59139f57f28e08c5d0772880eBruce Cran	act.sa_flags = SA_RESTART;
4852f694507513e44e59139f57f28e08c5d0772880eBruce Cran	sigaction(SIGBREAK, &act, NULL);
4862f694507513e44e59139f57f28e08c5d0772880eBruce Cran#endif
4872f694507513e44e59139f57f28e08c5d0772880eBruce Cran
488b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboe	memset(&act, 0, sizeof(act));
489b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboe	act.sa_handler = sig_show_status;
490b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboe	act.sa_flags = SA_RESTART;
491b852e7cf097cec1c7fb92305f9c3c6b394bb39adJens Axboe	sigaction(SIGUSR1, &act, NULL);
492cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
493cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
49481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int send_client_cmd_line(struct fio_client *client)
49581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
496fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_single_line_pdu *cslp;
497fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_line_pdu *clp;
498fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	unsigned long offset;
4997f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	unsigned int *lens;
500fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	void *pdu;
501fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	size_t mem;
50281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	int i, ret;
50381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
50439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	dprint(FD_NET, "client: send cmdline %d\n", client->argc);
50560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
5067f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	lens = malloc(client->argc * sizeof(unsigned int));
5077f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
508fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	/*
509fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	 * Find out how much mem we need
510fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	 */
5117f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	for (i = 0, mem = 0; i < client->argc; i++) {
5127f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		lens[i] = strlen(client->argv[i]) + 1;
5137f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		mem += lens[i];
5147f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	}
515fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
516fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	/*
517fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	 * We need one cmd_line_pdu, and argc number of cmd_single_line_pdu
518fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	 */
519fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	mem += sizeof(*clp) + (client->argc * sizeof(*cslp));
520fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
521fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	pdu = malloc(mem);
522fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp = pdu;
523fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	offset = sizeof(*clp);
524fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
525fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	for (i = 0; i < client->argc; i++) {
5267f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		uint16_t arg_len = lens[i];
527fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
528fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp = pdu + offset;
529fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		strcpy((char *) cslp->text, client->argv[i]);
530fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp->len = cpu_to_le16(arg_len);
531fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		offset += sizeof(*cslp) + arg_len;
532fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	}
53381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
5347f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	free(lens);
535fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp->lines = cpu_to_le16(client->argc);
53646bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	clp->client_type = __cpu_to_le16(client->type);
53740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOBLINE, pdu, mem, NULL, NULL);
53881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	free(pdu);
53981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
54081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
54181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
542a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboeint fio_clients_connect(void)
543a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe{
544a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	struct fio_client *client;
545a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	struct flist_head *entry, *tmp;
546a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	int ret;
547a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
54893bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#ifdef WIN32
54993bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran	WSADATA wsd;
5503c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe	WSAStartup(MAKEWORD(2, 2), &wsd);
55193bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#endif
55293bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran
55360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "client: connect all\n");
55460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
555cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	client_signal_handler();
556cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
557a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	flist_for_each_safe(entry, tmp, &client_list) {
558a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe		client = flist_entry(entry, struct fio_client, list);
559a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
560a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe		ret = fio_client_connect(client);
5610b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (ret) {
562a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe			remove_client(client);
5630b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			continue;
5640b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		}
5650b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
56681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		if (client->argc > 1)
56781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe			send_client_cmd_line(client);
568a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	}
569a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
570a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	return !nr_clients;
571a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe}
572a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
573b9d2f30a214ebd274340f888739be250838d63c2Jens Axboeint fio_start_client(struct fio_client *client)
574b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe{
575b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	dprint(FD_NET, "client: start %s\n", client->hostname);
576b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_RUN, 0, NULL);
577b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe}
578b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
579b9d2f30a214ebd274340f888739be250838d63c2Jens Axboeint fio_start_all_clients(void)
580b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe{
581b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct fio_client *client;
582b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct flist_head *entry, *tmp;
583b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	int ret;
584b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
585b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	dprint(FD_NET, "client: start all\n");
586b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
587952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	fio_client_json_init();
588952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu
589b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	flist_for_each_safe(entry, tmp, &client_list) {
590b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		client = flist_entry(entry, struct fio_client, list);
591b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
592b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		ret = fio_start_client(client);
593b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		if (ret) {
594b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe			remove_client(client);
595b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe			continue;
596b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		}
597b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	}
598b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
599b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return flist_empty(&client_list);
600b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe}
601b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
602132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe/*
603132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * Send file contents to server backend. We could use sendfile(), but to remain
604132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * more portable lets just read/write the darn thing.
605132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe */
6069988ca70151a191c477179be7999300ddff16230Jens Axboestatic int __fio_client_send_ini(struct fio_client *client, const char *filename)
607132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
60846bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	struct cmd_job_pdu *pdu;
60946bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	size_t p_size;
610132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct stat sb;
61146bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	char *p;
61246bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	void *buf;
613132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	off_t len;
614132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int fd, ret;
615132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
61646c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "send ini %s to %s\n", filename, client->hostname);
61746c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
618132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fd = open(filename, O_RDONLY);
619132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fd < 0) {
62025095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		int ret = -errno;
62125095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe
622e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		log_err("fio: job file <%s> open: %s\n", filename, strerror(errno));
62325095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		return ret;
624132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
625132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
626132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fstat(fd, &sb) < 0) {
62725095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		int ret = -errno;
62825095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe
629132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: job file stat: %s\n", strerror(errno));
630b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
63125095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe		return ret;
632132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
633132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
63446bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	p_size = sb.st_size + sizeof(*pdu);
63546bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu = malloc(p_size);
63646bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	buf = pdu->buf;
637132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
638132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	len = sb.st_size;
639132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	p = buf;
640132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
641132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = read(fd, p, len);
642132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
643132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
644132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
645132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
646132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
647132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
648132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
649132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
650132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
651132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
652132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (1);
653132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
6540b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	if (len) {
6550b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		log_err("fio: failed reading job file %s\n", filename);
656b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
65703a22d9188def5a2643c577a70d410f65a3e8f79Hong Zhiguo		free(pdu);
6580b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		return 1;
6590b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	}
6600b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
66146bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->buf_len = __cpu_to_le32(sb.st_size);
66246bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->client_type = cpu_to_le32(client->type);
66346bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe
664c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe	client->sent_job = 1;
66540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOB, pdu, p_size, NULL, NULL);
66646bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	free(pdu);
667b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe	close(fd);
668132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
669132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
67037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
6719988ca70151a191c477179be7999300ddff16230Jens Axboeint fio_client_send_ini(struct fio_client *client, const char *filename)
6729988ca70151a191c477179be7999300ddff16230Jens Axboe{
67325095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe	int ret;
67425095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe
67525095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe	ret = __fio_client_send_ini(client, filename);
6763af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe	if (!ret)
6773af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe		client->sent_job = 1;
6789988ca70151a191c477179be7999300ddff16230Jens Axboe
67925095e1bbcdc9f79f7052f6ff79e4b7245cce955Jens Axboe	return ret;
6809988ca70151a191c477179be7999300ddff16230Jens Axboe}
6819988ca70151a191c477179be7999300ddff16230Jens Axboe
682a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboeint fio_clients_send_ini(const char *filename)
683a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe{
684a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	struct fio_client *client;
685a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	struct flist_head *entry, *tmp;
686a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
687a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	flist_for_each_safe(entry, tmp, &client_list) {
688a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe		client = flist_entry(entry, struct fio_client, list);
689a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
69014ea90edf265aae2b82f25418fde179c452909f9Jens Axboe		if (client->nr_ini_file) {
69114ea90edf265aae2b82f25418fde179c452909f9Jens Axboe			int i;
69214ea90edf265aae2b82f25418fde179c452909f9Jens Axboe
69314ea90edf265aae2b82f25418fde179c452909f9Jens Axboe			for (i = 0; i < client->nr_ini_file; i++) {
69414ea90edf265aae2b82f25418fde179c452909f9Jens Axboe				const char *ini = client->ini_file[i];
69514ea90edf265aae2b82f25418fde179c452909f9Jens Axboe
69614ea90edf265aae2b82f25418fde179c452909f9Jens Axboe				if (fio_client_send_ini(client, ini)) {
69714ea90edf265aae2b82f25418fde179c452909f9Jens Axboe					remove_client(client);
69814ea90edf265aae2b82f25418fde179c452909f9Jens Axboe					break;
69914ea90edf265aae2b82f25418fde179c452909f9Jens Axboe				}
70014ea90edf265aae2b82f25418fde179c452909f9Jens Axboe			}
70114ea90edf265aae2b82f25418fde179c452909f9Jens Axboe		} else if (!filename || fio_client_send_ini(client, filename))
7023af452010d32267d085ba1612ebc0a40812c28a9Jens Axboe			remove_client(client);
703a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	}
704a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
705a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe	return !nr_clients;
706a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe}
707a37f69b72a74cbde6151458b890aab8d093f0c9fJens Axboe
70840c605169e60d32fc321a2f9f465e76cba745489Jens Axboeint fio_client_update_options(struct fio_client *client,
70940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			      struct thread_options *o, uint64_t *tag)
71040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
71140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	struct cmd_add_job_pdu pdu;
71240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
71340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	pdu.thread_number = cpu_to_le32(client->thread_number);
71440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	pdu.groupid = cpu_to_le32(client->groupid);
71540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	convert_thread_options_to_net(&pdu.top, o);
716952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu
71740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return fio_net_send_cmd(client->fd, FIO_NET_CMD_UPDATE_JOB, &pdu, sizeof(pdu), tag, &client->cmd_list);
71840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
71940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
720a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src)
721a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
722a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->max_val	= le64_to_cpu(src->max_val);
723a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->min_val	= le64_to_cpu(src->min_val);
724a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->samples	= le64_to_cpu(src->samples);
725802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
726802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	/*
727802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 * Floats arrive as IEEE 754 encoded uint64_t, convert back to double
728802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 */
729802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->mean.u.f	= fio_uint64_to_double(le64_to_cpu(dst->mean.u.i));
730802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->S.u.f	= fio_uint64_to_double(le64_to_cpu(dst->S.u.i));
731a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
732a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
733a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_ts(struct thread_stat *dst, struct thread_stat *src)
734a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
735a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i, j;
736a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
7372f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	dst->error		= le32_to_cpu(src->error);
7382f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	dst->thread_number	= le32_to_cpu(src->thread_number);
7392f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	dst->groupid		= le32_to_cpu(src->groupid);
7402f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	dst->pid		= le32_to_cpu(src->pid);
7412f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	dst->members		= le32_to_cpu(src->members);
742771e58befea806d2d881953050c4e65329eee382Jens Axboe	dst->unified_rw_rep	= le32_to_cpu(src->unified_rw_rep);
743a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
744298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
745a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&dst->clat_stat[i], &src->clat_stat[i]);
746a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&dst->slat_stat[i], &src->slat_stat[i]);
747a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&dst->lat_stat[i], &src->lat_stat[i]);
748a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&dst->bw_stat[i], &src->bw_stat[i]);
749a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
750a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
751a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->usr_time		= le64_to_cpu(src->usr_time);
752a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->sys_time		= le64_to_cpu(src->sys_time);
753a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->ctx		= le64_to_cpu(src->ctx);
754a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->minf		= le64_to_cpu(src->minf);
755a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->majf		= le64_to_cpu(src->majf);
756a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->clat_percentiles	= le64_to_cpu(src->clat_percentiles);
757802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
758802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
759802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe		fio_fp64_t *fps = &src->percentile_list[i];
760802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe		fio_fp64_t *fpd = &dst->percentile_list[i];
761802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
762802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe		fpd->u.f = fio_uint64_to_double(le64_to_cpu(fps->u.i));
763802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	}
764a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
765a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
766a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_map[i]	= le32_to_cpu(src->io_u_map[i]);
767a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_submit[i]	= le32_to_cpu(src->io_u_submit[i]);
768a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_complete[i]	= le32_to_cpu(src->io_u_complete[i]);
769a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
770a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
771a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
772a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_lat_u[i]	= le32_to_cpu(src->io_u_lat_u[i]);
773a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_u_lat_m[i]	= le32_to_cpu(src->io_u_lat_m[i]);
774a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
775a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
776298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++)
777a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
778a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			dst->io_u_plat[i][j] = le32_to_cpu(src->io_u_plat[i][j]);
779a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
78078799debc66f717469e751b3b9eb5dfa48cc547bJens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
781a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->total_io_u[i]	= le64_to_cpu(src->total_io_u[i]);
78293eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe		dst->short_io_u[i]	= le64_to_cpu(src->short_io_u[i]);
783a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
784a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
785a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->total_submit	= le64_to_cpu(src->total_submit);
786a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->total_complete	= le64_to_cpu(src->total_complete);
787a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
788298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
789a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_bytes[i]	= le64_to_cpu(src->io_bytes[i]);
790a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->runtime[i]		= le64_to_cpu(src->runtime[i]);
791a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
792a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
793a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->total_run_time	= le64_to_cpu(src->total_run_time);
794a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->continue_on_error	= le16_to_cpu(src->continue_on_error);
795a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->total_err_count	= le64_to_cpu(src->total_err_count);
796ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	dst->first_error	= le32_to_cpu(src->first_error);
797ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	dst->kb_base		= le32_to_cpu(src->kb_base);
798ad705bcb7e79a7cdb9891db17b4c40b13b6c30c3Steven Noonan	dst->unit_base		= le32_to_cpu(src->unit_base);
7993e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe
8003e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	dst->latency_depth	= le32_to_cpu(src->latency_depth);
8013e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	dst->latency_target	= le64_to_cpu(src->latency_target);
8023e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	dst->latency_window	= le64_to_cpu(src->latency_window);
8033e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	dst->latency_percentile.u.f = fio_uint64_to_double(le64_to_cpu(src->latency_percentile.u.i));
804a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
805a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
806a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
807a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
808a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i;
809a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
810298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
811a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_run[i]		= le64_to_cpu(src->max_run[i]);
812a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_run[i]		= le64_to_cpu(src->min_run[i]);
813a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_bw[i]		= le64_to_cpu(src->max_bw[i]);
814a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_bw[i]		= le64_to_cpu(src->min_bw[i]);
815a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_kb[i]		= le64_to_cpu(src->io_kb[i]);
816a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->agg[i]		= le64_to_cpu(src->agg[i]);
817a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
818a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
819a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->kb_base	= le32_to_cpu(src->kb_base);
820ad705bcb7e79a7cdb9891db17b4c40b13b6c30c3Steven Noonan	dst->unit_base	= le32_to_cpu(src->unit_base);
821a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= le32_to_cpu(src->groupid);
822771e58befea806d2d881953050c4e65329eee382Jens Axboe	dst->unified_rw_rep	= le32_to_cpu(src->unified_rw_rep);
823a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
824a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
825952b05e00103bf45576e1860cde0626bd42ed52aCastor Fustatic void json_object_add_client_info(struct json_object *obj,
826952b05e00103bf45576e1860cde0626bd42ed52aCastor Fustruct fio_client *client)
827952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu{
828952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	json_object_add_value_string(obj, "hostname", client->hostname);
829952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	json_object_add_value_int(obj, "port", client->port);
830952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu}
831952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu
83289e5fad91bc33f1687cca6b1bf5aa3084c424650Jens Axboestatic void handle_ts(struct fio_client *client, struct fio_net_cmd *cmd)
833a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
834a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct cmd_ts_pdu *p = (struct cmd_ts_pdu *) cmd->payload;
835952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	struct json_object *tsobj;
836a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
837952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	tsobj = show_thread_status(&p->ts, &p->rs);
838108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe	client->did_stat = 1;
839952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	if (tsobj) {
840952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		json_object_add_client_info(tsobj, client);
841952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		json_array_add_value_object(clients_array, tsobj);
842952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	}
84337f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
844108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe	if (!do_output_all_clients)
84537f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe		return;
84637f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
84737f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	sum_thread_stats(&client_ts, &p->ts, sum_stat_nr);
84837f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	sum_group_stats(&client_gs, &p->rs);
84937f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
85037f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	client_ts.members++;
8512f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	client_ts.thread_number = p->ts.thread_number;
85237f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	client_ts.groupid = p->ts.groupid;
853771e58befea806d2d881953050c4e65329eee382Jens Axboe	client_ts.unified_rw_rep = p->ts.unified_rw_rep;
85437f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
85537f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	if (++sum_stat_nr == sum_stat_clients) {
85637f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe		strcpy(client_ts.name, "All clients");
857952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		tsobj = show_thread_status(&client_ts, &client_gs);
858952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		if (tsobj) {
859952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu			json_object_add_client_info(tsobj, client);
860952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu			json_array_add_value_object(clients_array, tsobj);
861952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		}
86237f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	}
863a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
864a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
86589e5fad91bc33f1687cca6b1bf5aa3084c424650Jens Axboestatic void handle_gs(struct fio_client *client, struct fio_net_cmd *cmd)
866a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
867a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct group_run_stats *gs = (struct group_run_stats *) cmd->payload;
868a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
869a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	show_group_stats(gs);
870a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
871a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
8723bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboestatic void handle_text(struct fio_client *client, struct fio_net_cmd *cmd)
8733bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe{
8743bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	struct cmd_text_pdu *pdu = (struct cmd_text_pdu *) cmd->payload;
8753bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	const char *buf = (const char *) pdu->buf;
8763bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	const char *name;
8773bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	int fio_unused ret;
8783bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
8793bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	name = client->name ? client->name : client->hostname;
8803bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
8813bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	if (!client->skip_newline)
8823bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		fprintf(f_out, "<%s> ", name);
8833bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	ret = fwrite(buf, pdu->buf_len, 1, f_out);
8843bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	fflush(f_out);
8853bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	client->skip_newline = strchr(buf, '\n') == NULL;
8863bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe}
8873bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
888d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_agg(struct disk_util_agg *agg)
889d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
890d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
891d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
892d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
893d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		agg->ios[i]	= le32_to_cpu(agg->ios[i]);
894d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		agg->merges[i]	= le32_to_cpu(agg->merges[i]);
895d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		agg->sectors[i]	= le64_to_cpu(agg->sectors[i]);
896d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		agg->ticks[i]	= le32_to_cpu(agg->ticks[i]);
897d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
898d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
899d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	agg->io_ticks		= le32_to_cpu(agg->io_ticks);
900d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	agg->time_in_queue	= le32_to_cpu(agg->time_in_queue);
901d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	agg->slavecount		= le32_to_cpu(agg->slavecount);
902823ba54bfc91f18fdd847e6efc41b422529bc4f8Anton Blanchard	agg->max_util.u.f	= fio_uint64_to_double(__le64_to_cpu(agg->max_util.u.i));
903d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
904d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
905d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_dus(struct disk_util_stat *dus)
906d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
907d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
908d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
909d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
910a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe		dus->s.ios[i]		= le32_to_cpu(dus->s.ios[i]);
911a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe		dus->s.merges[i]	= le32_to_cpu(dus->s.merges[i]);
912a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe		dus->s.sectors[i]	= le64_to_cpu(dus->s.sectors[i]);
913a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe		dus->s.ticks[i]		= le32_to_cpu(dus->s.ticks[i]);
914d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
915d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
916a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe	dus->s.io_ticks		= le32_to_cpu(dus->s.io_ticks);
917a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe	dus->s.time_in_queue	= le32_to_cpu(dus->s.time_in_queue);
918a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe	dus->s.msec		= le64_to_cpu(dus->s.msec);
919d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
920d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
921d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void handle_du(struct fio_client *client, struct fio_net_cmd *cmd)
922d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
923d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct cmd_du_pdu *du = (struct cmd_du_pdu *) cmd->payload;
924d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
925d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	if (!client->disk_stats_shown) {
926d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		client->disk_stats_shown = 1;
927d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		log_info("\nDisk stats (read/write):\n");
928d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
929d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
930952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	if (output_format == FIO_OUTPUT_JSON) {
931952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		struct json_object *duobj;
932952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		json_array_add_disk_util(&du->dus, &du->agg, du_array);
933952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		duobj = json_array_last_value_object(du_array);
934952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		json_object_add_client_info(duobj, client);
935952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	} else
936952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu		print_disk_util(&du->dus, &du->agg, output_format == FIO_OUTPUT_TERSE);
937d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
938d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
9393bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboestatic void convert_jobs_eta(struct jobs_eta *je)
940cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe{
941cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	int i;
942cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
943cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->nr_running		= le32_to_cpu(je->nr_running);
944cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->nr_ramp		= le32_to_cpu(je->nr_ramp);
945cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->nr_pending		= le32_to_cpu(je->nr_pending);
946714e85f340194409d0abcf643cd2f154a7380a74Jens Axboe	je->nr_setting_up	= le32_to_cpu(je->nr_setting_up);
947cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->files_open		= le32_to_cpu(je->files_open);
948cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
949298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
950298921d65ea914873cbc270af6663dad9e08b782Jens Axboe		je->m_rate[i]	= le32_to_cpu(je->m_rate[i]);
951298921d65ea914873cbc270af6663dad9e08b782Jens Axboe		je->t_rate[i]	= le32_to_cpu(je->t_rate[i]);
952298921d65ea914873cbc270af6663dad9e08b782Jens Axboe		je->m_iops[i]	= le32_to_cpu(je->m_iops[i]);
953298921d65ea914873cbc270af6663dad9e08b782Jens Axboe		je->t_iops[i]	= le32_to_cpu(je->t_iops[i]);
95416725bb04ffc0d58af3f1fe91cd58b31961a74f7Jens Axboe		je->rate[i]	= le32_to_cpu(je->rate[i]);
95516725bb04ffc0d58af3f1fe91cd58b31961a74f7Jens Axboe		je->iops[i]	= le32_to_cpu(je->iops[i]);
956cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	}
957cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
958b51eedb75e3f1a9db33fa488ff7d9cc0a956b8eeJens Axboe	je->elapsed_sec		= le64_to_cpu(je->elapsed_sec);
959cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe	je->eta_sec		= le64_to_cpu(je->eta_sec);
9608c621fb2aa4b99c8a8b6b62435d713ab39b52c62Jens Axboe	je->nr_threads		= le32_to_cpu(je->nr_threads);
961b7f05eb03c84bdc1259d1bb1c348328b16164430Jens Axboe	je->is_pow2		= le32_to_cpu(je->is_pow2);
962ed2c0a120c9ebc7770fe14ef47f9d302c11cdfdaJens Axboe	je->unit_base		= le32_to_cpu(je->unit_base);
96348fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe}
96448fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
9653e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboevoid fio_client_sum_jobs_eta(struct jobs_eta *dst, struct jobs_eta *je)
96648fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe{
96748fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	int i;
96848fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
96948fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->nr_running		+= je->nr_running;
97048fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->nr_ramp		+= je->nr_ramp;
97148fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->nr_pending		+= je->nr_pending;
972714e85f340194409d0abcf643cd2f154a7380a74Jens Axboe	dst->nr_setting_up	+= je->nr_setting_up;
97348fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->files_open		+= je->files_open;
97448fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
975298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
9763e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		dst->m_rate[i]	+= je->m_rate[i];
9773e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		dst->t_rate[i]	+= je->t_rate[i];
9783e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		dst->m_iops[i]	+= je->m_iops[i];
9793e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		dst->t_iops[i]	+= je->t_iops[i];
98016725bb04ffc0d58af3f1fe91cd58b31961a74f7Jens Axboe		dst->rate[i]	+= je->rate[i];
98116725bb04ffc0d58af3f1fe91cd58b31961a74f7Jens Axboe		dst->iops[i]	+= je->iops[i];
98248fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	}
98348fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
98448fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	dst->elapsed_sec	+= je->elapsed_sec;
98548fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
98648fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	if (je->eta_sec > dst->eta_sec)
98748fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe		dst->eta_sec = je->eta_sec;
9888c621fb2aa4b99c8a8b6b62435d713ab39b52c62Jens Axboe
9898c621fb2aa4b99c8a8b6b62435d713ab39b52c62Jens Axboe	dst->nr_threads		+= je->nr_threads;
9908c621fb2aa4b99c8a8b6b62435d713ab39b52c62Jens Axboe	/* we need to handle je->run_str too ... */
99148fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe}
99248fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe
993a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboevoid fio_client_dec_jobs_eta(struct client_eta *eta, client_eta_op eta_fn)
99482c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe{
99582c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	if (!--eta->pending) {
996a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe		eta_fn(&eta->eta);
99782c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		free(eta);
99882c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	}
99982c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe}
100082c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
100189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic void remove_reply_cmd(struct fio_client *client, struct fio_net_cmd *cmd)
100289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
100340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	struct fio_net_cmd_reply *reply = NULL;
100489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct flist_head *entry;
100589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
100689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_for_each(entry, &client->cmd_list) {
100740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		reply = flist_entry(entry, struct fio_net_cmd_reply, list);
100889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
100940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		if (cmd->tag == (uintptr_t) reply)
101089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			break;
101189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
101240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		reply = NULL;
101389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
101489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
101540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	if (!reply) {
10164e0a8fa2593006505b7f4e18931a201d221b49e9Jens Axboe		log_err("fio: client: unable to find matching tag (%llx)\n", (unsigned long long) cmd->tag);
101789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return;
101889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
101989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
102040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	flist_del(&reply->list);
102140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	cmd->tag = reply->saved_tag;
102240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	free(reply);
102340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
102440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
102540c605169e60d32fc321a2f9f465e76cba745489Jens Axboeint fio_client_wait_for_reply(struct fio_client *client, uint64_t tag)
102640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
102740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	do {
102840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		struct fio_net_cmd_reply *reply = NULL;
102940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		struct flist_head *entry;
103040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
103140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		flist_for_each(entry, &client->cmd_list) {
103240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			reply = flist_entry(entry, struct fio_net_cmd_reply, list);
103340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
103440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			if (tag == (uintptr_t) reply)
103540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe				break;
103640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
103740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			reply = NULL;
103840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		}
103940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
104040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		if (!reply)
104140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			break;
104240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
104340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		usleep(1000);
104440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	} while (1);
104540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
104640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return 0;
104789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
104889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
104982c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboestatic void handle_eta(struct fio_client *client, struct fio_net_cmd *cmd)
105048fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe{
105148fbb46e7c9a2721b3b23898ab9ec79727ab4e9bJens Axboe	struct jobs_eta *je = (struct jobs_eta *) cmd->payload;
1052df380934e53c645b4b7cdec882b512b4d20ebc14Jens Axboe	struct client_eta *eta = (struct client_eta *) (uintptr_t) cmd->tag;
1053af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
1054af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "client: got eta tag %p, %d\n", eta, eta->pending);
1055cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
1056f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe	assert(client->eta_in_flight == eta);
1057f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe
1058f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe	client->eta_in_flight = NULL;
105982c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	flist_del_init(&client->eta_list);
106082c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
10612f99deb0895b2d0b618e6e72c74add7192b4d73fJens Axboe	if (client->ops->jobs_eta)
10622f99deb0895b2d0b618e6e72c74add7192b4d73fJens Axboe		client->ops->jobs_eta(client, je);
10632f99deb0895b2d0b618e6e72c74add7192b4d73fJens Axboe
10643e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe	fio_client_sum_jobs_eta(&eta->eta, je);
1065a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe	fio_client_dec_jobs_eta(eta, client->ops->eta);
1066cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe}
1067cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
1068b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboestatic void handle_probe(struct fio_client *client, struct fio_net_cmd *cmd)
10692e03b4b2a072b79946b0ee651dff38273868473aJens Axboe{
10703989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_probe_reply_pdu *probe = (struct cmd_probe_reply_pdu *) cmd->payload;
1071d2333358fb3729de6681ed5cc3ec45cd86b5cfb8Jens Axboe	const char *os, *arch;
1072d2333358fb3729de6681ed5cc3ec45cd86b5cfb8Jens Axboe	char bit[16];
10732e03b4b2a072b79946b0ee651dff38273868473aJens Axboe
1074cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	os = fio_get_os_string(probe->os);
1075cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	if (!os)
1076cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe		os = "unknown";
1077cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe
1078cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	arch = fio_get_arch_string(probe->arch);
1079cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	if (!arch)
1080cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe		os = "unknown";
1081cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe
1082d2333358fb3729de6681ed5cc3ec45cd86b5cfb8Jens Axboe	sprintf(bit, "%d-bit", probe->bpp * 8);
10833989b14303458519192f4ace8caf091d587f5e6eJens Axboe	probe->flags = le64_to_cpu(probe->flags);
108438fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe
10853989b14303458519192f4ace8caf091d587f5e6eJens Axboe	log_info("hostname=%s, be=%u, %s, os=%s, arch=%s, fio=%s, flags=%lx\n",
108638fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe		probe->hostname, probe->bigendian, bit, os, arch,
10873989b14303458519192f4ace8caf091d587f5e6eJens Axboe		probe->fio_version, (unsigned long) probe->flags);
1088b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe
1089b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe	if (!client->name)
1090b5296ddb3f34610e4bd90272bf5035a41691d00fJens Axboe		client->name = strdup((char *) probe->hostname);
10912e03b4b2a072b79946b0ee651dff38273868473aJens Axboe}
10922e03b4b2a072b79946b0ee651dff38273868473aJens Axboe
109311e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboestatic void handle_start(struct fio_client *client, struct fio_net_cmd *cmd)
109411e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe{
109511e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	struct cmd_start_pdu *pdu = (struct cmd_start_pdu *) cmd->payload;
109611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
109711e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	client->state = Client_started;
109811e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	client->jobs = le32_to_cpu(pdu->jobs);
1099108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe	client->nr_stat = le32_to_cpu(pdu->stat_outputs);
1100108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe
1101108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe	if (sum_stat_clients > 1)
1102108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe		do_output_all_clients = 1;
1103108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe
1104108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe	sum_stat_clients += client->nr_stat;
110511e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe}
110611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
110711e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboestatic void handle_stop(struct fio_client *client, struct fio_net_cmd *cmd)
110811e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe{
1109498c92c27b475bcc0cb65e529fb02713bc1fb62cJens Axboe	if (client->error)
1110498c92c27b475bcc0cb65e529fb02713bc1fb62cJens Axboe		log_info("client <%s>: exited with error %d\n", client->hostname, client->error);
111111e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe}
111211e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
11136b79c80c14766df7b0507c4ec679507a315ad61aJens Axboestatic void convert_stop(struct fio_net_cmd *cmd)
11146b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe{
11156b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe	struct cmd_end_pdu *pdu = (struct cmd_end_pdu *) cmd->payload;
11166b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe
11176b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe	pdu->error = le32_to_cpu(pdu->error);
11186b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe}
11196b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe
1120084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboestatic void convert_text(struct fio_net_cmd *cmd)
1121084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe{
1122084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	struct cmd_text_pdu *pdu = (struct cmd_text_pdu *) cmd->payload;
1123084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
1124084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->level	= le32_to_cpu(pdu->level);
1125084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->buf_len	= le32_to_cpu(pdu->buf_len);
1126084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_sec	= le64_to_cpu(pdu->log_sec);
1127084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_usec	= le64_to_cpu(pdu->log_usec);
1128084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe}
1129084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
11303989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic struct cmd_iolog_pdu *convert_iolog_gz(struct fio_net_cmd *cmd,
11313989b14303458519192f4ace8caf091d587f5e6eJens Axboe					      struct cmd_iolog_pdu *pdu)
11321b42725f06f8906b9b99381da3490484f59df28aJens Axboe{
11333989b14303458519192f4ace8caf091d587f5e6eJens Axboe#ifdef CONFIG_ZLIB
11341b42725f06f8906b9b99381da3490484f59df28aJens Axboe	struct cmd_iolog_pdu *ret;
11351b42725f06f8906b9b99381da3490484f59df28aJens Axboe	z_stream stream;
11363989b14303458519192f4ace8caf091d587f5e6eJens Axboe	uint32_t nr_samples;
11373989b14303458519192f4ace8caf091d587f5e6eJens Axboe	size_t total;
11381b42725f06f8906b9b99381da3490484f59df28aJens Axboe	void *p;
11391b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11401b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zalloc = Z_NULL;
11411b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zfree = Z_NULL;
11421b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.opaque = Z_NULL;
11431b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.avail_in = 0;
11441b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.next_in = Z_NULL;
11451b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11461b42725f06f8906b9b99381da3490484f59df28aJens Axboe	if (inflateInit(&stream) != Z_OK)
11471b42725f06f8906b9b99381da3490484f59df28aJens Axboe		return NULL;
11481b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11491b42725f06f8906b9b99381da3490484f59df28aJens Axboe	/*
1150f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	 * Get header first, it's not compressed
11511b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 */
11521b42725f06f8906b9b99381da3490484f59df28aJens Axboe	nr_samples = le32_to_cpu(pdu->nr_samples);
11531b42725f06f8906b9b99381da3490484f59df28aJens Axboe
1154f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	total = nr_samples * sizeof(struct io_sample);
1155f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	ret = malloc(total + sizeof(*pdu));
11561b42725f06f8906b9b99381da3490484f59df28aJens Axboe	ret->nr_samples = nr_samples;
11573989b14303458519192f4ace8caf091d587f5e6eJens Axboe
11583989b14303458519192f4ace8caf091d587f5e6eJens Axboe	memcpy(ret, pdu, sizeof(*pdu));
1159f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe
1160f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	p = (void *) ret + sizeof(*pdu);
11611b42725f06f8906b9b99381da3490484f59df28aJens Axboe
1162f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	stream.avail_in = cmd->pdu_len - sizeof(*pdu);
1163f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	stream.next_in = (void *) pdu + sizeof(*pdu);
11641b42725f06f8906b9b99381da3490484f59df28aJens Axboe	while (stream.avail_in) {
11651b42725f06f8906b9b99381da3490484f59df28aJens Axboe		unsigned int this_chunk = 65536;
11661b42725f06f8906b9b99381da3490484f59df28aJens Axboe		unsigned int this_len;
11671b42725f06f8906b9b99381da3490484f59df28aJens Axboe		int err;
11681b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11691b42725f06f8906b9b99381da3490484f59df28aJens Axboe		if (this_chunk > total)
11701b42725f06f8906b9b99381da3490484f59df28aJens Axboe			this_chunk = total;
11711b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11721b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.avail_out = this_chunk;
11731b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.next_out = p;
11741b42725f06f8906b9b99381da3490484f59df28aJens Axboe		err = inflate(&stream, Z_NO_FLUSH);
11753c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		/* may be Z_OK, or Z_STREAM_END */
11763c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		if (err < 0) {
11771b42725f06f8906b9b99381da3490484f59df28aJens Axboe			log_err("fio: inflate error %d\n", err);
1178f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe			free(ret);
1179f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe			ret = NULL;
11803989b14303458519192f4ace8caf091d587f5e6eJens Axboe			goto err;
11811b42725f06f8906b9b99381da3490484f59df28aJens Axboe		}
11821b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11831b42725f06f8906b9b99381da3490484f59df28aJens Axboe		this_len = this_chunk - stream.avail_out;
11841b42725f06f8906b9b99381da3490484f59df28aJens Axboe		p += this_len;
11851b42725f06f8906b9b99381da3490484f59df28aJens Axboe		total -= this_len;
11861b42725f06f8906b9b99381da3490484f59df28aJens Axboe	}
11871b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11883989b14303458519192f4ace8caf091d587f5e6eJens Axboeerr:
11893989b14303458519192f4ace8caf091d587f5e6eJens Axboe	inflateEnd(&stream);
11903989b14303458519192f4ace8caf091d587f5e6eJens Axboe	return ret;
11913989b14303458519192f4ace8caf091d587f5e6eJens Axboe#else
11923989b14303458519192f4ace8caf091d587f5e6eJens Axboe	return NULL;
11933989b14303458519192f4ace8caf091d587f5e6eJens Axboe#endif
11943989b14303458519192f4ace8caf091d587f5e6eJens Axboe}
11953989b14303458519192f4ace8caf091d587f5e6eJens Axboe
11963989b14303458519192f4ace8caf091d587f5e6eJens Axboe/*
11973989b14303458519192f4ace8caf091d587f5e6eJens Axboe * This has been compressed on the server side, since it can be big.
11983989b14303458519192f4ace8caf091d587f5e6eJens Axboe * Uncompress here.
11993989b14303458519192f4ace8caf091d587f5e6eJens Axboe */
12003989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd)
12013989b14303458519192f4ace8caf091d587f5e6eJens Axboe{
12023989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_iolog_pdu *pdu = (struct cmd_iolog_pdu *) cmd->payload;
12033989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_iolog_pdu *ret;
12043989b14303458519192f4ace8caf091d587f5e6eJens Axboe	int i;
12053989b14303458519192f4ace8caf091d587f5e6eJens Axboe
12063989b14303458519192f4ace8caf091d587f5e6eJens Axboe	/*
12073989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 * Convert if compressed and we support it. If it's not
12083989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 * compressed, we need not do anything.
12093989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 */
12103989b14303458519192f4ace8caf091d587f5e6eJens Axboe	if (le32_to_cpu(pdu->compressed)) {
12113989b14303458519192f4ace8caf091d587f5e6eJens Axboe#ifndef CONFIG_ZLIB
12123989b14303458519192f4ace8caf091d587f5e6eJens Axboe		log_err("fio: server sent compressed data by mistake\n");
12133989b14303458519192f4ace8caf091d587f5e6eJens Axboe		return NULL;
12143989b14303458519192f4ace8caf091d587f5e6eJens Axboe#endif
12153989b14303458519192f4ace8caf091d587f5e6eJens Axboe		ret = convert_iolog_gz(cmd, pdu);
12163989b14303458519192f4ace8caf091d587f5e6eJens Axboe		if (!ret) {
12173989b14303458519192f4ace8caf091d587f5e6eJens Axboe			log_err("fio: failed decompressing log\n");
12183989b14303458519192f4ace8caf091d587f5e6eJens Axboe			return NULL;
12193989b14303458519192f4ace8caf091d587f5e6eJens Axboe		}
12203989b14303458519192f4ace8caf091d587f5e6eJens Axboe	} else
12213989b14303458519192f4ace8caf091d587f5e6eJens Axboe		ret = pdu;
12223989b14303458519192f4ace8caf091d587f5e6eJens Axboe
12233989b14303458519192f4ace8caf091d587f5e6eJens Axboe	ret->thread_number	= le32_to_cpu(ret->thread_number);
12243989b14303458519192f4ace8caf091d587f5e6eJens Axboe	ret->nr_samples		= le32_to_cpu(ret->nr_samples);
12253989b14303458519192f4ace8caf091d587f5e6eJens Axboe	ret->log_type		= le32_to_cpu(ret->log_type);
12263989b14303458519192f4ace8caf091d587f5e6eJens Axboe	ret->compressed		= le32_to_cpu(ret->compressed);
12273989b14303458519192f4ace8caf091d587f5e6eJens Axboe
1228f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	for (i = 0; i < ret->nr_samples; i++) {
1229f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		struct io_sample *s = &ret->samples[i];
1230f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe
1231f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->time	= le64_to_cpu(s->time);
1232f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->val	= le64_to_cpu(s->val);
1233f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->ddir	= le32_to_cpu(s->ddir);
1234f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->bs	= le32_to_cpu(s->bs);
1235f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	}
1236f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe
12371b42725f06f8906b9b99381da3490484f59df28aJens Axboe	return ret;
12381b42725f06f8906b9b99381da3490484f59df28aJens Axboe}
12391b42725f06f8906b9b99381da3490484f59df28aJens Axboe
1240a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboeint fio_handle_client(struct fio_client *client)
124137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
1242a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe	struct client_ops *ops = client->ops;
124337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	struct fio_net_cmd *cmd;
124437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
124560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "client: handle %s\n", client->hostname);
124660efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
1247e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	cmd = fio_net_recv_cmd(client->fd);
1248e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	if (!cmd)
1249e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		return 0;
1250c2c9458515bda1f77e25f95122ef6ec8d8cc3ec7Jens Axboe
1251b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	dprint(FD_NET, "client: got cmd op %s from %s (pdu=%u)\n",
1252b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		fio_server_op(cmd->opcode), client->hostname, cmd->pdu_len);
125346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
1254e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	switch (cmd->opcode) {
1255e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_QUIT:
12563ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		if (ops->quit)
125735c0ba7ff55bbd438cdc171945c61d501a4e693eJens Axboe			ops->quit(client, cmd);
1258e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		remove_client(client);
1259e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
1260e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
1261084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	case FIO_NET_CMD_TEXT:
1262084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe		convert_text(cmd);
126335c0ba7ff55bbd438cdc171945c61d501a4e693eJens Axboe		ops->text(client, cmd);
1264e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
1265e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
12663bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	case FIO_NET_CMD_DU: {
12673bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		struct cmd_du_pdu *du = (struct cmd_du_pdu *) cmd->payload;
12683bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
12693bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		convert_dus(&du->dus);
12703bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		convert_agg(&du->agg);
12713bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
1272dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameron		ops->disk_util(client, cmd);
1273d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		free(cmd);
1274d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		break;
12753bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		}
12763bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	case FIO_NET_CMD_TS: {
12773bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		struct cmd_ts_pdu *p = (struct cmd_ts_pdu *) cmd->payload;
12783bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
12793bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		convert_ts(&p->ts, &p->ts);
12803bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		convert_gs(&p->rs, &p->rs);
12813bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
128289e5fad91bc33f1687cca6b1bf5aa3084c424650Jens Axboe		ops->thread_status(client, cmd);
1283e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
1284e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
12853bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		}
12863bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	case FIO_NET_CMD_GS: {
12873bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		struct group_run_stats *gs = (struct group_run_stats *) cmd->payload;
12883bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
12893bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		convert_gs(gs, gs);
12903bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
129189e5fad91bc33f1687cca6b1bf5aa3084c424650Jens Axboe		ops->group_stats(client, cmd);
1292e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
1293e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
12943bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		}
12953bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe	case FIO_NET_CMD_ETA: {
12963bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		struct jobs_eta *je = (struct jobs_eta *) cmd->payload;
12973bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe
129889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		remove_reply_cmd(client, cmd);
12993bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		convert_jobs_eta(je);
1300a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe		handle_eta(client, cmd);
1301e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
1302e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
13033bf236c082e36f222b64edf9ae2bd7637156d0acJens Axboe		}
1304e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	case FIO_NET_CMD_PROBE:
130589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		remove_reply_cmd(client, cmd);
1306dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameron		ops->probe(client, cmd);
1307e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
1308e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
13095d7793aa2b1dc1044b1918d829a1bcd4c9a19196Jens Axboe	case FIO_NET_CMD_SERVER_START:
131001be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe		client->state = Client_running;
131185dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboe		if (ops->job_start)
131285dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboe			ops->job_start(client, cmd);
131301be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe		free(cmd);
131401be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe		break;
131585dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboe	case FIO_NET_CMD_START: {
131685dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboe		struct cmd_start_pdu *pdu = (struct cmd_start_pdu *) cmd->payload;
131785dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboe
131885dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboe		pdu->jobs = le32_to_cpu(pdu->jobs);
131985dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboe		ops->start(client, cmd);
1320e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
1321e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
132285dd01e7d7fa9989bf55002bc416c4d8118fdf5fJens Axboe		}
13236b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe	case FIO_NET_CMD_STOP: {
13246b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe		struct cmd_end_pdu *pdu = (struct cmd_end_pdu *) cmd->payload;
13256b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe
13266b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe		convert_stop(cmd);
13276b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe		client->state = Client_stopped;
1328122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		client->error = le32_to_cpu(pdu->error);
1329122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		client->signal = le32_to_cpu(pdu->signal);
13306b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe		ops->stop(client, cmd);
1331e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
1332e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
13336b79c80c14766df7b0507c4ec679507a315ad61aJens Axboe		}
133440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	case FIO_NET_CMD_ADD_JOB: {
133540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		struct cmd_add_job_pdu *pdu = (struct cmd_add_job_pdu *) cmd->payload;
133640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
133740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		client->thread_number = le32_to_cpu(pdu->thread_number);
133840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		client->groupid = le32_to_cpu(pdu->groupid);
133940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
1340807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe		if (ops->add_job)
1341807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe			ops->add_job(client, cmd);
1342807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe		free(cmd);
1343807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe		break;
134440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		}
13451b42725f06f8906b9b99381da3490484f59df28aJens Axboe	case FIO_NET_CMD_IOLOG:
13461b42725f06f8906b9b99381da3490484f59df28aJens Axboe		if (ops->iolog) {
13471b42725f06f8906b9b99381da3490484f59df28aJens Axboe			struct cmd_iolog_pdu *pdu;
13481b42725f06f8906b9b99381da3490484f59df28aJens Axboe
13491b42725f06f8906b9b99381da3490484f59df28aJens Axboe			pdu = convert_iolog(cmd);
13501b42725f06f8906b9b99381da3490484f59df28aJens Axboe			ops->iolog(client, pdu);
13511b42725f06f8906b9b99381da3490484f59df28aJens Axboe		}
13521b42725f06f8906b9b99381da3490484f59df28aJens Axboe		free(cmd);
13531b42725f06f8906b9b99381da3490484f59df28aJens Axboe		break;
135440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	case FIO_NET_CMD_UPDATE_JOB:
135540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		ops->update_job(client, cmd);
1356649cee91722e8e582b30175a1493f2815ae75f06Jens Axboe		remove_reply_cmd(client, cmd);
135740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		free(cmd);
135840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		break;
1359e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	default:
136089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		log_err("fio: unknown client op: %s\n", fio_server_op(cmd->opcode));
1361e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		free(cmd);
1362e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		break;
136337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	}
136437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
1365e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe	return 1;
136637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe}
1367b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
1368a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboestatic void request_client_etas(struct client_ops *ops)
1369af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{
1370af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct fio_client *client;
1371af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct flist_head *entry;
1372af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct client_eta *eta;
137382c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	int skipped = 0;
1374af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
1375af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "client: request eta (%d)\n", nr_clients);
1376af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
1377af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	eta = malloc(sizeof(*eta));
1378af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	memset(&eta->eta, 0, sizeof(eta->eta));
1379af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	eta->pending = nr_clients;
1380af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
1381af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	flist_for_each(entry, &client_list) {
1382af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		client = flist_entry(entry, struct fio_client, list);
1383af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
138482c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		if (!flist_empty(&client->eta_list)) {
138582c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe			skipped++;
138682c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe			continue;
138782c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		}
138801be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe		if (client->state != Client_running)
138901be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe			continue;
139082c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
1391f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe		assert(!client->eta_in_flight);
139282c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe		flist_add_tail(&client->eta_list, &eta_list);
1393f77d2676c36ec30cfb765b90505bdda7208c9796Jens Axboe		client->eta_in_flight = eta;
1394af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_SEND_ETA,
1395df380934e53c645b4b7cdec882b512b4d20ebc14Jens Axboe					(uintptr_t) eta, &client->cmd_list);
1396af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
1397af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
139882c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe	while (skipped--)
1399a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe		fio_client_dec_jobs_eta(eta, ops->eta);
140082c1ed38d6c90c03beda072ed064a445ecb56acaJens Axboe
1401af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "client: requested eta tag %p\n", eta);
1402af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe}
1403af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
140489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int client_check_cmd_timeout(struct fio_client *client,
140589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe				    struct timeval *now)
140689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
140740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	struct fio_net_cmd_reply *reply;
140889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct flist_head *entry, *tmp;
140989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret = 0;
141089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
141189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_for_each_safe(entry, tmp, &client->cmd_list) {
141240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		reply = flist_entry(entry, struct fio_net_cmd_reply, list);
141389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
141440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		if (mtime_since(&reply->tv, now) < FIO_NET_CLIENT_TIMEOUT)
141589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			continue;
141689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
141789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		log_err("fio: client %s, timeout on cmd %s\n", client->hostname,
141840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe						fio_server_op(reply->opcode));
141940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		flist_del(&reply->list);
142040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		free(reply);
142189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		ret = 1;
142289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
142389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
142489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return flist_empty(&client->cmd_list) && ret;
142589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
142689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
1427a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboestatic int fio_check_clients_timed_out(void)
142889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
142989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct fio_client *client;
143089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct flist_head *entry, *tmp;
143189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct timeval tv;
143289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret = 0;
143389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
143467bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	fio_gettime(&tv, NULL);
143589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
143689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_for_each_safe(entry, tmp, &client_list) {
143789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		client = flist_entry(entry, struct fio_client, list);
143889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
143989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		if (flist_empty(&client->cmd_list))
144089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			continue;
144189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
144289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		if (!client_check_cmd_timeout(client, &tv))
144389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			continue;
144489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
1445a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe		if (client->ops->timed_out)
1446a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe			client->ops->timed_out(client);
1447ed727a4632fa3195f31758c79e209ca8d524bbc4Jens Axboe		else
1448ed727a4632fa3195f31758c79e209ca8d524bbc4Jens Axboe			log_err("fio: client %s timed out\n", client->hostname);
1449ed727a4632fa3195f31758c79e209ca8d524bbc4Jens Axboe
145089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		remove_client(client);
145189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		ret = 1;
145289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
145389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
145489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return ret;
145589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
145689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
1457dd366728eb503e6344215ae6ec153c7ab6eafd9bStephen M. Cameronint fio_handle_clients(struct client_ops *ops)
1458b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe{
1459b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	struct pollfd *pfds;
1460498c92c27b475bcc0cb65e529fb02713bc1fb62cJens Axboe	int i, ret = 0, retval = 0;
1461b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
146267bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	fio_gettime(&eta_tv, NULL);
1463af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
1464b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	pfds = malloc(nr_clients * sizeof(struct pollfd));
1465b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
146637f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	init_thread_stat(&client_ts);
146737f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe	init_group_run_stat(&client_gs);
146837f0c1ae23ad1716403d3d113c3dfdf41c47e329Jens Axboe
146982a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe	while (!exit_backend && nr_clients) {
1470c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe		struct flist_head *entry, *tmp;
1471c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe		struct fio_client *client;
1472c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe
147382a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe		i = 0;
1474c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe		flist_for_each_safe(entry, tmp, &client_list) {
147582a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe			client = flist_entry(entry, struct fio_client, list);
1476b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
1477a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe			if (!client->sent_job && !client->ops->stay_connected &&
1478c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe			    flist_empty(&client->cmd_list)) {
1479c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe				remove_client(client);
1480c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe				continue;
1481c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe			}
1482c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe
148382a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe			pfds[i].fd = client->fd;
148482a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe			pfds[i].events = POLLIN;
148582a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe			i++;
148682a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe		}
148782a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe
1488c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe		if (!nr_clients)
1489c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe			break;
1490c2cb68696255a8fda93043a1f2219b60af614549Jens Axboe
149182a4be1bcef4228233e61b0b034ad6eb78a7558cJens Axboe		assert(i == nr_clients);
1492b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
14935c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe		do {
1494af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe			struct timeval tv;
1495af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
149667bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe			fio_gettime(&tv, NULL);
1497af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe			if (mtime_since(&eta_tv, &tv) >= 900) {
1498a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe				request_client_etas(ops);
1499af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe				memcpy(&eta_tv, &tv, sizeof(tv));
150089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
1501a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe				if (fio_check_clients_timed_out())
150289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe					break;
1503af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe			}
1504af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
150580102c86786d7d50ba72366cee03061735b3cbacJens Axboe			ret = poll(pfds, nr_clients, ops->eta_msec);
15065c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe			if (ret < 0) {
15075c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe				if (errno == EINTR)
15085c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe					continue;
15095c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe				log_err("fio: poll clients: %s\n", strerror(errno));
15105c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe				break;
15115c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe			} else if (!ret)
1512b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe				continue;
15135c2857f9f5cb350c9441be3f3e1cd7c9dc18b1c5Jens Axboe		} while (ret <= 0);
1514b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
1515b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe		for (i = 0; i < nr_clients; i++) {
1516b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			if (!(pfds[i].revents & POLLIN))
1517b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe				continue;
1518b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
1519b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			client = find_client_by_fd(pfds[i].fd);
1520b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			if (!client) {
152165e1a120131f069fda859498ff4565a9b6e16dc2Jens Axboe				log_err("fio: unknown client fd %ld\n", (long) pfds[i].fd);
1522b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe				continue;
1523b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe			}
1524a52766160d7f2a937c74d4adee1819ef00467d4bJens Axboe			if (!fio_handle_client(client)) {
152528d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe				log_info("client: host=%s disconnected\n",
152628d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe						client->hostname);
152728d3ab07f7c68afe9ad3b07bb9c288f3e94957daJens Axboe				remove_client(client);
1528498c92c27b475bcc0cb65e529fb02713bc1fb62cJens Axboe				retval = 1;
15293899076470e108d9815a322aaa97e662d141b50cJens Axboe			} else if (client->error)
1530498c92c27b475bcc0cb65e529fb02713bc1fb62cJens Axboe				retval = 1;
1531343cb4a98200757bdcb0c5203e9120bb777625a8Jens Axboe			fio_put_client(client);
1532b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe		}
1533b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	}
1534b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe
1535952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu	fio_client_json_fini();
1536952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu
1537b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe	free(pfds);
1538498c92c27b475bcc0cb65e529fb02713bc1fb62cJens Axboe	return retval;
1539b66570dce15587a37a64685f8ab72c3018771b2bJens Axboe}
1540