150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <stdio.h>
250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <stdlib.h>
3142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe#include <stdarg.h>
450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <unistd.h>
550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <limits.h>
650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <errno.h>
750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/poll.h>
850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/types.h>
950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/wait.h>
10d05c4a03365f1b677c05840865e67ffaf2c5b05bJens Axboe#include <sys/socket.h>
1187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/stat.h>
1287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/un.h>
131f51bba9851d792fcf87e05f302162d50854c3a8Bruce Cran#include <sys/uio.h>
1450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netinet/in.h>
1550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <arpa/inet.h>
1650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netdb.h>
17e46d809110bd4ad2980ca64931b683673444454bJens Axboe#include <syslog.h>
189e22ecb0271038f61e00e448d8839f0c1bf6017eJens Axboe#include <signal.h>
193989b14303458519192f4ace8caf091d587f5e6eJens Axboe#ifdef CONFIG_ZLIB
201b42725f06f8906b9b99381da3490484f59df28aJens Axboe#include <zlib.h>
213989b14303458519192f4ace8caf091d587f5e6eJens Axboe#endif
2250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
2350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h"
24132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h"
25fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h"
26c7c6cb4cb3114ec4ce3107e15c184e161b50122eJens Axboe#include "lib/ieee754.h"
2789cf1480594858ad4e02499834c04fe48ff0a89dJens Axboe
285adc2447a8d52322981da4cd364a560bbd9d8351Stephen M. Cameronint fio_net_port = FIO_NET_PORT;
2950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
30009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0;
31009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
3246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1;
3387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *fio_server_arg;
3487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *bind_sock;
3587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic struct sockaddr_in saddr_in;
36811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic struct sockaddr_in6 saddr_in6;
37811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic int use_ipv6;
383989b14303458519192f4ace8caf091d587f5e6eJens Axboe#ifdef CONFIG_ZLIB
393989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic unsigned int has_zlib = 1;
403989b14303458519192f4ace8caf091d587f5e6eJens Axboe#else
413989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic unsigned int has_zlib = 0;
423989b14303458519192f4ace8caf091d587f5e6eJens Axboe#endif
433989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic unsigned int use_zlib;
4437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
45122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestruct fio_fork_item {
46122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct flist_head list;
47122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int exitval;
48122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int signal;
49122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int exited;
50122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid_t pid;
51122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe};
52122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
5389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic const char *fio_server_ops[FIO_NET_CMD_NR] = {
5489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"",
5589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"QUIT",
5689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"EXIT",
5789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOB",
5889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOBLINE",
5989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TEXT",
6089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TS",
6189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"GS",
6289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"SEND_ETA",
6389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"ETA",
6489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"PROBE",
6589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"START",
66d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"STOP",
67d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"DISK_UTIL",
68b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	"SERVER_START",
69807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe	"ADD_JOB",
708d7b618a261e7642769b8f0bf2cf6649bb383330Jens Axboe	"CMD_RUN",
71c70e63e5a86e524a60662d6538803c5e18ab7a4fJens Axboe	"CMD_IOLOG",
7289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe};
7389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
7489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeconst char *fio_server_op(unsigned int op)
7589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
7689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	static char buf[32];
7789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
7889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (op < FIO_NET_CMD_NR)
7989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_server_ops[op];
8089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
8189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	sprintf(buf, "UNKNOWN/%d", op);
8289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return buf;
8389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
8489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
855235f62680ba4be74d56805eb54c3af4de28e556Jens Axboestatic ssize_t iov_total_len(const struct iovec *iov, int count)
86132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
875235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	ssize_t ret = 0;
88794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
895235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	while (count--) {
905235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe		ret += iov->iov_len;
915235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe		iov++;
925235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	}
935235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
945235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	return ret;
955235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe}
96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
975235f62680ba4be74d56805eb54c3af4de28e556Jens Axboestatic int fio_sendv_data(int sk, struct iovec *iov, int count)
985235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe{
995235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	ssize_t total_len = iov_total_len(iov, count);
1005235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	ssize_t ret;
1015235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1025235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	do {
1035235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe		ret = writev(sk, iov, count);
104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
1055235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			total_len -= ret;
1065235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			if (!total_len)
107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
1085235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1095235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			while (ret) {
1105235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				if (ret >= iov->iov_len) {
1115235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe					ret -= iov->iov_len;
1125235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe					iov++;
1135235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe					continue;
1145235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				}
1155235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				iov->iov_base += ret;
1165235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				iov->iov_len -= ret;
1175235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				ret = 0;
1185235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			}
119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
120132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
122132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
1237b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
1247b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
125132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
126132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1275235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	if (!total_len)
128132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1308b4e61b27203fff2cc68a967ae3f6cacaca71e43Jens Axboe	if (errno)
1318b4e61b27203fff2cc68a967ae3f6cacaca71e43Jens Axboe		return -errno;
1328b4e61b27203fff2cc68a967ae3f6cacaca71e43Jens Axboe
133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 1;
134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1365235f62680ba4be74d56805eb54c3af4de28e556Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len)
1375235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe{
1385235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	struct iovec iov = { .iov_base = (void *) p, .iov_len = len };
1395235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1405235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_FRAGMENT_PDU);
1415235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1425235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	return fio_sendv_data(sk, &iov, 1);
1435235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe}
1445235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len)
146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = recv(sk, p, len, MSG_WAITALL);
149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
154132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
155132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
156132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
157132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
158132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
159132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
1607b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
1617b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
162132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
163132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
164132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
165132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
166132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
167132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return -1;
168132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
169132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
170132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd)
171132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
172fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
173132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
174fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16);
175fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16);
176132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
17725dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	crc = fio_crc16(cmd, FIO_NET_CMD_CRC_SZ);
178fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != cmd->cmd_crc16) {
179132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on command (got %x, wanted %x)\n",
180fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				cmd->cmd_crc16, crc);
181132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
182132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
183132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
184132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->version	= le16_to_cpu(cmd->version);
185132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->opcode	= le16_to_cpu(cmd->opcode);
186132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->flags	= le32_to_cpu(cmd->flags);
187af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	cmd->tag	= le64_to_cpu(cmd->tag);
188132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->pdu_len	= le32_to_cpu(cmd->pdu_len);
189132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
190132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->version) {
191fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	case FIO_SERVER_VER:
192132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
193132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
194132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: bad server cmd version %d\n", cmd->version);
195132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
196132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
197132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
198b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	if (cmd->pdu_len > FIO_SERVER_MAX_FRAGMENT_PDU) {
199132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: command payload too large: %u\n", cmd->pdu_len);
200132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
201132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
202132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
203132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
204132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
205132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
206a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
207a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands
208a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
209e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk)
210132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
211dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe	struct fio_net_cmd cmd, *tmp, *cmdret = NULL;
212a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	size_t cmd_size = 0, pdu_offset = 0;
213fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
214a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret, first = 1;
215a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	void *pdu = NULL;
216132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
217a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	do {
218a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, &cmd, sizeof(cmd));
219a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
220a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
221132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
222a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* We have a command, verify it and swap if need be */
223a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = verify_convert_cmd(&cmd);
224a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
225a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
226132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
2270b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (first) {
2280b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			/* if this is text, add room for \0 at the end */
2290b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			cmd_size = sizeof(cmd) + cmd.pdu_len + 1;
2300b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			assert(!cmdret);
2310b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		} else
232a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			cmd_size += cmd.pdu_len;
233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
234dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		if (cmd_size / 1024 > FIO_SERVER_MAX_CMD_MB * 1024) {
235dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			log_err("fio: cmd+pdu too large (%llu)\n", (unsigned long long) cmd_size);
236dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			ret = 1;
237dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			break;
238dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		}
239dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe
240dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		tmp = realloc(cmdret, cmd_size);
241dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		if (!tmp) {
242dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			log_err("fio: server failed allocating cmd\n");
243dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			ret = 1;
244dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			break;
245dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		}
246dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		cmdret = tmp;
247132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
248a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (first)
249a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			memcpy(cmdret, &cmd, sizeof(cmd));
25067f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		else if (cmdret->opcode != cmd.opcode) {
25167f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			log_err("fio: fragment opcode mismatch (%d != %d)\n",
25267f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe					cmdret->opcode, cmd.opcode);
25367f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			ret = 1;
25467f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			break;
25567f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		}
256a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
257a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (!cmd.pdu_len)
258a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
259a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
260a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* There's payload, get it */
261a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu = (void *) cmdret->payload + pdu_offset;
262a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, pdu, cmd.pdu_len);
263a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
264a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
265a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
266a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* Verify payload crc */
26725dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe		crc = fio_crc16(pdu, cmd.pdu_len);
268a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (crc != cmd.pdu_crc16) {
269a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("fio: server bad crc on payload ");
270a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc);
271a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			ret = 1;
272a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
273a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		}
274a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
275a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu_offset += cmd.pdu_len;
276817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe		if (!first)
277817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe			cmdret->pdu_len += cmd.pdu_len;
278a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		first = 0;
279a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	} while (cmd.flags & FIO_NET_CMD_F_MORE);
280132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
281a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	if (ret) {
282a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		free(cmdret);
283a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = NULL;
2840b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	} else if (cmdret) {
2850b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* zero-terminate text input */
286084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe		if (cmdret->pdu_len) {
287084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe			if (cmdret->opcode == FIO_NET_CMD_TEXT) {
288084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe				struct cmd_text_pdu *pdu = (struct cmd_text_pdu *) cmdret->payload;
289084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe				char *buf = (char *) pdu->buf;
2900b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
2913c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe				buf[pdu->buf_len] = '\0';
292084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe			} else if (cmdret->opcode == FIO_NET_CMD_JOB) {
29346bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe				struct cmd_job_pdu *pdu = (struct cmd_job_pdu *) cmdret->payload;
29446bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe				char *buf = (char *) pdu->buf;
29546bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe				int len = le32_to_cpu(pdu->buf_len);
296084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
29746bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe				buf[len] = '\0';
298084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe			}
2990b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		}
300084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
3010b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* frag flag is internal */
302a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret->flags &= ~FIO_NET_CMD_F_MORE;
3030b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	}
304a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
305a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	return cmdret;
306132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
307132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
30840c605169e60d32fc321a2f9f465e76cba745489Jens Axboestatic void add_reply(uint64_t tag, struct flist_head *list)
30940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
310a572bbfb6a85b03e459a56616c2e95e497e005e8Aaron Carroll	struct fio_net_cmd_reply *reply;
31140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
312a572bbfb6a85b03e459a56616c2e95e497e005e8Aaron Carroll	reply = (struct fio_net_cmd_reply *) (uintptr_t) tag;
31340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	flist_add_tail(&reply->list, list);
31440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
31540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
31640c605169e60d32fc321a2f9f465e76cba745489Jens Axboestatic uint64_t alloc_reply(uint64_t tag, uint16_t opcode)
31740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
31840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	struct fio_net_cmd_reply *reply;
31940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
32040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	reply = calloc(1, sizeof(*reply));
32140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	INIT_FLIST_HEAD(&reply->list);
32240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	gettimeofday(&reply->tv, NULL);
32340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	reply->saved_tag = tag;
32440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	reply->opcode = opcode;
32540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
32640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return (uintptr_t) reply;
32740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
32840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
32940c605169e60d32fc321a2f9f465e76cba745489Jens Axboestatic void free_reply(uint64_t tag)
33040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
331a572bbfb6a85b03e459a56616c2e95e497e005e8Aaron Carroll	struct fio_net_cmd_reply *reply;
33240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
333a572bbfb6a85b03e459a56616c2e95e497e005e8Aaron Carroll	reply = (struct fio_net_cmd_reply *) (uintptr_t) tag;
33440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	free(reply);
33540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
33640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
33753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboevoid fio_net_cmd_crc_pdu(struct fio_net_cmd *cmd, const void *pdu)
338132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
339132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	uint32_t pdu_len;
340132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
34125dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	cmd->cmd_crc16 = __cpu_to_le16(fio_crc16(cmd, FIO_NET_CMD_CRC_SZ));
342132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
343132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	pdu_len = le32_to_cpu(cmd->pdu_len);
3441b42725f06f8906b9b99381da3490484f59df28aJens Axboe	cmd->pdu_crc16 = __cpu_to_le16(fio_crc16(pdu, pdu_len));
3451b42725f06f8906b9b99381da3490484f59df28aJens Axboe}
3461b42725f06f8906b9b99381da3490484f59df28aJens Axboe
3471b42725f06f8906b9b99381da3490484f59df28aJens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd)
3481b42725f06f8906b9b99381da3490484f59df28aJens Axboe{
3491b42725f06f8906b9b99381da3490484f59df28aJens Axboe	fio_net_cmd_crc_pdu(cmd, cmd->payload);
350132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
351132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
352af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
35340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		     uint64_t *tagptr, struct flist_head *list)
354794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{
3557f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	struct fio_net_cmd *cmd = NULL;
3567f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	size_t this_len, cur_len = 0;
35740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint64_t tag;
358794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	int ret;
359794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
36040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	if (list) {
36140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		assert(tagptr);
36240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		tag = *tagptr = alloc_reply(*tagptr, opcode);
36340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	} else
36440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		tag = tagptr ? *tagptr : 0;
36540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
366794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	do {
367794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		this_len = size;
368b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		if (this_len > FIO_SERVER_MAX_FRAGMENT_PDU)
369b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe			this_len = FIO_SERVER_MAX_FRAGMENT_PDU;
370794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
3717f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		if (!cmd || cur_len < sizeof(*cmd) + this_len) {
3727f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			if (cmd)
3737f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe				free(cmd);
3747f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
3757f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cur_len = sizeof(*cmd) + this_len;
3767f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cmd = malloc(cur_len);
3777f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		}
378794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
379af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		fio_init_net_cmd(cmd, opcode, buf, this_len, tag);
380794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
381794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len < size)
382ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe			cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE);
383794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
384794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_net_cmd_crc(cmd);
385794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
386794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
387794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		size -= this_len;
388794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		buf += this_len;
389794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	} while (!ret && size);
390794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
39140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	if (list) {
39240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		if (ret)
39340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			free_reply(tag);
39440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		else
39540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			add_reply(tag, list);
39640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	}
39740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
3987f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	if (cmd)
3997f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		free(cmd);
4007f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
401794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	return ret;
402794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe}
403794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
40489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag)
405132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
406178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe	struct fio_net_cmd cmd;
407132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
408af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_init_net_cmd(&cmd, opcode, NULL, 0, tag);
409132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fio_net_cmd_crc(&cmd);
410132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
411132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return fio_send_data(sk, &cmd, sizeof(cmd));
412132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
413132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
41489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe/*
41589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * If 'list' is non-NULL, then allocate and store the sent command for
41689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * later verification.
41789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe */
41889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag,
41989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			    struct flist_head *list)
42089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
42189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret;
42289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
42340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	if (list)
42440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		tag = alloc_reply(tag, opcode);
42589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
42640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	ret = fio_net_send_simple_stack_cmd(sk, opcode, tag);
42789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (ret) {
42840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		if (list)
42940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			free_reply(tag);
43040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
43189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return ret;
43289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
43389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
43440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	if (list)
43540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		add_reply(tag, list);
43640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
43789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return 0;
43889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
43989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
440122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboeint fio_net_send_quit(int sk)
441437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{
44246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: sending quit\n");
443122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
4448c95307bd5f72720460ee4a46519b9a1b474e7cdJens Axboe	return fio_net_send_simple_cmd(sk, FIO_NET_CMD_QUIT, 0, NULL);
445437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe}
446437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe
447f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboestatic int fio_net_send_ack(int sk, struct fio_net_cmd *cmd, int error,
448f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe			    int signal)
449132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
45011e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	struct cmd_end_pdu epdu;
451f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	uint64_t tag = 0;
452122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
453f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	if (cmd)
454f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		tag = cmd->tag;
455122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
456122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	epdu.error = __cpu_to_le32(error);
457122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	epdu.signal = __cpu_to_le32(signal);
45840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return fio_net_send_cmd(sk, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), &tag, NULL);
459f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe}
460f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
461f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboeint fio_net_send_stop(int sk, int error, int signal)
462f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe{
463f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	dprint(FD_NET, "server: sending stop (%d, %d)\n", error, signal);
464f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	return fio_net_send_ack(sk, NULL, error, signal);
465122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
466122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
467122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_add_fork_item(pid_t pid, struct flist_head *list)
468122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
469122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct fio_fork_item *ffi;
470122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
471122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi = malloc(sizeof(*ffi));
472122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->exitval = 0;
473122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->signal = 0;
474122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->exited = 0;
475122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->pid = pid;
476122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_add_tail(&ffi->list, list);
477122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
478122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
4796348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic void fio_server_add_conn_pid(struct flist_head *conn_list, pid_t pid)
480122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
481a7533dbd90c821b2db04aa53168a4d0f4259ea6dJens Axboe	dprint(FD_NET, "server: forked off connection job (pid=%u)\n", (int) pid);
4826348b5dee54f24f2e78872948653942336f4c14eJens Axboe	fio_server_add_fork_item(pid, conn_list);
483122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
484122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
4856348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic void fio_server_add_job_pid(struct flist_head *job_list, pid_t pid)
486122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
487a7533dbd90c821b2db04aa53168a4d0f4259ea6dJens Axboe	dprint(FD_NET, "server: forked off job job (pid=%u)\n", (int) pid);
4886348b5dee54f24f2e78872948653942336f4c14eJens Axboe	fio_server_add_fork_item(pid, job_list);
489122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
490122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
491122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_check_fork_item(struct fio_fork_item *ffi)
492122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
493122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int ret, status;
494122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
495122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ret = waitpid(ffi->pid, &status, WNOHANG);
496122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	if (ret < 0) {
497122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (errno == ECHILD) {
498a7533dbd90c821b2db04aa53168a4d0f4259ea6dJens Axboe			log_err("fio: connection pid %u disappeared\n", (int) ffi->pid);
499122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
500122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		} else
501122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: waitpid: %s\n", strerror(errno));
502122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	} else if (ret == ffi->pid) {
503122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (WIFSIGNALED(status)) {
504122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->signal = WTERMSIG(status);
505122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
506122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
507122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (WIFEXITED(status)) {
508122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (WEXITSTATUS(status))
509122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				ffi->exitval = WEXITSTATUS(status);
510122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
511122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
512122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
513122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
514122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
515122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_fork_item_done(struct fio_fork_item *ffi)
516122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
517a7533dbd90c821b2db04aa53168a4d0f4259ea6dJens Axboe	dprint(FD_NET, "pid %u exited, sig=%u, exitval=%d\n", (int) ffi->pid, ffi->signal, ffi->exitval);
518122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
519122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	/*
520122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	 * Fold STOP and QUIT...
521122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	 */
522122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_stop(server_fd, ffi->exitval, ffi->signal);
523122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_quit(server_fd);
524122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_del(&ffi->list);
525122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	free(ffi);
526122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
527122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
528541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboestatic void fio_server_check_fork_items(struct flist_head *list)
529122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
530122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct flist_head *entry, *tmp;
531122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct fio_fork_item *ffi;
532122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
533122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_for_each_safe(entry, tmp, list) {
534122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		ffi = flist_entry(entry, struct fio_fork_item, list);
535122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
536122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_check_fork_item(ffi);
537122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
538122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (ffi->exited)
539122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			fio_server_fork_item_done(ffi);
540122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
541122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
542122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
5436348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic void fio_server_check_jobs(struct flist_head *job_list)
544122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
5456348b5dee54f24f2e78872948653942336f4c14eJens Axboe	fio_server_check_fork_items(job_list);
546122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
547122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
5486348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic void fio_server_check_conns(struct flist_head *conn_list)
549122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
5506348b5dee54f24f2e78872948653942336f4c14eJens Axboe	fio_server_check_fork_items(conn_list);
551122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
552122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
5536348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic int handle_run_cmd(struct flist_head *job_list, struct fio_net_cmd *cmd)
554122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
555122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid_t pid;
556a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret;
557132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
558122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	set_genesis_time();
55911e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
560122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid = fork();
561122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	if (pid) {
5626348b5dee54f24f2e78872948653942336f4c14eJens Axboe		fio_server_add_job_pid(job_list, pid);
563122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		return 0;
564122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
56511e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
566122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ret = fio_backend();
5672bb3f0a7e00d3d62943b0bcc8119ab81c157c349Jens Axboe	free_threads_shm();
568122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	_exit(ret);
56981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
57081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
571b9d2f30a214ebd274340f888739be250838d63c2Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd)
572b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe{
57346bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	struct cmd_job_pdu *pdu = (struct cmd_job_pdu *) cmd->payload;
57446bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	void *buf = pdu->buf;
575b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct cmd_start_pdu spdu;
576b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
57746bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->buf_len = le32_to_cpu(pdu->buf_len);
57846bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->client_type = le32_to_cpu(pdu->client_type);
57946bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe
58046bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	if (parse_jobs_ini(buf, 1, 0, pdu->client_type)) {
581122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_net_send_quit(server_fd);
582b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		return -1;
583b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	}
584b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
585b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
586108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe	spdu.stat_outputs = cpu_to_le32(stat_number);
58740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), NULL, NULL);
588b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return 0;
589b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe}
590b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
59181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd)
59281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
593fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	void *pdu = cmd->payload;
594fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_single_line_pdu *cslp;
595fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_line_pdu *clp;
596fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	unsigned long offset;
597b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct cmd_start_pdu spdu;
598fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	char **argv;
599b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	int i;
60081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
601fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp = pdu;
602fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp->lines = le16_to_cpu(clp->lines);
60346bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	clp->client_type = le16_to_cpu(clp->client_type);
604fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	argv = malloc(clp->lines * sizeof(char *));
605fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	offset = sizeof(*clp);
60681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
607fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	dprint(FD_NET, "server: %d command line args\n", clp->lines);
60839e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe
609fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	for (i = 0; i < clp->lines; i++) {
610fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp = pdu + offset;
611fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		argv[i] = (char *) cslp->text;
612fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
613fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		offset += sizeof(*cslp) + le16_to_cpu(cslp->len);
61439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe		dprint(FD_NET, "server: %d: %s\n", i, argv[i]);
61539e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	}
61681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
61746bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	if (parse_cmd_line(clp->lines, argv, clp->client_type)) {
618122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_net_send_quit(server_fd);
619fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		free(argv);
62081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
621e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
62281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
623fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	free(argv);
624fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
625b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
6261e5324e723116a5faf9da686993cc79c14d62d4bJens Axboe	spdu.stat_outputs = cpu_to_le32(stat_number);
62740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), NULL, NULL);
628b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return 0;
629132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
630132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
631c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd)
632c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{
6333989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_client_probe_pdu *pdu = (struct cmd_client_probe_pdu *) cmd->payload;
6343989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_probe_reply_pdu probe;
63540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint64_t tag = cmd->tag;
636c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
63789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: sending probe reply\n");
63889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
639c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	memset(&probe, 0, sizeof(probe));
640c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	gethostname((char *) probe.hostname, sizeof(probe.hostname));
6410dcebdf4a70ef0d8144b8fcba763ae87e7fc74b5Jens Axboe#ifdef CONFIG_BIG_ENDIAN
6426eb2479194603184f393057ea10326643edc7169Jens Axboe	probe.bigendian = 1;
6436eb2479194603184f393057ea10326643edc7169Jens Axboe#endif
644750db473abdebdbf3ddfc8556a9873762c9db8f4Jens Axboe	strncpy((char *) probe.fio_version, fio_version_string, sizeof(probe.fio_version));
645c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
646cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.os	= FIO_OS;
647cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.arch	= FIO_ARCH;
64838fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe	probe.bpp	= sizeof(void *);
649d31e26d0a575f91db96bda4d76b36fe38996d5f8Jens Axboe	probe.cpus	= __cpu_to_le32(cpus_online());
6503989b14303458519192f4ace8caf091d587f5e6eJens Axboe
6513989b14303458519192f4ace8caf091d587f5e6eJens Axboe	/*
6523989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 * If the client supports compression and we do too, then enable it
6533989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 */
6543989b14303458519192f4ace8caf091d587f5e6eJens Axboe	if (has_zlib && le64_to_cpu(pdu->flags) & FIO_PROBE_FLAG_ZLIB) {
6553989b14303458519192f4ace8caf091d587f5e6eJens Axboe		probe.flags = __cpu_to_le64(FIO_PROBE_FLAG_ZLIB);
6563989b14303458519192f4ace8caf091d587f5e6eJens Axboe		use_zlib = 1;
6573989b14303458519192f4ace8caf091d587f5e6eJens Axboe	} else {
6583989b14303458519192f4ace8caf091d587f5e6eJens Axboe		probe.flags = 0;
6593989b14303458519192f4ace8caf091d587f5e6eJens Axboe		use_zlib = 0;
6603989b14303458519192f4ace8caf091d587f5e6eJens Axboe	}
66138fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe
66240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), &tag, NULL);
663af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe}
664af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
665af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic int handle_send_eta_cmd(struct fio_net_cmd *cmd)
666af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{
667af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct jobs_eta *je;
668af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	size_t size;
66940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint64_t tag = cmd->tag;
670af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	int i;
671af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
672b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	if (!thread_number)
673b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe		return 0;
674b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe
675b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	size = sizeof(*je) + thread_number * sizeof(char) + 1;
6767f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	je = malloc(size);
6777f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	memset(je, 0, size);
678af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
679af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	if (!calc_thread_status(je, 1)) {
680af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		free(je);
681af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return 0;
682af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
683af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
684af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "server sending status\n");
685af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
686af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_running		= cpu_to_le32(je->nr_running);
687af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_ramp		= cpu_to_le32(je->nr_ramp);
688af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_pending		= cpu_to_le32(je->nr_pending);
689714e85f340194409d0abcf643cd2f154a7380a74Jens Axboe	je->nr_setting_up	= cpu_to_le32(je->nr_setting_up);
690af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->files_open		= cpu_to_le32(je->files_open);
691af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
692298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
6933e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->m_rate[i]	= cpu_to_le32(je->m_rate[i]);
6943e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->t_rate[i]	= cpu_to_le32(je->t_rate[i]);
6953e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->m_iops[i]	= cpu_to_le32(je->m_iops[i]);
6963e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->t_iops[i]	= cpu_to_le32(je->t_iops[i]);
69716725bb04ffc0d58af3f1fe91cd58b31961a74f7Jens Axboe		je->rate[i]	= cpu_to_le32(je->rate[i]);
69816725bb04ffc0d58af3f1fe91cd58b31961a74f7Jens Axboe		je->iops[i]	= cpu_to_le32(je->iops[i]);
699af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
700af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
701c1970b907ff0cb819de5607bc120d8acb527eb98Jens Axboe	je->elapsed_sec		= cpu_to_le64(je->elapsed_sec);
702af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->eta_sec		= cpu_to_le64(je->eta_sec);
7038c621fb2aa4b99c8a8b6b62435d713ab39b52c62Jens Axboe	je->nr_threads		= cpu_to_le32(je->nr_threads);
704b7f05eb03c84bdc1259d1bb1c348328b16164430Jens Axboe	je->is_pow2		= cpu_to_le32(je->is_pow2);
705ed2c0a120c9ebc7770fe14ef47f9d302c11cdfdaJens Axboe	je->unit_base		= cpu_to_le32(je->unit_base);
706af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
70740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, &tag, NULL);
708af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	free(je);
709af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	return 0;
710c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe}
711c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
71240c605169e60d32fc321a2f9f465e76cba745489Jens Axboestatic int send_update_job_reply(int fd, uint64_t __tag, int error)
71340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
71440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint64_t tag = __tag;
71540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint32_t pdu_error;
71640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
71740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	pdu_error = __cpu_to_le32(error);
71840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return fio_net_send_cmd(fd, FIO_NET_CMD_UPDATE_JOB, &pdu_error, sizeof(pdu_error), &tag, NULL);
71940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
72040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
721f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboestatic int handle_update_job_cmd(struct fio_net_cmd *cmd)
722f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe{
723f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	struct cmd_add_job_pdu *pdu = (struct cmd_add_job_pdu *) cmd->payload;
724f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	struct thread_data *td;
725f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	uint32_t tnumber;
726f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
727f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	tnumber = le32_to_cpu(pdu->thread_number);
728f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
729f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	dprint(FD_NET, "server: updating options for job %u\n", tnumber);
730f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
73130ffacbf5fe598195318c6e6a1dcd0456eba400bJens Axboe	if (!tnumber || tnumber > thread_number) {
73240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		send_update_job_reply(server_fd, cmd->tag, ENODEV);
733f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		return 0;
734f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	}
735f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
73630ffacbf5fe598195318c6e6a1dcd0456eba400bJens Axboe	td = &threads[tnumber - 1];
737f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	convert_thread_options_to_cpu(&td->o, &pdu->top);
73840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	send_update_job_reply(server_fd, cmd->tag, 0);
739f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	return 0;
740f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe}
741f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
7426348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic int handle_command(struct flist_head *job_list, struct fio_net_cmd *cmd)
743132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
744132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret;
745132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
7464b91ee8fd12c72bd76ce9f5ff9116626b48566a0Jens Axboe	dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%llx\n",
7474b91ee8fd12c72bd76ce9f5ff9116626b48566a0Jens Axboe			fio_server_op(cmd->opcode), cmd->pdu_len,
7484b91ee8fd12c72bd76ce9f5ff9116626b48566a0Jens Axboe			(unsigned long long) cmd->tag);
74946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
750132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->opcode) {
751132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_QUIT:
752cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe		fio_terminate_threads(TERMINATE_ALL);
753c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
754d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe	case FIO_NET_CMD_EXIT:
755132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		exit_backend = 1;
756c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
757132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_JOB:
7580b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		ret = handle_job_cmd(cmd);
759132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
76081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	case FIO_NET_CMD_JOBLINE:
76181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		ret = handle_jobline_cmd(cmd);
76281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		break;
763c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	case FIO_NET_CMD_PROBE:
764c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		ret = handle_probe_cmd(cmd);
765c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		break;
766af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	case FIO_NET_CMD_SEND_ETA:
767af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		ret = handle_send_eta_cmd(cmd);
768af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		break;
769b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	case FIO_NET_CMD_RUN:
7706348b5dee54f24f2e78872948653942336f4c14eJens Axboe		ret = handle_run_cmd(job_list, cmd);
771b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		break;
772f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	case FIO_NET_CMD_UPDATE_JOB:
773f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		ret = handle_update_job_cmd(cmd);
774f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		break;
775132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
7763c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe		log_err("fio: unknown opcode: %s\n", fio_server_op(cmd->opcode));
777132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = 1;
778132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
779132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
780132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
781132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
782132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
783122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic int handle_connection(int sk)
784132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
785132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd *cmd = NULL;
7866348b5dee54f24f2e78872948653942336f4c14eJens Axboe	FLIST_HEAD(job_list);
787132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
788132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
789122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	reset_fio_state();
790122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	server_fd = sk;
791122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
792132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* read forever */
793132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	while (!exit_backend) {
794e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		struct pollfd pfd = {
795e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.fd	= sk,
796e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.events	= POLLIN,
797e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		};
798e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
799e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		ret = 0;
800e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		do {
801541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			int timeout = 1000;
802541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
803541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			if (!flist_empty(&job_list))
804541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe				timeout = 100;
8053c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe
806541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			ret = poll(&pfd, 1, timeout);
807e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (ret < 0) {
808e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				if (errno == EINTR)
809e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe					break;
810e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
811e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
81219c65179fad3e0a32a450401ba7d312169627fddJens Axboe			} else if (!ret) {
8136348b5dee54f24f2e78872948653942336f4c14eJens Axboe				fio_server_check_jobs(&job_list);
814e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				continue;
81519c65179fad3e0a32a450401ba7d312169627fddJens Axboe			}
816e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
817e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & POLLIN)
818e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
819e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & (POLLERR|POLLHUP)) {
820e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				ret = 1;
821e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
822e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			}
82319c65179fad3e0a32a450401ba7d312169627fddJens Axboe		} while (!exit_backend);
824e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
8256348b5dee54f24f2e78872948653942336f4c14eJens Axboe		fio_server_check_jobs(&job_list);
826122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
827e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		if (ret < 0)
828e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			break;
829e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
830e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		cmd = fio_net_recv_cmd(sk);
831132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (!cmd) {
832c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe			ret = -1;
833132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
834132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		}
835132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
8366348b5dee54f24f2e78872948653942336f4c14eJens Axboe		ret = handle_command(&job_list, cmd);
837132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
838132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
839132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
840132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
841c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe		cmd = NULL;
842132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
843132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
844132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd)
845132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
846132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
847122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	close(sk);
848122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	_exit(ret);
849cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
850cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
85150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
85250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
853bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	struct sockaddr_in addr;
854479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe	struct sockaddr_in6 addr6;
855479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe	socklen_t len = use_ipv6 ? sizeof(addr6) : sizeof(addr);
856009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
8574a851614cfdbebddeb78de04ac89a39d26f25459Jens Axboe	int ret = 0, sk, exitval = 0;
8586348b5dee54f24f2e78872948653942336f4c14eJens Axboe	FLIST_HEAD(conn_list);
85950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
86060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server enter accept loop\n");
86160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
8624a851614cfdbebddeb78de04ac89a39d26f25459Jens Axboe	fio_set_fd_nonblocking(listen_sk, "server");
863009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
864122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	while (!exit_backend) {
865479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		const char *from;
866479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		char buf[64];
867122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pid_t pid;
868009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
869122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pfd.fd = listen_sk;
870122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pfd.events = POLLIN;
871122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		do {
872541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			int timeout = 1000;
873541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
874541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			if (!flist_empty(&conn_list))
875541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe				timeout = 100;
876541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
877541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			ret = poll(&pfd, 1, timeout);
878122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (ret < 0) {
879122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				if (errno == EINTR)
880122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe					break;
881122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
882122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				break;
883122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			} else if (!ret) {
8846348b5dee54f24f2e78872948653942336f4c14eJens Axboe				fio_server_check_conns(&conn_list);
885122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				continue;
886122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			}
887009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
888122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (pfd.revents & POLLIN)
889122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				break;
890122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		} while (!exit_backend);
89150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
8926348b5dee54f24f2e78872948653942336f4c14eJens Axboe		fio_server_check_conns(&conn_list);
89346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
894122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (exit_backend || ret < 0)
895122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			break;
896122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
897479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		if (use_ipv6)
898479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			sk = accept(listen_sk, (struct sockaddr *) &addr6, &len);
899479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		else
900479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			sk = accept(listen_sk, (struct sockaddr *) &addr, &len);
901479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe
902122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (sk < 0) {
903122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: accept: %s\n", strerror(errno));
904122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			return -1;
905122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
90637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
907479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		if (use_ipv6)
908479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			from = inet_ntop(AF_INET6, (struct sockaddr *) &addr6.sin6_addr, buf, sizeof(buf));
909479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		else
910479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			from = inet_ntop(AF_INET, (struct sockaddr *) &addr.sin_addr, buf, sizeof(buf));
911479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe
912479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		dprint(FD_NET, "server: connect from %s\n", from);
91350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
914122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pid = fork();
915122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (pid) {
916122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			close(sk);
9176348b5dee54f24f2e78872948653942336f4c14eJens Axboe			fio_server_add_conn_pid(&conn_list, pid);
918122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			continue;
919122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
9205c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
921122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		/* exits */
922122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		handle_connection(sk);
923122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
9245c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
925132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return exitval;
92650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
92750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
928084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboeint fio_server_text_output(int level, const char *buf, size_t len)
92937db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
930084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	struct cmd_text_pdu *pdu;
931084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	unsigned int tlen;
932084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	struct timeval tv;
933084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
934084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	if (server_fd == -1)
935084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe		return log_local_buf(buf, len);
936084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
937084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	tlen = sizeof(*pdu) + len;
938084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu = malloc(tlen);
939084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
940084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->level	= __cpu_to_le32(level);
941084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->buf_len	= __cpu_to_le32(len);
942084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
943084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	gettimeofday(&tv, NULL);
944084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_sec	= __cpu_to_le64(tv.tv_sec);
945084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_usec	= __cpu_to_le64(tv.tv_usec);
946337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe
947084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	memcpy(pdu->buf, buf, len);
948084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
94940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, pdu, tlen, NULL, NULL);
950084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	free(pdu);
951084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	return len;
952142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe}
953142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
954a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src)
955a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
956a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->max_val	= cpu_to_le64(src->max_val);
957a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->min_val	= cpu_to_le64(src->min_val);
958a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->samples	= cpu_to_le64(src->samples);
959802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
960802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	/*
961802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 * Encode to IEEE 754 for network transfer
962802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 */
963802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->mean.u.i	= __cpu_to_le64(fio_double_to_uint64(src->mean.u.f));
964802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->S.u.i	= __cpu_to_le64(fio_double_to_uint64(src->S.u.f));
965a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
966a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
967a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
968a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
969a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i;
970a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
971298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
972a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_run[i]		= cpu_to_le64(src->max_run[i]);
973a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_run[i]		= cpu_to_le64(src->min_run[i]);
974a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_bw[i]		= cpu_to_le64(src->max_bw[i]);
975a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_bw[i]		= cpu_to_le64(src->min_bw[i]);
976a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_kb[i]		= cpu_to_le64(src->io_kb[i]);
977a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->agg[i]		= cpu_to_le64(src->agg[i]);
978a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
979a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
980a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->kb_base	= cpu_to_le32(src->kb_base);
981ad705bcb7e79a7cdb9891db17b4c40b13b6c30c3Steven Noonan	dst->unit_base	= cpu_to_le32(src->unit_base);
982a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= cpu_to_le32(src->groupid);
983771e58befea806d2d881953050c4e65329eee382Jens Axboe	dst->unified_rw_rep	= cpu_to_le32(src->unified_rw_rep);
984a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
985a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
986a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
987a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats
988a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload.
989a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
990a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
991a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
992a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct cmd_ts_pdu p;
993a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i, j;
994a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
99560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending end stats\n");
99660efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
997317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe	memset(&p, 0, sizeof(p));
998317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe
9994e59d0f3a3ff569bddb31fe6927a9faf204ae9bfJens Axboe	strncpy(p.ts.name, ts->name, FIO_JOBNAME_SIZE - 1);
10004e59d0f3a3ff569bddb31fe6927a9faf204ae9bfJens Axboe	strncpy(p.ts.verror, ts->verror, FIO_VERROR_SIZE - 1);
10014e59d0f3a3ff569bddb31fe6927a9faf204ae9bfJens Axboe	strncpy(p.ts.description, ts->description, FIO_JOBDESC_SIZE - 1);
1002a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
10032f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.error		= cpu_to_le32(ts->error);
10042f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.thread_number	= cpu_to_le32(ts->thread_number);
10052f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.groupid		= cpu_to_le32(ts->groupid);
10062f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.pid		= cpu_to_le32(ts->pid);
10072f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.members		= cpu_to_le32(ts->members);
1008771e58befea806d2d881953050c4e65329eee382Jens Axboe	p.ts.unified_rw_rep	= cpu_to_le32(ts->unified_rw_rep);
1009a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1010298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1011a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]);
1012a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]);
1013a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]);
1014a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]);
1015a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1016a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1017a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.usr_time		= cpu_to_le64(ts->usr_time);
1018a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.sys_time		= cpu_to_le64(ts->sys_time);
1019a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.ctx		= cpu_to_le64(ts->ctx);
1020a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.minf		= cpu_to_le64(ts->minf);
1021a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.majf		= cpu_to_le64(ts->majf);
1022a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.clat_percentiles	= cpu_to_le64(ts->clat_percentiles);
1023802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
1024802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
1025cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *src = &ts->percentile_list[i];
1026cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *dst = &p.ts.percentile_list[i];
1027802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
1028cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		dst->u.i = __cpu_to_le64(fio_double_to_uint64(src->u.f));
1029802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	}
1030a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1031a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
1032a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_map[i]	= cpu_to_le32(ts->io_u_map[i]);
1033a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_submit[i]	= cpu_to_le32(ts->io_u_submit[i]);
1034a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_complete[i]	= cpu_to_le32(ts->io_u_complete[i]);
1035a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1036a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1037a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
1038a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_u[i]	= cpu_to_le32(ts->io_u_lat_u[i]);
1039a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_m[i]	= cpu_to_le32(ts->io_u_lat_m[i]);
1040a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1041a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1042298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++)
1043a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
1044a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]);
1045a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
104678799debc66f717469e751b3b9eb5dfa48cc547bJens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1047a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.total_io_u[i]	= cpu_to_le64(ts->total_io_u[i]);
104893eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe		p.ts.short_io_u[i]	= cpu_to_le64(ts->short_io_u[i]);
1049a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1050a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
105193eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe	p.ts.total_submit	= cpu_to_le64(ts->total_submit);
1052a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_complete	= cpu_to_le64(ts->total_complete);
1053a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1054298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1055a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_bytes[i]	= cpu_to_le64(ts->io_bytes[i]);
1056a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.runtime[i]		= cpu_to_le64(ts->runtime[i]);
1057a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1058a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1059a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_run_time	= cpu_to_le64(ts->total_run_time);
1060a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.continue_on_error	= cpu_to_le16(ts->continue_on_error);
1061a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_err_count	= cpu_to_le64(ts->total_err_count);
1062ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.first_error	= cpu_to_le32(ts->first_error);
1063ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.kb_base		= cpu_to_le32(ts->kb_base);
1064ad705bcb7e79a7cdb9891db17b4c40b13b6c30c3Steven Noonan	p.ts.unit_base		= cpu_to_le32(ts->unit_base);
1065a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
10663e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	p.ts.latency_depth	= cpu_to_le32(ts->latency_depth);
10673e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	p.ts.latency_target	= cpu_to_le64(ts->latency_target);
10683e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	p.ts.latency_window	= cpu_to_le64(ts->latency_window);
10693e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	p.ts.latency_percentile.u.i = __cpu_to_le64(fio_double_to_uint64(ts->latency_percentile.u.f));
10703e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe
1071a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&p.rs, rs);
1072a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
107340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), NULL, NULL);
1074a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
1075a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1076a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs)
1077a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
1078a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct group_run_stats gs;
1079a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
108060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending group run stats\n");
108160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
1082a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&gs, rs);
108340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), NULL, NULL);
1084cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe}
1085cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
1086d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src)
1087d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
1088d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
1089d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1090d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
1091d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ios[i]	= cpu_to_le32(src->ios[i]);
1092d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->merges[i]	= cpu_to_le32(src->merges[i]);
1093d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
1094d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
1095d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
1096d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1097d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->io_ticks		= cpu_to_le32(src->io_ticks);
1098d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
1099d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->slavecount		= cpu_to_le32(src->slavecount);
1100d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->max_util.u.i	= __cpu_to_le64(fio_double_to_uint64(src->max_util.u.f));
1101d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1102d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1103d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src)
1104d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
1105d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
1106d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
110759140421267ef809b00da12881b8d899ecefbb10Jens Axboe	dst->name[FIO_DU_NAME_SZ - 1] = '\0';
110859140421267ef809b00da12881b8d899ecefbb10Jens Axboe	strncpy((char *) dst->name, (char *) src->name, FIO_DU_NAME_SZ - 1);
1109d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1110d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
1111a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe		dst->s.ios[i]		= cpu_to_le32(src->s.ios[i]);
1112a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe		dst->s.merges[i]	= cpu_to_le32(src->s.merges[i]);
1113a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe		dst->s.sectors[i]	= cpu_to_le64(src->s.sectors[i]);
1114a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe		dst->s.ticks[i]		= cpu_to_le32(src->s.ticks[i]);
1115d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
1116d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1117a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe	dst->s.io_ticks		= cpu_to_le32(src->s.io_ticks);
1118a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe	dst->s.time_in_queue	= cpu_to_le32(src->s.time_in_queue);
1119a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe	dst->s.msec		= cpu_to_le64(src->s.msec);
1120d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1121d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1122d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboevoid fio_server_send_du(void)
1123d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
1124d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct disk_util *du;
1125d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct flist_head *entry;
1126d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct cmd_du_pdu pdu;
1127d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1128d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dprint(FD_NET, "server: sending disk_util %d\n", !flist_empty(&disk_list));
1129d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
11300766d92e06a119eea489e74d80d5840813559752Jens Axboe	memset(&pdu, 0, sizeof(pdu));
11310766d92e06a119eea489e74d80d5840813559752Jens Axboe
1132d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	flist_for_each(entry, &disk_list) {
1133d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		du = flist_entry(entry, struct disk_util, list);
1134d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1135d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_dus(&pdu.dus, &du->dus);
1136d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_agg(&pdu.agg, &du->agg);
1137d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
113840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), NULL, NULL);
1139d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
1140d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1141d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
114253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe/*
114353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe * Send a command with a separate PDU, not inlined in the command
114453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe */
114553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboestatic int fio_send_cmd_ext_pdu(int sk, uint16_t opcode, const void *buf,
114653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe				off_t size, uint64_t tag, uint32_t flags)
114753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe{
114853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	struct fio_net_cmd cmd;
114953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	struct iovec iov[2];
115053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
11519f24726136cc2e94359da7e0dbfd3b6955a71bc5Jens Axboe	iov[0].iov_base = (void *) &cmd;
115253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[0].iov_len = sizeof(cmd);
115353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[1].iov_base = (void *) buf;
115453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[1].iov_len = size;
115553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
115653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	__fio_init_net_cmd(&cmd, opcode, size, tag);
115753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	cmd.flags = __cpu_to_le32(flags);
115853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	fio_net_cmd_crc_pdu(&cmd, buf);
115953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
11608c95307bd5f72720460ee4a46519b9a1b474e7cdJens Axboe	return fio_sendv_data(sk, iov, 2);
116153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe}
116253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
11633989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic int fio_send_iolog_gz(struct cmd_iolog_pdu *pdu, struct io_log *log)
11641b42725f06f8906b9b99381da3490484f59df28aJens Axboe{
11653989b14303458519192f4ace8caf091d587f5e6eJens Axboe	int ret = 0;
11663989b14303458519192f4ace8caf091d587f5e6eJens Axboe#ifdef CONFIG_ZLIB
11671b42725f06f8906b9b99381da3490484f59df28aJens Axboe	z_stream stream;
11681b42725f06f8906b9b99381da3490484f59df28aJens Axboe	void *out_pdu;
11691b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11701b42725f06f8906b9b99381da3490484f59df28aJens Axboe	/*
11711b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * Dirty - since the log is potentially huge, compress it into
11721b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * FIO_SERVER_MAX_FRAGMENT_PDU chunks and let the receiving
11731b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * side defragment it.
11741b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 */
11751b42725f06f8906b9b99381da3490484f59df28aJens Axboe	out_pdu = malloc(FIO_SERVER_MAX_FRAGMENT_PDU);
11761b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11771b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zalloc = Z_NULL;
11781b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zfree = Z_NULL;
11791b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.opaque = Z_NULL;
11801b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11811b42725f06f8906b9b99381da3490484f59df28aJens Axboe	if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
118253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		ret = 1;
118353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		goto err;
11841b42725f06f8906b9b99381da3490484f59df28aJens Axboe	}
11851b42725f06f8906b9b99381da3490484f59df28aJens Axboe
1186f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	stream.next_in = (void *) log->log;
1187f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	stream.avail_in = log->nr_samples * sizeof(struct io_sample);
11881b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11891b42725f06f8906b9b99381da3490484f59df28aJens Axboe	do {
119053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		unsigned int this_len, flags = 0;
119153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		int ret;
11921b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11931b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.avail_out = FIO_SERVER_MAX_FRAGMENT_PDU;
11941b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.next_out = out_pdu;
11953c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		ret = deflate(&stream, Z_FINISH);
11963c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		/* may be Z_OK, or Z_STREAM_END */
11973c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		if (ret < 0)
11983c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe			goto err_zlib;
11991b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12001b42725f06f8906b9b99381da3490484f59df28aJens Axboe		this_len = FIO_SERVER_MAX_FRAGMENT_PDU - stream.avail_out;
12011b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12021b42725f06f8906b9b99381da3490484f59df28aJens Axboe		if (stream.avail_in)
120353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe			flags = FIO_NET_CMD_F_MORE;
12041b42725f06f8906b9b99381da3490484f59df28aJens Axboe
120553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG,
120653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe					   out_pdu, this_len, 0, flags);
120753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		if (ret)
120853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe			goto err_zlib;
12091b42725f06f8906b9b99381da3490484f59df28aJens Axboe	} while (stream.avail_in);
12101b42725f06f8906b9b99381da3490484f59df28aJens Axboe
121153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboeerr_zlib:
12121b42725f06f8906b9b99381da3490484f59df28aJens Axboe	deflateEnd(&stream);
121353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboeerr:
121453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	free(out_pdu);
12153989b14303458519192f4ace8caf091d587f5e6eJens Axboe#endif
121653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	return ret;
12171b42725f06f8906b9b99381da3490484f59df28aJens Axboe}
12181b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12193989b14303458519192f4ace8caf091d587f5e6eJens Axboeint fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
12203989b14303458519192f4ace8caf091d587f5e6eJens Axboe{
12213989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_iolog_pdu pdu;
12223989b14303458519192f4ace8caf091d587f5e6eJens Axboe	int i, ret = 0;
12233989b14303458519192f4ace8caf091d587f5e6eJens Axboe
12243989b14303458519192f4ace8caf091d587f5e6eJens Axboe	pdu.thread_number = cpu_to_le32(td->thread_number);
12253989b14303458519192f4ace8caf091d587f5e6eJens Axboe	pdu.nr_samples = __cpu_to_le32(log->nr_samples);
12263989b14303458519192f4ace8caf091d587f5e6eJens Axboe	pdu.log_type = cpu_to_le32(log->log_type);
12273989b14303458519192f4ace8caf091d587f5e6eJens Axboe	pdu.compressed = cpu_to_le32(use_zlib);
12289bdb9265ed6cfd95fc217a9030b188a5a345cc89Jens Axboe
12299bdb9265ed6cfd95fc217a9030b188a5a345cc89Jens Axboe	strncpy((char *) pdu.name, name, FIO_NET_NAME_MAX);
12309bdb9265ed6cfd95fc217a9030b188a5a345cc89Jens Axboe	pdu.name[FIO_NET_NAME_MAX - 1] = '\0';
12313989b14303458519192f4ace8caf091d587f5e6eJens Axboe
12323989b14303458519192f4ace8caf091d587f5e6eJens Axboe	for (i = 0; i < log->nr_samples; i++) {
12333989b14303458519192f4ace8caf091d587f5e6eJens Axboe		struct io_sample *s = &log->log[i];
12343989b14303458519192f4ace8caf091d587f5e6eJens Axboe
12353989b14303458519192f4ace8caf091d587f5e6eJens Axboe		s->time	= cpu_to_le64(s->time);
12363989b14303458519192f4ace8caf091d587f5e6eJens Axboe		s->val	= cpu_to_le64(s->val);
12373989b14303458519192f4ace8caf091d587f5e6eJens Axboe		s->ddir	= cpu_to_le32(s->ddir);
12383989b14303458519192f4ace8caf091d587f5e6eJens Axboe		s->bs	= cpu_to_le32(s->bs);
12393989b14303458519192f4ace8caf091d587f5e6eJens Axboe	}
12403989b14303458519192f4ace8caf091d587f5e6eJens Axboe
12413989b14303458519192f4ace8caf091d587f5e6eJens Axboe	/*
12423989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 * Send header first, it's not compressed.
12433989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 */
12443989b14303458519192f4ace8caf091d587f5e6eJens Axboe	ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, &pdu,
12453989b14303458519192f4ace8caf091d587f5e6eJens Axboe					sizeof(pdu), 0, FIO_NET_CMD_F_MORE);
12463989b14303458519192f4ace8caf091d587f5e6eJens Axboe	if (ret)
12473989b14303458519192f4ace8caf091d587f5e6eJens Axboe		return ret;
12483989b14303458519192f4ace8caf091d587f5e6eJens Axboe
12493989b14303458519192f4ace8caf091d587f5e6eJens Axboe	/*
12503989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 * Now send actual log, compress if we can, otherwise just plain
12513989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 */
12523989b14303458519192f4ace8caf091d587f5e6eJens Axboe	if (use_zlib)
12533989b14303458519192f4ace8caf091d587f5e6eJens Axboe		return fio_send_iolog_gz(&pdu, log);
12543989b14303458519192f4ace8caf091d587f5e6eJens Axboe
12553989b14303458519192f4ace8caf091d587f5e6eJens Axboe	return fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, log->log,
12563989b14303458519192f4ace8caf091d587f5e6eJens Axboe			log->nr_samples * sizeof(struct io_sample), 0, 0);
12573989b14303458519192f4ace8caf091d587f5e6eJens Axboe}
12583989b14303458519192f4ace8caf091d587f5e6eJens Axboe
12592f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboevoid fio_server_send_add_job(struct thread_data *td)
1260807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe{
1261807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe	struct cmd_add_job_pdu pdu;
1262807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1263731e30a2551315c609c23ac107377b63c02d51faJens Axboe	memset(&pdu, 0, sizeof(pdu));
12642f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.thread_number = cpu_to_le32(td->thread_number);
12652f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.groupid = cpu_to_le32(td->groupid);
12662f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	convert_thread_options_to_net(&pdu.top, &td->o);
1267807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
126840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ADD_JOB, &pdu, sizeof(pdu), NULL, NULL);
1269807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe}
1270807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1271122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboevoid fio_server_send_start(struct thread_data *td)
1272122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
1273122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	assert(server_fd != -1);
1274122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
1275122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_SERVER_START, 0, NULL);
1276122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
1277122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
127887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_ip(void)
127981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
1280811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	struct sockaddr *addr;
128167bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	socklen_t socklen;
128217e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe	char buf[80];
128317e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe	const char *str;
128487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, opt;
128581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1286811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6)
1287811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET6, SOCK_STREAM, 0);
1288811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	else
1289811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET, SOCK_STREAM, 0);
1290811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
129181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (sk < 0) {
129281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
129381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
129481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
129581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
129681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	opt = 1;
12971f81991ed356dd7257aef2c715ba9a24d9af93a5Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt)) < 0) {
129881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
1299b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
130081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
130181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
130281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT
13036eb2479194603184f393057ea10326643edc7169Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
130481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
1305b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
130681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
130781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
130881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif
130981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1310811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6) {
131117e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		const void *src = &saddr_in6.sin6_addr;
131217e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe
1313811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in6;
1314811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in6);
1315811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in6.sin6_family = AF_INET6;
131617e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		str = inet_ntop(AF_INET6, src, buf, sizeof(buf));
1317811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else {
131817e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		const void *src = &saddr_in.sin_addr;
131917e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe
1320811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in;
1321811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in);
1322811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in.sin_family = AF_INET;
132317e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		str = inet_ntop(AF_INET, src, buf, sizeof(buf));
1324811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	}
132581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1326811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (bind(sk, addr, socklen) < 0) {
132781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
132817e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		log_info("fio: failed with IPv%c %s\n", use_ipv6 ? '6' : '4', str);
1329b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
133081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
133181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
133281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
133387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
133487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
133587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
133687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_sock(void)
133787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
133887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un addr;
133967bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	socklen_t len;
134087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode_t mode;
134187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
134287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
134387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = socket(AF_UNIX, SOCK_STREAM, 0);
134487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0) {
134587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: socket: %s\n", strerror(errno));
134687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
134787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
134887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
134987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode = umask(000);
135087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
135187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	memset(&addr, 0, sizeof(addr));
135287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	addr.sun_family = AF_UNIX;
1353a48fddbcb33991f9b2d1be1fa0a5e5cfb9ea9faeJens Axboe	strncpy(addr.sun_path, bind_sock, sizeof(addr.sun_path) - 1);
135487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
135587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	len = sizeof(addr.sun_family) + strlen(bind_sock) + 1;
135687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
135787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (bind(sk, (struct sockaddr *) &addr, len) < 0) {
135887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: bind: %s\n", strerror(errno));
1359b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
136087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
136187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
136287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
136387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	umask(mode);
136487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
136587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
136687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
136787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_connection(void)
136887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
1369bebe639808147d587bbe776566d390b9ff98773fJens Axboe	char bind_str[128];
137087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
137187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
137287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
137387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
137487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!bind_sock)
137587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_ip();
137687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	else
137787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_sock();
137887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
137987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
138087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return sk;
138187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1382afdcad2315c22200d594a29885053d7671881ebbJens Axboe	memset(bind_str, 0, sizeof(bind_str));
1383afdcad2315c22200d594a29885053d7671881ebbJens Axboe
1384811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (!bind_sock) {
1385811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		char *p, port[16];
1386811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		const void *src;
1387811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		int af;
1388811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1389811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (use_ipv6) {
1390811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET6;
1391811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in6.sin6_addr;
1392811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		} else {
1393811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET;
1394811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in.sin_addr;
1395811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		}
1396811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1397811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		p = (char *) inet_ntop(af, src, bind_str, sizeof(bind_str));
1398811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1399811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sprintf(port, ",%u", fio_net_port);
1400811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (p)
1401811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcat(p, port);
1402811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		else
1403afdcad2315c22200d594a29885053d7671881ebbJens Axboe			strncpy(bind_str, port, sizeof(bind_str) - 1);
1404811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else
1405afdcad2315c22200d594a29885053d7671881ebbJens Axboe		strncpy(bind_str, bind_sock, sizeof(bind_str) - 1);
1406bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1407bebe639808147d587bbe776566d390b9ff98773fJens Axboe	log_info("fio: server listening on %s\n", bind_str);
1408bebe639808147d587bbe776566d390b9ff98773fJens Axboe
140989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (listen(sk, 0) < 0) {
141081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
14112fd973c9e7bbbf88d52a55ee1daa2568d4bf5f41Jens Axboe		close(sk);
141281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
141381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
141481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
141587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
141687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
141787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
14183aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboeint fio_server_parse_host(const char *host, int ipv6, struct in_addr *inp,
14193ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			  struct in6_addr *inp6)
14203ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
14213ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe{
14223ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	int ret = 0;
14233ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
14243aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboe	if (ipv6)
14253ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = inet_pton(AF_INET6, host, inp6);
14263ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	else
14273ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = inet_pton(AF_INET, host, inp);
14283ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
14293ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	if (ret != 1) {
1430479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		struct addrinfo hints, *res;
1431479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe
1432479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		memset(&hints, 0, sizeof(hints));
14333aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboe		hints.ai_family = ipv6 ? AF_INET6 : AF_INET;
1434479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		hints.ai_socktype = SOCK_STREAM;
14353ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
1436479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		ret = getaddrinfo(host, NULL, &hints, &res);
1437479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		if (ret) {
1438479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			log_err("fio: failed to resolve <%s> (%s)\n", host,
1439479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe					gai_strerror(ret));
14403caf43e3a1567affb2e35f4577d7c51c606187f1Jens Axboe			return 1;
14413ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		}
14423ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
14433aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboe		if (ipv6)
1444479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			memcpy(inp6, &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr, sizeof(*inp6));
1445479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		else
1446479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			memcpy(inp, &((struct sockaddr_in *) res->ai_addr)->sin_addr, sizeof(*inp));
1447479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe
14483ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = 1;
1449479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		freeaddrinfo(res);
14503ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	}
14513ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
14523ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	return !(ret == 1);
14533ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe}
14543ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
1455660a2bfb0858f94633f9e567b81968981541f079Jens Axboe/*
1456660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Parse a host/ip/port string. Reads from 'str'.
1457660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
1458660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Outputs:
1459660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
1460660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv4:
1461660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp is the destination.
1462660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv6:
1463660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp6 is the dest, and *ipv6 is 1.
1464660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For local domain sockets:
1465660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the filename, *is_sock is 1.
1466660a2bfb0858f94633f9e567b81968981541f079Jens Axboe */
1467bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_server_parse_string(const char *str, char **ptr, int *is_sock,
1468811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    int *port, struct in_addr *inp,
1469811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    struct in6_addr *inp6, int *ipv6)
1470bebe639808147d587bbe776566d390b9ff98773fJens Axboe{
147176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	const char *host = str;
147276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	char *portp;
14733ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	int lport = 0;
147476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
1475bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*ptr = NULL;
1476bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*is_sock = 0;
14776d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	*port = fio_net_port;
1478811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	*ipv6 = 0;
1479bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1480bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!strncmp(str, "sock:", 5)) {
1481bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*ptr = strdup(str + 5);
1482bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*is_sock = 1;
148376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
148476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
148576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
148676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
148776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
148876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * Is it ip:<ip or host>:port
148976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
149076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strncmp(host, "ip:", 3))
149176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 3;
149276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip4:", 4))
149376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
149476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip6:", 4)) {
149576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
149676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*ipv6 = 1;
149776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	} else if (host[0] == ':') {
149876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* String is :port */
149976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host++;
150076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		lport = atoi(host);
150176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!lport || lport > 65535) {
15024e0a8fa2593006505b7f4e18931a201d221b49e9Jens Axboe			log_err("fio: bad server port %u\n", lport);
150376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			return 1;
150476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
150576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* no hostname given, we are done */
150676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
150776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
150876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
150976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
151076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
1511b96b90c383b25f4d0a002f672c3ff3dc02fdbf7bJens Axboe	 * If no port seen yet, check if there's a last ',' at the end
151276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
151376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!lport) {
151476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		portp = strchr(host, ',');
151576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (portp) {
151676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			*portp = '\0';
151776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			portp++;
151876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			lport = atoi(portp);
1519bebe639808147d587bbe776566d390b9ff98773fJens Axboe			if (!lport || lport > 65535) {
15204e0a8fa2593006505b7f4e18931a201d221b49e9Jens Axboe				log_err("fio: bad server port %u\n", lport);
1521bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
1522bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
1523bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
152476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
1525bebe639808147d587bbe776566d390b9ff98773fJens Axboe
152676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (lport)
152776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
1528bebe639808147d587bbe776566d390b9ff98773fJens Axboe
152976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strlen(host))
153076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
1531bebe639808147d587bbe776566d390b9ff98773fJens Axboe
153276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	*ptr = strdup(host);
1533811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
15343aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboe	if (fio_server_parse_host(*ptr, *ipv6, inp, inp6)) {
15353ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		free(*ptr);
15363ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		*ptr = NULL;
15373ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		return 1;
1538bebe639808147d587bbe776566d390b9ff98773fJens Axboe	}
1539bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1540bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (*port == 0)
1541bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*port = fio_net_port;
1542bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1543bebe639808147d587bbe776566d390b9ff98773fJens Axboe	return 0;
1544bebe639808147d587bbe776566d390b9ff98773fJens Axboe}
1545bebe639808147d587bbe776566d390b9ff98773fJens Axboe
154687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe/*
154787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Server arg should be one of:
154887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
154987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * sock:/path/to/socket
155087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *   ip:1.2.3.4
155187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *      1.2.3.4
155287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
155387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Where sock uses unix domain sockets, and ip binds the server to
155487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * a specific interface. If no arguments are given to the server, it
155587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * uses IP and binds to 0.0.0.0.
155687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
155787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe */
155887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_handle_server_arg(void)
155987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
15606d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	int port = fio_net_port;
1561a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe	int is_sock, ret = 0;
1562bebe639808147d587bbe776566d390b9ff98773fJens Axboe
156387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
156487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
156587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!fio_server_arg)
1566a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe		goto out;
156787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
15684e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock,
1569811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&port, &saddr_in.sin_addr,
1570811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&saddr_in6.sin6_addr, &use_ipv6);
15714e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
15724e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	if (!is_sock && bind_sock) {
15734e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		free(bind_sock);
15744e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		bind_sock = NULL;
15754e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	}
15764e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
1577a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboeout:
15786d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	fio_net_port = port;
15796d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	saddr_in.sin_port = htons(port);
1580811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	saddr_in6.sin6_port = htons(port);
15814e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	return ret;
158287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
158387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
158443cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboestatic void sig_int(int sig)
158543cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe{
158643cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	if (bind_sock)
158743cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe		unlink(bind_sock);
158843cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe}
158943cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe
159043cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboestatic void set_sig_handlers(void)
159143cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe{
159243cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	struct sigaction act;
159343cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe
159443cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	memset(&act, 0, sizeof(act));
159543cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	act.sa_handler = sig_int;
159643cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	act.sa_flags = SA_RESTART;
159743cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	sigaction(SIGINT, &act, NULL);
159843cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe}
159943cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe
160087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_server(void)
160187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
160287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, ret;
160387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
160487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
160587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
160687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_handle_server_arg())
160787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
160887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
160987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = fio_init_server_connection();
161087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
161187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
161281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
161343cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	set_sig_handlers();
161443cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe
161581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	ret = accept_loop(sk);
161687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
161781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	close(sk);
161887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
161987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_server_arg) {
162087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		free(fio_server_arg);
162187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fio_server_arg = NULL;
162287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
1623bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (bind_sock)
1624bebe639808147d587bbe776566d390b9ff98773fJens Axboe		free(bind_sock);
162587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
162681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
162781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
162881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
16297b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboevoid fio_server_got_signal(int signal)
16309abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{
16317b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	if (signal == SIGPIPE)
16327b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		server_fd = -1;
16337b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	else {
16347b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		log_info("\nfio: terminating on signal %d\n", signal);
16357b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		exit_backend = 1;
16367b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	}
16379abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe}
16389abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe
163913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int check_existing_pidfile(const char *pidfile)
164013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe{
164113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	struct stat sb;
164213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	char buf[16];
164313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid_t pid;
164413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	FILE *f;
164513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
164613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (stat(pidfile, &sb))
164713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
164813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
164913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	f = fopen(pidfile, "r");
165013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (!f)
165113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
165213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1653bfc3b17986fb80aeb5a6ea962bb38fc1509d60a8Jens Axboe	if (fread(buf, sb.st_size, 1, f) <= 0) {
165413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		fclose(f);
165513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
165613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
165713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(f);
165813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
165913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid = atoi(buf);
166013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (kill(pid, SIGCONT) < 0)
1661ea5aa1be68de71f9f02eb3d6f4db726adcafb40aJens Axboe		return errno != ESRCH;
166213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
166313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 1;
166413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe}
166513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
166613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int write_pid(pid_t pid, const char *pidfile)
1667402668f3e05259bfc135fc097136428feda01006Jens Axboe{
1668402668f3e05259bfc135fc097136428feda01006Jens Axboe	FILE *fpid;
1669402668f3e05259bfc135fc097136428feda01006Jens Axboe
1670402668f3e05259bfc135fc097136428feda01006Jens Axboe	fpid = fopen(pidfile, "w");
1671402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!fpid) {
1672402668f3e05259bfc135fc097136428feda01006Jens Axboe		log_err("fio: failed opening pid file %s\n", pidfile);
167313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
1674402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1675402668f3e05259bfc135fc097136428feda01006Jens Axboe
1676402668f3e05259bfc135fc097136428feda01006Jens Axboe	fprintf(fpid, "%u\n", (unsigned int) pid);
167713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(fpid);
167813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 0;
1679402668f3e05259bfc135fc097136428feda01006Jens Axboe}
1680402668f3e05259bfc135fc097136428feda01006Jens Axboe
1681402668f3e05259bfc135fc097136428feda01006Jens Axboe/*
1682402668f3e05259bfc135fc097136428feda01006Jens Axboe * If pidfile is specified, background us.
1683402668f3e05259bfc135fc097136428feda01006Jens Axboe */
1684402668f3e05259bfc135fc097136428feda01006Jens Axboeint fio_start_server(char *pidfile)
1685e46d809110bd4ad2980ca64931b683673444454bJens Axboe{
1686e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid_t pid;
1687402668f3e05259bfc135fc097136428feda01006Jens Axboe	int ret;
1688e46d809110bd4ad2980ca64931b683673444454bJens Axboe
168993bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#if defined(WIN32)
1690905c78b90f92bab91555313f7b4bd83d18246139Jens Axboe	WSADATA wsd;
16913c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe	WSAStartup(MAKEWORD(2, 2), &wsd);
169293bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#endif
169393bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran
1694402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!pidfile)
1695e46d809110bd4ad2980ca64931b683673444454bJens Axboe		return fio_server();
1696e46d809110bd4ad2980ca64931b683673444454bJens Axboe
169713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (check_existing_pidfile(pidfile)) {
169813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: pidfile %s exists and server appears alive\n",
169913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe								pidfile);
1700b8ba87ac231c3facccb1e5b0e8b1b88dd162f8f3Jens Axboe		free(pidfile);
170113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return -1;
170213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
170313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1704e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid = fork();
1705e46d809110bd4ad2980ca64931b683673444454bJens Axboe	if (pid < 0) {
170613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: failed server fork: %s", strerror(errno));
1707402668f3e05259bfc135fc097136428feda01006Jens Axboe		free(pidfile);
1708c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
1709402668f3e05259bfc135fc097136428feda01006Jens Axboe	} else if (pid) {
171013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		int ret = write_pid(pid, pidfile);
171113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1712b8ba87ac231c3facccb1e5b0e8b1b88dd162f8f3Jens Axboe		free(pidfile);
171313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		exit(ret);
1714402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1715e46d809110bd4ad2980ca64931b683673444454bJens Axboe
1716e46d809110bd4ad2980ca64931b683673444454bJens Axboe	setsid();
171713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
171813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	log_syslog = 1;
1719e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDIN_FILENO);
1720e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDOUT_FILENO);
1721e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDERR_FILENO);
1722e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_out = NULL;
1723e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_err = NULL;
1724402668f3e05259bfc135fc097136428feda01006Jens Axboe
1725402668f3e05259bfc135fc097136428feda01006Jens Axboe	ret = fio_server();
1726402668f3e05259bfc135fc097136428feda01006Jens Axboe
1727402668f3e05259bfc135fc097136428feda01006Jens Axboe	closelog();
1728402668f3e05259bfc135fc097136428feda01006Jens Axboe	unlink(pidfile);
1729402668f3e05259bfc135fc097136428feda01006Jens Axboe	free(pidfile);
1730402668f3e05259bfc135fc097136428feda01006Jens Axboe	return ret;
1731e46d809110bd4ad2980ca64931b683673444454bJens Axboe}
173287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1733bebe639808147d587bbe776566d390b9ff98773fJens Axboevoid fio_server_set_arg(const char *arg)
173487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
173587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_server_arg = strdup(arg);
173687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
1737