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"
27de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe#include "verify.h"
28de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe#include "smalloc.h"
2989cf1480594858ad4e02499834c04fe48ff0a89dJens Axboe
305adc2447a8d52322981da4cd364a560bbd9d8351Stephen M. Cameronint fio_net_port = FIO_NET_PORT;
3150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
32009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0;
33009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
3446c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1;
3587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *fio_server_arg;
3687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *bind_sock;
3787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic struct sockaddr_in saddr_in;
38811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic struct sockaddr_in6 saddr_in6;
39811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic int use_ipv6;
403989b14303458519192f4ace8caf091d587f5e6eJens Axboe#ifdef CONFIG_ZLIB
413989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic unsigned int has_zlib = 1;
423989b14303458519192f4ace8caf091d587f5e6eJens Axboe#else
433989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic unsigned int has_zlib = 0;
443989b14303458519192f4ace8caf091d587f5e6eJens Axboe#endif
453989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic unsigned int use_zlib;
46de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboestatic char me[128];
4737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
48122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestruct fio_fork_item {
49122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct flist_head list;
50122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int exitval;
51122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int signal;
52122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int exited;
53122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid_t pid;
54122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe};
55122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
56de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboestruct cmd_reply {
57de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	struct fio_mutex lock;
58de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	void *data;
59de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	size_t size;
60de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	int error;
61de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe};
62de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
6389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic const char *fio_server_ops[FIO_NET_CMD_NR] = {
6489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"",
6589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"QUIT",
6689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"EXIT",
6789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOB",
6889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOBLINE",
6989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TEXT",
7089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TS",
7189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"GS",
7289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"SEND_ETA",
7389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"ETA",
7489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"PROBE",
7589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"START",
76d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"STOP",
77d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"DISK_UTIL",
78b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	"SERVER_START",
79807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe	"ADD_JOB",
80de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	"RUN",
81de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	"IOLOG",
82de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	"UPDATE_JOB",
83de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	"LOAD_FILE",
84de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	"VTRIGGER",
85de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	"SENDFILE",
8689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe};
8789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
8889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeconst char *fio_server_op(unsigned int op)
8989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
9089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	static char buf[32];
9189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
9289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (op < FIO_NET_CMD_NR)
9389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_server_ops[op];
9489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
9589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	sprintf(buf, "UNKNOWN/%d", op);
9689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return buf;
9789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
9889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
995235f62680ba4be74d56805eb54c3af4de28e556Jens Axboestatic ssize_t iov_total_len(const struct iovec *iov, int count)
100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
1015235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	ssize_t ret = 0;
102794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
1035235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	while (count--) {
1045235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe		ret += iov->iov_len;
1055235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe		iov++;
1065235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	}
1075235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1085235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	return ret;
1095235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe}
110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1115235f62680ba4be74d56805eb54c3af4de28e556Jens Axboestatic int fio_sendv_data(int sk, struct iovec *iov, int count)
1125235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe{
1135235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	ssize_t total_len = iov_total_len(iov, count);
1145235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	ssize_t ret;
1155235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1165235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	do {
1175235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe		ret = writev(sk, iov, count);
118132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
1195235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			total_len -= ret;
1205235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			if (!total_len)
121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
1225235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1235235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			while (ret) {
1245235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				if (ret >= iov->iov_len) {
1255235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe					ret -= iov->iov_len;
1265235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe					iov++;
1275235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe					continue;
1285235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				}
1295235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				iov->iov_base += ret;
1305235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				iov->iov_len -= ret;
1315235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				ret = 0;
1325235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			}
133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
136132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
1377b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
1387b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
139132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
140132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1415235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	if (!total_len)
142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
143132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1448b4e61b27203fff2cc68a967ae3f6cacaca71e43Jens Axboe	if (errno)
1458b4e61b27203fff2cc68a967ae3f6cacaca71e43Jens Axboe		return -errno;
1468b4e61b27203fff2cc68a967ae3f6cacaca71e43Jens Axboe
147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 1;
148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1505235f62680ba4be74d56805eb54c3af4de28e556Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len)
1515235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe{
1525235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	struct iovec iov = { .iov_base = (void *) p, .iov_len = len };
1535235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1545235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_FRAGMENT_PDU);
1555235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1565235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	return fio_sendv_data(sk, &iov, 1);
1575235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe}
1585235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
159132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len)
160132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
161132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
162132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = recv(sk, p, len, MSG_WAITALL);
163132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
164132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
165132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
166132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
167132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
168132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
169132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
170132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
171132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
172132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
173132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
1747b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
1757b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
176132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
177132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
178132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
179132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
180132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
181132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return -1;
182132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
183132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
184132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd)
185132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
186fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
187132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
188fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16);
189fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16);
190132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
19125dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	crc = fio_crc16(cmd, FIO_NET_CMD_CRC_SZ);
192fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != cmd->cmd_crc16) {
193132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on command (got %x, wanted %x)\n",
194fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				cmd->cmd_crc16, crc);
195132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
196132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
197132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
198132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->version	= le16_to_cpu(cmd->version);
199132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->opcode	= le16_to_cpu(cmd->opcode);
200132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->flags	= le32_to_cpu(cmd->flags);
201af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	cmd->tag	= le64_to_cpu(cmd->tag);
202132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->pdu_len	= le32_to_cpu(cmd->pdu_len);
203132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
204132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->version) {
205fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	case FIO_SERVER_VER:
206132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
207132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
208132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: bad server cmd version %d\n", cmd->version);
209132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
210132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
211132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
212b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	if (cmd->pdu_len > FIO_SERVER_MAX_FRAGMENT_PDU) {
213132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: command payload too large: %u\n", cmd->pdu_len);
214132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
215132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
216132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
217132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
218132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
219132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
220a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
221a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands
222a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
223e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk)
224132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
225dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe	struct fio_net_cmd cmd, *tmp, *cmdret = NULL;
226a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	size_t cmd_size = 0, pdu_offset = 0;
227fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
228a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret, first = 1;
229a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	void *pdu = NULL;
230132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
231a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	do {
232a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, &cmd, sizeof(cmd));
233a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
234a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
236a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* We have a command, verify it and swap if need be */
237a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = verify_convert_cmd(&cmd);
238a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
239a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
240132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
2410b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (first) {
2420b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			/* if this is text, add room for \0 at the end */
2430b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			cmd_size = sizeof(cmd) + cmd.pdu_len + 1;
2440b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			assert(!cmdret);
2450b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		} else
246a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			cmd_size += cmd.pdu_len;
247132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
248dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		if (cmd_size / 1024 > FIO_SERVER_MAX_CMD_MB * 1024) {
249dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			log_err("fio: cmd+pdu too large (%llu)\n", (unsigned long long) cmd_size);
250dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			ret = 1;
251dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			break;
252dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		}
253dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe
254dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		tmp = realloc(cmdret, cmd_size);
255dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		if (!tmp) {
256dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			log_err("fio: server failed allocating cmd\n");
257dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			ret = 1;
258dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe			break;
259dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		}
260dfbf1f6f34dfef111120438d9c4e2f75f20b4578Jens Axboe		cmdret = tmp;
261132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
262a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (first)
263a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			memcpy(cmdret, &cmd, sizeof(cmd));
26467f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		else if (cmdret->opcode != cmd.opcode) {
26567f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			log_err("fio: fragment opcode mismatch (%d != %d)\n",
26667f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe					cmdret->opcode, cmd.opcode);
26767f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			ret = 1;
26867f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			break;
26967f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		}
270a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
271a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (!cmd.pdu_len)
272a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
273a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
274a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* There's payload, get it */
275a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu = (void *) cmdret->payload + pdu_offset;
276a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, pdu, cmd.pdu_len);
277a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
278a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
279a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
280a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* Verify payload crc */
28125dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe		crc = fio_crc16(pdu, cmd.pdu_len);
282a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (crc != cmd.pdu_crc16) {
283a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("fio: server bad crc on payload ");
284a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc);
285a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			ret = 1;
286a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
287a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		}
288a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
289a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu_offset += cmd.pdu_len;
290817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe		if (!first)
291817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe			cmdret->pdu_len += cmd.pdu_len;
292a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		first = 0;
293a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	} while (cmd.flags & FIO_NET_CMD_F_MORE);
294132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
295a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	if (ret) {
296a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		free(cmdret);
297a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = NULL;
2980b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	} else if (cmdret) {
2990b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* zero-terminate text input */
300084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe		if (cmdret->pdu_len) {
301084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe			if (cmdret->opcode == FIO_NET_CMD_TEXT) {
3020f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe				struct cmd_text_pdu *__pdu = (struct cmd_text_pdu *) cmdret->payload;
3030f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe				char *buf = (char *) __pdu->buf;
3040b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
3050f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe				buf[__pdu->buf_len] = '\0';
306084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe			} else if (cmdret->opcode == FIO_NET_CMD_JOB) {
3070f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe				struct cmd_job_pdu *__pdu = (struct cmd_job_pdu *) cmdret->payload;
3080f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe				char *buf = (char *) __pdu->buf;
3090f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe				int len = le32_to_cpu(__pdu->buf_len);
310084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
31146bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe				buf[len] = '\0';
312084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe			}
3130b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		}
314084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
3150b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* frag flag is internal */
316a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret->flags &= ~FIO_NET_CMD_F_MORE;
3170b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	}
318a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
319a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	return cmdret;
320132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
321132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
32240c605169e60d32fc321a2f9f465e76cba745489Jens Axboestatic void add_reply(uint64_t tag, struct flist_head *list)
32340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
324a572bbfb6a85b03e459a56616c2e95e497e005e8Aaron Carroll	struct fio_net_cmd_reply *reply;
32540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
326a572bbfb6a85b03e459a56616c2e95e497e005e8Aaron Carroll	reply = (struct fio_net_cmd_reply *) (uintptr_t) tag;
32740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	flist_add_tail(&reply->list, list);
32840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
32940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
33040c605169e60d32fc321a2f9f465e76cba745489Jens Axboestatic uint64_t alloc_reply(uint64_t tag, uint16_t opcode)
33140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
33240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	struct fio_net_cmd_reply *reply;
33340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
33440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	reply = calloc(1, sizeof(*reply));
33540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	INIT_FLIST_HEAD(&reply->list);
336ea12b2d28a1ff2e78d851ea65f828b7790dcab9cJens Axboe	fio_gettime(&reply->tv, NULL);
33740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	reply->saved_tag = tag;
33840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	reply->opcode = opcode;
33940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
34040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return (uintptr_t) reply;
34140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
34240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
34340c605169e60d32fc321a2f9f465e76cba745489Jens Axboestatic void free_reply(uint64_t tag)
34440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
345a572bbfb6a85b03e459a56616c2e95e497e005e8Aaron Carroll	struct fio_net_cmd_reply *reply;
34640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
347a572bbfb6a85b03e459a56616c2e95e497e005e8Aaron Carroll	reply = (struct fio_net_cmd_reply *) (uintptr_t) tag;
34840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	free(reply);
34940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
35040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
35153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboevoid fio_net_cmd_crc_pdu(struct fio_net_cmd *cmd, const void *pdu)
352132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
353132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	uint32_t pdu_len;
354132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
35525dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	cmd->cmd_crc16 = __cpu_to_le16(fio_crc16(cmd, FIO_NET_CMD_CRC_SZ));
356132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
357132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	pdu_len = le32_to_cpu(cmd->pdu_len);
3581b42725f06f8906b9b99381da3490484f59df28aJens Axboe	cmd->pdu_crc16 = __cpu_to_le16(fio_crc16(pdu, pdu_len));
3591b42725f06f8906b9b99381da3490484f59df28aJens Axboe}
3601b42725f06f8906b9b99381da3490484f59df28aJens Axboe
3611b42725f06f8906b9b99381da3490484f59df28aJens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd)
3621b42725f06f8906b9b99381da3490484f59df28aJens Axboe{
3631b42725f06f8906b9b99381da3490484f59df28aJens Axboe	fio_net_cmd_crc_pdu(cmd, cmd->payload);
364132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
365132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
366af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
36740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		     uint64_t *tagptr, struct flist_head *list)
368794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{
3697f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	struct fio_net_cmd *cmd = NULL;
3707f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	size_t this_len, cur_len = 0;
37140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint64_t tag;
372794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	int ret;
373794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
37440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	if (list) {
37540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		assert(tagptr);
37640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		tag = *tagptr = alloc_reply(*tagptr, opcode);
37740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	} else
37840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		tag = tagptr ? *tagptr : 0;
37940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
380794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	do {
381794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		this_len = size;
382b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		if (this_len > FIO_SERVER_MAX_FRAGMENT_PDU)
383b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe			this_len = FIO_SERVER_MAX_FRAGMENT_PDU;
384794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
3857f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		if (!cmd || cur_len < sizeof(*cmd) + this_len) {
3867f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			if (cmd)
3877f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe				free(cmd);
3887f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
3897f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cur_len = sizeof(*cmd) + this_len;
3907f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cmd = malloc(cur_len);
3917f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		}
392794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
393af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		fio_init_net_cmd(cmd, opcode, buf, this_len, tag);
394794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
395794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len < size)
396ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe			cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE);
397794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
398794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_net_cmd_crc(cmd);
399794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
400794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
401794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		size -= this_len;
402794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		buf += this_len;
403794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	} while (!ret && size);
404794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
40540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	if (list) {
40640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		if (ret)
40740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			free_reply(tag);
40840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		else
40940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			add_reply(tag, list);
41040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	}
41140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
4127f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	if (cmd)
4137f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		free(cmd);
4147f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
415794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	return ret;
416794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe}
417794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
41889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag)
419132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
420178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe	struct fio_net_cmd cmd;
421132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
422af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_init_net_cmd(&cmd, opcode, NULL, 0, tag);
423132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fio_net_cmd_crc(&cmd);
424132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
425132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return fio_send_data(sk, &cmd, sizeof(cmd));
426132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
427132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
42889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe/*
42989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * If 'list' is non-NULL, then allocate and store the sent command for
43089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * later verification.
43189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe */
43289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag,
43389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			    struct flist_head *list)
43489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
43589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret;
43689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
43740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	if (list)
43840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		tag = alloc_reply(tag, opcode);
43989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
44040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	ret = fio_net_send_simple_stack_cmd(sk, opcode, tag);
44189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (ret) {
44240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		if (list)
44340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe			free_reply(tag);
44440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
44589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return ret;
44689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
44789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
44840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	if (list)
44940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		add_reply(tag, list);
45040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
45189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return 0;
45289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
45389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
454122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboeint fio_net_send_quit(int sk)
455437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{
45646c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: sending quit\n");
457122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
4588c95307bd5f72720460ee4a46519b9a1b474e7cdJens Axboe	return fio_net_send_simple_cmd(sk, FIO_NET_CMD_QUIT, 0, NULL);
459437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe}
460437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe
461f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboestatic int fio_net_send_ack(int sk, struct fio_net_cmd *cmd, int error,
462f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe			    int signal)
463132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
46411e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	struct cmd_end_pdu epdu;
465f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	uint64_t tag = 0;
466122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
467f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	if (cmd)
468f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		tag = cmd->tag;
469122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
470122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	epdu.error = __cpu_to_le32(error);
471122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	epdu.signal = __cpu_to_le32(signal);
47240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return fio_net_send_cmd(sk, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), &tag, NULL);
473f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe}
474f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
475f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboeint fio_net_send_stop(int sk, int error, int signal)
476f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe{
477f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	dprint(FD_NET, "server: sending stop (%d, %d)\n", error, signal);
478f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	return fio_net_send_ack(sk, NULL, error, signal);
479122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
480122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
481122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_add_fork_item(pid_t pid, struct flist_head *list)
482122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
483122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct fio_fork_item *ffi;
484122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
485122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi = malloc(sizeof(*ffi));
486122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->exitval = 0;
487122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->signal = 0;
488122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->exited = 0;
489122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->pid = pid;
490122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_add_tail(&ffi->list, list);
491122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
492122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
4936348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic void fio_server_add_conn_pid(struct flist_head *conn_list, pid_t pid)
494122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
495a7533dbd90c821b2db04aa53168a4d0f4259ea6dJens Axboe	dprint(FD_NET, "server: forked off connection job (pid=%u)\n", (int) pid);
4966348b5dee54f24f2e78872948653942336f4c14eJens Axboe	fio_server_add_fork_item(pid, conn_list);
497122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
498122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
4996348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic void fio_server_add_job_pid(struct flist_head *job_list, pid_t pid)
500122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
501a7533dbd90c821b2db04aa53168a4d0f4259ea6dJens Axboe	dprint(FD_NET, "server: forked off job job (pid=%u)\n", (int) pid);
5026348b5dee54f24f2e78872948653942336f4c14eJens Axboe	fio_server_add_fork_item(pid, job_list);
503122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
504122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
505122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_check_fork_item(struct fio_fork_item *ffi)
506122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
507122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int ret, status;
508122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
509122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ret = waitpid(ffi->pid, &status, WNOHANG);
510122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	if (ret < 0) {
511122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (errno == ECHILD) {
512a7533dbd90c821b2db04aa53168a4d0f4259ea6dJens Axboe			log_err("fio: connection pid %u disappeared\n", (int) ffi->pid);
513122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
514122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		} else
515122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: waitpid: %s\n", strerror(errno));
516122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	} else if (ret == ffi->pid) {
517122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (WIFSIGNALED(status)) {
518122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->signal = WTERMSIG(status);
519122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
520122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
521122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (WIFEXITED(status)) {
522122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (WEXITSTATUS(status))
523122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				ffi->exitval = WEXITSTATUS(status);
524122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
525122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
526122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
527122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
528122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
529122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_fork_item_done(struct fio_fork_item *ffi)
530122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
531a7533dbd90c821b2db04aa53168a4d0f4259ea6dJens Axboe	dprint(FD_NET, "pid %u exited, sig=%u, exitval=%d\n", (int) ffi->pid, ffi->signal, ffi->exitval);
532122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
533122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	/*
534122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	 * Fold STOP and QUIT...
535122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	 */
536122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_stop(server_fd, ffi->exitval, ffi->signal);
537122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_quit(server_fd);
538122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_del(&ffi->list);
539122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	free(ffi);
540122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
541122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
542541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboestatic void fio_server_check_fork_items(struct flist_head *list)
543122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
544122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct flist_head *entry, *tmp;
545122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct fio_fork_item *ffi;
546122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
547122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_for_each_safe(entry, tmp, list) {
548122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		ffi = flist_entry(entry, struct fio_fork_item, list);
549122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
550122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_check_fork_item(ffi);
551122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
552122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (ffi->exited)
553122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			fio_server_fork_item_done(ffi);
554122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
555122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
556122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
5576348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic void fio_server_check_jobs(struct flist_head *job_list)
558122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
5596348b5dee54f24f2e78872948653942336f4c14eJens Axboe	fio_server_check_fork_items(job_list);
560122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
561122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
5626348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic void fio_server_check_conns(struct flist_head *conn_list)
563122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
5646348b5dee54f24f2e78872948653942336f4c14eJens Axboe	fio_server_check_fork_items(conn_list);
565122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
566122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
5673589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboestatic int handle_load_file_cmd(struct fio_net_cmd *cmd)
5683589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe{
5693589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	struct cmd_load_file_pdu *pdu = (struct cmd_load_file_pdu *) cmd->payload;
5703589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	void *file_name = pdu->file;
5713589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	struct cmd_start_pdu spdu;
5723589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe
5733589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	dprint(FD_NET, "server: loading local file %s\n", (char *) file_name);
5743589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe
5753589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	pdu->name_len = le16_to_cpu(pdu->name_len);
5763589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	pdu->client_type = le16_to_cpu(pdu->client_type);
5773589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe
5783589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	if (parse_jobs_ini(file_name, 0, 0, pdu->client_type)) {
5793589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe		fio_net_send_quit(server_fd);
5803589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe		return -1;
5813589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	}
5823589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe
5833589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
5843589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	spdu.stat_outputs = cpu_to_le32(stat_number);
5853589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), NULL, NULL);
5863589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	return 0;
5873589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe}
5883589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe
5896348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic int handle_run_cmd(struct flist_head *job_list, struct fio_net_cmd *cmd)
590122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
591122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid_t pid;
592a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret;
593132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
594386626f66c67c16c4ff0032b8ceacd4b8a7eb8faJens Axboe	fio_time_init();
595122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	set_genesis_time();
59611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
597122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid = fork();
598122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	if (pid) {
5996348b5dee54f24f2e78872948653942336f4c14eJens Axboe		fio_server_add_job_pid(job_list, pid);
600122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		return 0;
601122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
60211e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
603122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ret = fio_backend();
6042bb3f0a7e00d3d62943b0bcc8119ab81c157c349Jens Axboe	free_threads_shm();
605122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	_exit(ret);
60681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
60781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
608b9d2f30a214ebd274340f888739be250838d63c2Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd)
609b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe{
61046bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	struct cmd_job_pdu *pdu = (struct cmd_job_pdu *) cmd->payload;
61146bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	void *buf = pdu->buf;
612b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct cmd_start_pdu spdu;
613b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
61446bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->buf_len = le32_to_cpu(pdu->buf_len);
61546bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->client_type = le32_to_cpu(pdu->client_type);
61646bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe
61746bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	if (parse_jobs_ini(buf, 1, 0, pdu->client_type)) {
618122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_net_send_quit(server_fd);
619b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		return -1;
620b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	}
621b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
622b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
623108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe	spdu.stat_outputs = cpu_to_le32(stat_number);
62440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), NULL, NULL);
625b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return 0;
626b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe}
627b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
62881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd)
62981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
630fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	void *pdu = cmd->payload;
631fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_single_line_pdu *cslp;
632fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_line_pdu *clp;
633fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	unsigned long offset;
634b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct cmd_start_pdu spdu;
635fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	char **argv;
636b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	int i;
63781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
638fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp = pdu;
639fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp->lines = le16_to_cpu(clp->lines);
64046bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	clp->client_type = le16_to_cpu(clp->client_type);
641fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	argv = malloc(clp->lines * sizeof(char *));
642fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	offset = sizeof(*clp);
64381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
644fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	dprint(FD_NET, "server: %d command line args\n", clp->lines);
64539e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe
646fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	for (i = 0; i < clp->lines; i++) {
647fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp = pdu + offset;
648fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		argv[i] = (char *) cslp->text;
649fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
650fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		offset += sizeof(*cslp) + le16_to_cpu(cslp->len);
65139e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe		dprint(FD_NET, "server: %d: %s\n", i, argv[i]);
65239e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	}
65381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
65446bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	if (parse_cmd_line(clp->lines, argv, clp->client_type)) {
655122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_net_send_quit(server_fd);
656fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		free(argv);
65781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
658e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
65981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
660fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	free(argv);
661fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
662b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
6631e5324e723116a5faf9da686993cc79c14d62d4bJens Axboe	spdu.stat_outputs = cpu_to_le32(stat_number);
66440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), NULL, NULL);
665b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return 0;
666132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
667132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
668c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd)
669c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{
6703989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_client_probe_pdu *pdu = (struct cmd_client_probe_pdu *) cmd->payload;
6713989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_probe_reply_pdu probe;
67240c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint64_t tag = cmd->tag;
673c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
67489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: sending probe reply\n");
67589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
676de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	strcpy(me, (char *) pdu->server);
677de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
678c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	memset(&probe, 0, sizeof(probe));
679c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	gethostname((char *) probe.hostname, sizeof(probe.hostname));
6800dcebdf4a70ef0d8144b8fcba763ae87e7fc74b5Jens Axboe#ifdef CONFIG_BIG_ENDIAN
6816eb2479194603184f393057ea10326643edc7169Jens Axboe	probe.bigendian = 1;
6826eb2479194603184f393057ea10326643edc7169Jens Axboe#endif
683750db473abdebdbf3ddfc8556a9873762c9db8f4Jens Axboe	strncpy((char *) probe.fio_version, fio_version_string, sizeof(probe.fio_version));
684c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
685cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.os	= FIO_OS;
686cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.arch	= FIO_ARCH;
68738fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe	probe.bpp	= sizeof(void *);
688d31e26d0a575f91db96bda4d76b36fe38996d5f8Jens Axboe	probe.cpus	= __cpu_to_le32(cpus_online());
6893989b14303458519192f4ace8caf091d587f5e6eJens Axboe
6903989b14303458519192f4ace8caf091d587f5e6eJens Axboe	/*
6913989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 * If the client supports compression and we do too, then enable it
6923989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 */
6933989b14303458519192f4ace8caf091d587f5e6eJens Axboe	if (has_zlib && le64_to_cpu(pdu->flags) & FIO_PROBE_FLAG_ZLIB) {
6943989b14303458519192f4ace8caf091d587f5e6eJens Axboe		probe.flags = __cpu_to_le64(FIO_PROBE_FLAG_ZLIB);
6953989b14303458519192f4ace8caf091d587f5e6eJens Axboe		use_zlib = 1;
6963989b14303458519192f4ace8caf091d587f5e6eJens Axboe	} else {
6973989b14303458519192f4ace8caf091d587f5e6eJens Axboe		probe.flags = 0;
6983989b14303458519192f4ace8caf091d587f5e6eJens Axboe		use_zlib = 0;
6993989b14303458519192f4ace8caf091d587f5e6eJens Axboe	}
70038fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe
70140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), &tag, NULL);
702af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe}
703af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
704af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic int handle_send_eta_cmd(struct fio_net_cmd *cmd)
705af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{
706af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct jobs_eta *je;
70740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint64_t tag = cmd->tag;
70861f6cced3dcde7e4a6fc9fca01783ec80ff269a4Jens Axboe	size_t size;
709af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	int i;
710af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
71161f6cced3dcde7e4a6fc9fca01783ec80ff269a4Jens Axboe	je = get_jobs_eta(1, &size);
71261f6cced3dcde7e4a6fc9fca01783ec80ff269a4Jens Axboe	if (!je)
713af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return 0;
714af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
715af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "server sending status\n");
716af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
717af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_running		= cpu_to_le32(je->nr_running);
718af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_ramp		= cpu_to_le32(je->nr_ramp);
719af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_pending		= cpu_to_le32(je->nr_pending);
720714e85f340194409d0abcf643cd2f154a7380a74Jens Axboe	je->nr_setting_up	= cpu_to_le32(je->nr_setting_up);
721af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->files_open		= cpu_to_le32(je->files_open);
722af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
723298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
7243e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->m_rate[i]	= cpu_to_le32(je->m_rate[i]);
7253e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->t_rate[i]	= cpu_to_le32(je->t_rate[i]);
7263e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->m_iops[i]	= cpu_to_le32(je->m_iops[i]);
7273e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->t_iops[i]	= cpu_to_le32(je->t_iops[i]);
72816725bb04ffc0d58af3f1fe91cd58b31961a74f7Jens Axboe		je->rate[i]	= cpu_to_le32(je->rate[i]);
72916725bb04ffc0d58af3f1fe91cd58b31961a74f7Jens Axboe		je->iops[i]	= cpu_to_le32(je->iops[i]);
730af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
731af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
732c1970b907ff0cb819de5607bc120d8acb527eb98Jens Axboe	je->elapsed_sec		= cpu_to_le64(je->elapsed_sec);
733af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->eta_sec		= cpu_to_le64(je->eta_sec);
7348c621fb2aa4b99c8a8b6b62435d713ab39b52c62Jens Axboe	je->nr_threads		= cpu_to_le32(je->nr_threads);
735b7f05eb03c84bdc1259d1bb1c348328b16164430Jens Axboe	je->is_pow2		= cpu_to_le32(je->is_pow2);
736ed2c0a120c9ebc7770fe14ef47f9d302c11cdfdaJens Axboe	je->unit_base		= cpu_to_le32(je->unit_base);
737af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
73840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, &tag, NULL);
739af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	free(je);
740af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	return 0;
741c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe}
742c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
74340c605169e60d32fc321a2f9f465e76cba745489Jens Axboestatic int send_update_job_reply(int fd, uint64_t __tag, int error)
74440c605169e60d32fc321a2f9f465e76cba745489Jens Axboe{
74540c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint64_t tag = __tag;
74640c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	uint32_t pdu_error;
74740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
74840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	pdu_error = __cpu_to_le32(error);
74940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	return fio_net_send_cmd(fd, FIO_NET_CMD_UPDATE_JOB, &pdu_error, sizeof(pdu_error), &tag, NULL);
75040c605169e60d32fc321a2f9f465e76cba745489Jens Axboe}
75140c605169e60d32fc321a2f9f465e76cba745489Jens Axboe
752f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboestatic int handle_update_job_cmd(struct fio_net_cmd *cmd)
753f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe{
754f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	struct cmd_add_job_pdu *pdu = (struct cmd_add_job_pdu *) cmd->payload;
755f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	struct thread_data *td;
756f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	uint32_t tnumber;
757f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
758f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	tnumber = le32_to_cpu(pdu->thread_number);
759f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
760f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	dprint(FD_NET, "server: updating options for job %u\n", tnumber);
761f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
76230ffacbf5fe598195318c6e6a1dcd0456eba400bJens Axboe	if (!tnumber || tnumber > thread_number) {
76340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		send_update_job_reply(server_fd, cmd->tag, ENODEV);
764f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		return 0;
765f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	}
766f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
76730ffacbf5fe598195318c6e6a1dcd0456eba400bJens Axboe	td = &threads[tnumber - 1];
768f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	convert_thread_options_to_cpu(&td->o, &pdu->top);
76940c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	send_update_job_reply(server_fd, cmd->tag, 0);
770f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	return 0;
771f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe}
772f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
773de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboestatic int handle_trigger_cmd(struct fio_net_cmd *cmd)
774de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe{
775de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	struct cmd_vtrigger_pdu *pdu = (struct cmd_vtrigger_pdu *) cmd->payload;
776de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	char *buf = (char *) pdu->cmd;
777de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	struct all_io_list *rep;
778de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	size_t sz;
779de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
780de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	pdu->len = le16_to_cpu(pdu->len);
781de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	buf[pdu->len] = '\0';
782de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
783de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	rep = get_all_io_list(IO_LIST_ALL, &sz);
784de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	if (!rep) {
785de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		struct all_io_list state;
786de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
787de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		state.threads = cpu_to_le64((uint64_t) 0);
788de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		fio_net_send_cmd(server_fd, FIO_NET_CMD_VTRIGGER, &state, sizeof(state), NULL, NULL);
789de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	} else {
790de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		fio_net_send_cmd(server_fd, FIO_NET_CMD_VTRIGGER, rep, sz, NULL, NULL);
791de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		free(rep);
792de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	}
793de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
794de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	exec_trigger(buf);
795de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	return 0;
796de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe}
797de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
7986348b5dee54f24f2e78872948653942336f4c14eJens Axboestatic int handle_command(struct flist_head *job_list, struct fio_net_cmd *cmd)
799132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
800132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret;
801132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
8024b91ee8fd12c72bd76ce9f5ff9116626b48566a0Jens Axboe	dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%llx\n",
8034b91ee8fd12c72bd76ce9f5ff9116626b48566a0Jens Axboe			fio_server_op(cmd->opcode), cmd->pdu_len,
8044b91ee8fd12c72bd76ce9f5ff9116626b48566a0Jens Axboe			(unsigned long long) cmd->tag);
80546c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
806132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->opcode) {
807132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_QUIT:
808cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe		fio_terminate_threads(TERMINATE_ALL);
809c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
810d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe	case FIO_NET_CMD_EXIT:
811132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		exit_backend = 1;
812c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
8133589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe	case FIO_NET_CMD_LOAD_FILE:
8143589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe		ret = handle_load_file_cmd(cmd);
8153589918ceb15ffdc795c963923ce10ac9b9c87d5Jens Axboe		break;
816132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_JOB:
8170b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		ret = handle_job_cmd(cmd);
818132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
81981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	case FIO_NET_CMD_JOBLINE:
82081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		ret = handle_jobline_cmd(cmd);
82181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		break;
822c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	case FIO_NET_CMD_PROBE:
823c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		ret = handle_probe_cmd(cmd);
824c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		break;
825af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	case FIO_NET_CMD_SEND_ETA:
826af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		ret = handle_send_eta_cmd(cmd);
827af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		break;
828b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	case FIO_NET_CMD_RUN:
8296348b5dee54f24f2e78872948653942336f4c14eJens Axboe		ret = handle_run_cmd(job_list, cmd);
830b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		break;
831f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	case FIO_NET_CMD_UPDATE_JOB:
832f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		ret = handle_update_job_cmd(cmd);
833f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		break;
834de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	case FIO_NET_CMD_VTRIGGER:
835de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		ret = handle_trigger_cmd(cmd);
836de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		break;
837de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	case FIO_NET_CMD_SENDFILE: {
838de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		struct cmd_sendfile_reply *in;
839de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		struct cmd_reply *rep;
840de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
841de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		rep = (struct cmd_reply *) (uintptr_t) cmd->tag;
842de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
843de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		in = (struct cmd_sendfile_reply *) cmd->payload;
844de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		in->size = le32_to_cpu(in->size);
845de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		in->error = le32_to_cpu(in->error);
846de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		if (in->error) {
847de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe			ret = 1;
848de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe			rep->error = in->error;
849de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		} else {
850de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe			ret = 0;
851de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe			rep->data = smalloc(in->size);
852de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe			if (!rep->data) {
853de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe				ret = 1;
854de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe				rep->error = ENOMEM;
855de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe			} else {
856de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe				rep->size = in->size;
857de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe				memcpy(rep->data, in->data, in->size);
858de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe			}
859de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		}
860de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		fio_mutex_up(&rep->lock);
861de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		break;
862de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		}
863132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
8643c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe		log_err("fio: unknown opcode: %s\n", fio_server_op(cmd->opcode));
865132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = 1;
866132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
867132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
868132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
869132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
870132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
871122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic int handle_connection(int sk)
872132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
873132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd *cmd = NULL;
8746348b5dee54f24f2e78872948653942336f4c14eJens Axboe	FLIST_HEAD(job_list);
875132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
876132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
877122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	reset_fio_state();
878122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	server_fd = sk;
879122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
880132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* read forever */
881132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	while (!exit_backend) {
882e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		struct pollfd pfd = {
883e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.fd	= sk,
884e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.events	= POLLIN,
885e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		};
886e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
887e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		ret = 0;
888e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		do {
889541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			int timeout = 1000;
890541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
891541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			if (!flist_empty(&job_list))
892541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe				timeout = 100;
8933c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe
894541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			ret = poll(&pfd, 1, timeout);
895e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (ret < 0) {
896e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				if (errno == EINTR)
897e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe					break;
898e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
899e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
90019c65179fad3e0a32a450401ba7d312169627fddJens Axboe			} else if (!ret) {
9016348b5dee54f24f2e78872948653942336f4c14eJens Axboe				fio_server_check_jobs(&job_list);
902e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				continue;
90319c65179fad3e0a32a450401ba7d312169627fddJens Axboe			}
904e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
905e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & POLLIN)
906e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
907e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & (POLLERR|POLLHUP)) {
908e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				ret = 1;
909e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
910e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			}
91119c65179fad3e0a32a450401ba7d312169627fddJens Axboe		} while (!exit_backend);
912e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
9136348b5dee54f24f2e78872948653942336f4c14eJens Axboe		fio_server_check_jobs(&job_list);
914122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
915e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		if (ret < 0)
916e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			break;
917e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
918e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		cmd = fio_net_recv_cmd(sk);
919132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (!cmd) {
920c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe			ret = -1;
921132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
922132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		}
923132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
9246348b5dee54f24f2e78872948653942336f4c14eJens Axboe		ret = handle_command(&job_list, cmd);
925132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
926132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
927132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
928132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
929c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe		cmd = NULL;
930132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
931132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
932132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd)
933132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
934132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
935122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	close(sk);
936122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	_exit(ret);
937cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
938cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
93950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
94050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
941bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	struct sockaddr_in addr;
942479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe	struct sockaddr_in6 addr6;
943479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe	socklen_t len = use_ipv6 ? sizeof(addr6) : sizeof(addr);
944009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
9454a851614cfdbebddeb78de04ac89a39d26f25459Jens Axboe	int ret = 0, sk, exitval = 0;
9466348b5dee54f24f2e78872948653942336f4c14eJens Axboe	FLIST_HEAD(conn_list);
94750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
94860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server enter accept loop\n");
94960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
9504a851614cfdbebddeb78de04ac89a39d26f25459Jens Axboe	fio_set_fd_nonblocking(listen_sk, "server");
951009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
952122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	while (!exit_backend) {
953479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		const char *from;
954479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		char buf[64];
955122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pid_t pid;
956009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
957122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pfd.fd = listen_sk;
958122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pfd.events = POLLIN;
959122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		do {
960541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			int timeout = 1000;
961541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
962541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			if (!flist_empty(&conn_list))
963541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe				timeout = 100;
964541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
965541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			ret = poll(&pfd, 1, timeout);
966122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (ret < 0) {
967122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				if (errno == EINTR)
968122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe					break;
969122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
970122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				break;
971122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			} else if (!ret) {
9726348b5dee54f24f2e78872948653942336f4c14eJens Axboe				fio_server_check_conns(&conn_list);
973122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				continue;
974122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			}
975009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
976122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (pfd.revents & POLLIN)
977122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				break;
978122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		} while (!exit_backend);
97950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
9806348b5dee54f24f2e78872948653942336f4c14eJens Axboe		fio_server_check_conns(&conn_list);
98146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
982122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (exit_backend || ret < 0)
983122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			break;
984122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
985479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		if (use_ipv6)
986479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			sk = accept(listen_sk, (struct sockaddr *) &addr6, &len);
987479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		else
988479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			sk = accept(listen_sk, (struct sockaddr *) &addr, &len);
989479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe
990122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (sk < 0) {
991122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: accept: %s\n", strerror(errno));
992122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			return -1;
993122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
99437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
995479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		if (use_ipv6)
996479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			from = inet_ntop(AF_INET6, (struct sockaddr *) &addr6.sin6_addr, buf, sizeof(buf));
997479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		else
998479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			from = inet_ntop(AF_INET, (struct sockaddr *) &addr.sin_addr, buf, sizeof(buf));
999479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe
1000479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		dprint(FD_NET, "server: connect from %s\n", from);
100150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
1002122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pid = fork();
1003122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (pid) {
1004122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			close(sk);
10056348b5dee54f24f2e78872948653942336f4c14eJens Axboe			fio_server_add_conn_pid(&conn_list, pid);
1006122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			continue;
1007122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
10085c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
1009122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		/* exits */
1010122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		handle_connection(sk);
1011122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
10125c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
1013132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return exitval;
101450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
101550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
1016084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboeint fio_server_text_output(int level, const char *buf, size_t len)
101737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
1018084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	struct cmd_text_pdu *pdu;
1019084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	unsigned int tlen;
1020084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	struct timeval tv;
1021084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
1022084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	if (server_fd == -1)
1023084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe		return log_local_buf(buf, len);
1024084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
1025084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	tlen = sizeof(*pdu) + len;
1026084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu = malloc(tlen);
1027084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
1028084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->level	= __cpu_to_le32(level);
1029084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->buf_len	= __cpu_to_le32(len);
1030084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
1031084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	gettimeofday(&tv, NULL);
1032084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_sec	= __cpu_to_le64(tv.tv_sec);
1033084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_usec	= __cpu_to_le64(tv.tv_usec);
1034337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe
1035084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	memcpy(pdu->buf, buf, len);
1036084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
103740c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, pdu, tlen, NULL, NULL);
1038084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	free(pdu);
1039084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	return len;
1040142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe}
1041142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
1042a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src)
1043a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
1044a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->max_val	= cpu_to_le64(src->max_val);
1045a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->min_val	= cpu_to_le64(src->min_val);
1046a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->samples	= cpu_to_le64(src->samples);
1047802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
1048802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	/*
1049802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 * Encode to IEEE 754 for network transfer
1050802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 */
10512b827faedef7fc8b62a993e07e623e84dcd3f1b3Jens Axboe	dst->mean.u.i	= cpu_to_le64(fio_double_to_uint64(src->mean.u.f));
10522b827faedef7fc8b62a993e07e623e84dcd3f1b3Jens Axboe	dst->S.u.i	= cpu_to_le64(fio_double_to_uint64(src->S.u.f));
1053a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
1054a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1055a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
1056a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
1057a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i;
1058a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1059298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1060a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_run[i]		= cpu_to_le64(src->max_run[i]);
1061a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_run[i]		= cpu_to_le64(src->min_run[i]);
1062a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_bw[i]		= cpu_to_le64(src->max_bw[i]);
1063a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_bw[i]		= cpu_to_le64(src->min_bw[i]);
1064a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_kb[i]		= cpu_to_le64(src->io_kb[i]);
1065a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->agg[i]		= cpu_to_le64(src->agg[i]);
1066a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1067a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1068a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->kb_base	= cpu_to_le32(src->kb_base);
1069ad705bcb7e79a7cdb9891db17b4c40b13b6c30c3Steven Noonan	dst->unit_base	= cpu_to_le32(src->unit_base);
1070a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= cpu_to_le32(src->groupid);
1071771e58befea806d2d881953050c4e65329eee382Jens Axboe	dst->unified_rw_rep	= cpu_to_le32(src->unified_rw_rep);
1072a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
1073a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1074a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
1075a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats
1076a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload.
1077a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
1078a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
1079a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
1080a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct cmd_ts_pdu p;
1081a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i, j;
1082a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
108360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending end stats\n");
108460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
1085317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe	memset(&p, 0, sizeof(p));
1086317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe
10874e59d0f3a3ff569bddb31fe6927a9faf204ae9bfJens Axboe	strncpy(p.ts.name, ts->name, FIO_JOBNAME_SIZE - 1);
10884e59d0f3a3ff569bddb31fe6927a9faf204ae9bfJens Axboe	strncpy(p.ts.verror, ts->verror, FIO_VERROR_SIZE - 1);
10894e59d0f3a3ff569bddb31fe6927a9faf204ae9bfJens Axboe	strncpy(p.ts.description, ts->description, FIO_JOBDESC_SIZE - 1);
1090a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
10912f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.error		= cpu_to_le32(ts->error);
10922f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.thread_number	= cpu_to_le32(ts->thread_number);
10932f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.groupid		= cpu_to_le32(ts->groupid);
10942f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.pid		= cpu_to_le32(ts->pid);
10952f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.members		= cpu_to_le32(ts->members);
1096771e58befea806d2d881953050c4e65329eee382Jens Axboe	p.ts.unified_rw_rep	= cpu_to_le32(ts->unified_rw_rep);
1097a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1098298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1099a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]);
1100a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]);
1101a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]);
1102a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]);
1103a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1104a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1105a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.usr_time		= cpu_to_le64(ts->usr_time);
1106a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.sys_time		= cpu_to_le64(ts->sys_time);
1107a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.ctx		= cpu_to_le64(ts->ctx);
1108a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.minf		= cpu_to_le64(ts->minf);
1109a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.majf		= cpu_to_le64(ts->majf);
1110a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.clat_percentiles	= cpu_to_le64(ts->clat_percentiles);
1111623216dc7051bca6f52462c00ac9fad65537654bJens Axboe	p.ts.percentile_precision = cpu_to_le64(ts->percentile_precision);
1112802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
1113802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
1114cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *src = &ts->percentile_list[i];
1115cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *dst = &p.ts.percentile_list[i];
1116802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
11172b827faedef7fc8b62a993e07e623e84dcd3f1b3Jens Axboe		dst->u.i = cpu_to_le64(fio_double_to_uint64(src->u.f));
1118802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	}
1119a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1120a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
1121a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_map[i]	= cpu_to_le32(ts->io_u_map[i]);
1122a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_submit[i]	= cpu_to_le32(ts->io_u_submit[i]);
1123a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_complete[i]	= cpu_to_le32(ts->io_u_complete[i]);
1124a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1125a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1126a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
1127a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_u[i]	= cpu_to_le32(ts->io_u_lat_u[i]);
1128a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_m[i]	= cpu_to_le32(ts->io_u_lat_m[i]);
1129a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1130a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1131298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++)
1132a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
1133a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]);
1134a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
113578799debc66f717469e751b3b9eb5dfa48cc547bJens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1136a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.total_io_u[i]	= cpu_to_le64(ts->total_io_u[i]);
113793eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe		p.ts.short_io_u[i]	= cpu_to_le64(ts->short_io_u[i]);
113867e149c4c2b580089287813246344908770c3be9Jens Axboe		p.ts.drop_io_u[i]	= cpu_to_le64(ts->drop_io_u[i]);
1139a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1140a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
114193eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe	p.ts.total_submit	= cpu_to_le64(ts->total_submit);
1142a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_complete	= cpu_to_le64(ts->total_complete);
1143a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1144298921d65ea914873cbc270af6663dad9e08b782Jens Axboe	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
1145a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_bytes[i]	= cpu_to_le64(ts->io_bytes[i]);
1146a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.runtime[i]		= cpu_to_le64(ts->runtime[i]);
1147a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
1148a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1149a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_run_time	= cpu_to_le64(ts->total_run_time);
1150a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.continue_on_error	= cpu_to_le16(ts->continue_on_error);
1151a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_err_count	= cpu_to_le64(ts->total_err_count);
1152ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.first_error	= cpu_to_le32(ts->first_error);
1153ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.kb_base		= cpu_to_le32(ts->kb_base);
1154ad705bcb7e79a7cdb9891db17b4c40b13b6c30c3Steven Noonan	p.ts.unit_base		= cpu_to_le32(ts->unit_base);
1155a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
11563e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	p.ts.latency_depth	= cpu_to_le32(ts->latency_depth);
11573e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	p.ts.latency_target	= cpu_to_le64(ts->latency_target);
11583e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe	p.ts.latency_window	= cpu_to_le64(ts->latency_window);
11592b827faedef7fc8b62a993e07e623e84dcd3f1b3Jens Axboe	p.ts.latency_percentile.u.i = cpu_to_le64(fio_double_to_uint64(ts->latency_percentile.u.f));
11603e260a46ea9a8de224c3d0a29a608da3440f284aJens Axboe
1161a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&p.rs, rs);
1162a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
116340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), NULL, NULL);
1164a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
1165a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
1166a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs)
1167a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
1168a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct group_run_stats gs;
1169a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
117060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending group run stats\n");
117160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
1172a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&gs, rs);
117340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), NULL, NULL);
1174cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe}
1175cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
1176d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src)
1177d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
1178d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
1179d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1180d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
11812a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe		dst->ios[i]	= cpu_to_le64(src->ios[i]);
11822a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe		dst->merges[i]	= cpu_to_le64(src->merges[i]);
1183d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
11842a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe		dst->ticks[i]	= cpu_to_le64(src->ticks[i]);
1185d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
1186d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
11872a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe	dst->io_ticks		= cpu_to_le64(src->io_ticks);
11882a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe	dst->time_in_queue	= cpu_to_le64(src->time_in_queue);
1189d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->slavecount		= cpu_to_le32(src->slavecount);
11902b827faedef7fc8b62a993e07e623e84dcd3f1b3Jens Axboe	dst->max_util.u.i	= cpu_to_le64(fio_double_to_uint64(src->max_util.u.f));
1191d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1192d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1193d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src)
1194d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
1195d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
1196d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
119759140421267ef809b00da12881b8d899ecefbb10Jens Axboe	dst->name[FIO_DU_NAME_SZ - 1] = '\0';
119859140421267ef809b00da12881b8d899ecefbb10Jens Axboe	strncpy((char *) dst->name, (char *) src->name, FIO_DU_NAME_SZ - 1);
1199d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1200d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
12012a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe		dst->s.ios[i]		= cpu_to_le64(src->s.ios[i]);
12022a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe		dst->s.merges[i]	= cpu_to_le64(src->s.merges[i]);
1203a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe		dst->s.sectors[i]	= cpu_to_le64(src->s.sectors[i]);
12042a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe		dst->s.ticks[i]		= cpu_to_le64(src->s.ticks[i]);
1205d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
1206d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
12072a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe	dst->s.io_ticks		= cpu_to_le64(src->s.io_ticks);
12082a3bf76465a94399b3cb5ced55ddf98d81125fa3Jens Axboe	dst->s.time_in_queue	= cpu_to_le64(src->s.time_in_queue);
1209a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe	dst->s.msec		= cpu_to_le64(src->s.msec);
1210d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1211d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1212d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboevoid fio_server_send_du(void)
1213d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
1214d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct disk_util *du;
1215d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct flist_head *entry;
1216d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct cmd_du_pdu pdu;
1217d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1218d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dprint(FD_NET, "server: sending disk_util %d\n", !flist_empty(&disk_list));
1219d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
12200766d92e06a119eea489e74d80d5840813559752Jens Axboe	memset(&pdu, 0, sizeof(pdu));
12210766d92e06a119eea489e74d80d5840813559752Jens Axboe
1222d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	flist_for_each(entry, &disk_list) {
1223d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		du = flist_entry(entry, struct disk_util, list);
1224d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1225d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_dus(&pdu.dus, &du->dus);
1226d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_agg(&pdu.agg, &du->agg);
1227d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
122840c605169e60d32fc321a2f9f465e76cba745489Jens Axboe		fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), NULL, NULL);
1229d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
1230d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1231d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
123253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe/*
123353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe * Send a command with a separate PDU, not inlined in the command
123453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe */
123553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboestatic int fio_send_cmd_ext_pdu(int sk, uint16_t opcode, const void *buf,
123653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe				off_t size, uint64_t tag, uint32_t flags)
123753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe{
123853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	struct fio_net_cmd cmd;
123953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	struct iovec iov[2];
124053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
12419f24726136cc2e94359da7e0dbfd3b6955a71bc5Jens Axboe	iov[0].iov_base = (void *) &cmd;
124253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[0].iov_len = sizeof(cmd);
124353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[1].iov_base = (void *) buf;
124453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[1].iov_len = size;
124553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
124653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	__fio_init_net_cmd(&cmd, opcode, size, tag);
124753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	cmd.flags = __cpu_to_le32(flags);
124853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	fio_net_cmd_crc_pdu(&cmd, buf);
124953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
12508c95307bd5f72720460ee4a46519b9a1b474e7cdJens Axboe	return fio_sendv_data(sk, iov, 2);
125153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe}
125253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
12533989b14303458519192f4ace8caf091d587f5e6eJens Axboestatic int fio_send_iolog_gz(struct cmd_iolog_pdu *pdu, struct io_log *log)
12541b42725f06f8906b9b99381da3490484f59df28aJens Axboe{
12553989b14303458519192f4ace8caf091d587f5e6eJens Axboe	int ret = 0;
12563989b14303458519192f4ace8caf091d587f5e6eJens Axboe#ifdef CONFIG_ZLIB
12571b42725f06f8906b9b99381da3490484f59df28aJens Axboe	z_stream stream;
12581b42725f06f8906b9b99381da3490484f59df28aJens Axboe	void *out_pdu;
12591b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12601b42725f06f8906b9b99381da3490484f59df28aJens Axboe	/*
12611b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * Dirty - since the log is potentially huge, compress it into
12621b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * FIO_SERVER_MAX_FRAGMENT_PDU chunks and let the receiving
12631b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * side defragment it.
12641b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 */
12651b42725f06f8906b9b99381da3490484f59df28aJens Axboe	out_pdu = malloc(FIO_SERVER_MAX_FRAGMENT_PDU);
12661b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12671b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zalloc = Z_NULL;
12681b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zfree = Z_NULL;
12691b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.opaque = Z_NULL;
12701b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12711b42725f06f8906b9b99381da3490484f59df28aJens Axboe	if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
127253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		ret = 1;
127353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		goto err;
12741b42725f06f8906b9b99381da3490484f59df28aJens Axboe	}
12751b42725f06f8906b9b99381da3490484f59df28aJens Axboe
1276f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	stream.next_in = (void *) log->log;
1277ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe	stream.avail_in = log->nr_samples * log_entry_sz(log);
12781b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12791b42725f06f8906b9b99381da3490484f59df28aJens Axboe	do {
128053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		unsigned int this_len, flags = 0;
12811b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12821b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.avail_out = FIO_SERVER_MAX_FRAGMENT_PDU;
12831b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.next_out = out_pdu;
12843c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		ret = deflate(&stream, Z_FINISH);
12853c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		/* may be Z_OK, or Z_STREAM_END */
12863c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		if (ret < 0)
12873c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe			goto err_zlib;
12881b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12891b42725f06f8906b9b99381da3490484f59df28aJens Axboe		this_len = FIO_SERVER_MAX_FRAGMENT_PDU - stream.avail_out;
12901b42725f06f8906b9b99381da3490484f59df28aJens Axboe
12911b42725f06f8906b9b99381da3490484f59df28aJens Axboe		if (stream.avail_in)
129253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe			flags = FIO_NET_CMD_F_MORE;
12931b42725f06f8906b9b99381da3490484f59df28aJens Axboe
129453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG,
129553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe					   out_pdu, this_len, 0, flags);
129653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		if (ret)
129753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe			goto err_zlib;
12981b42725f06f8906b9b99381da3490484f59df28aJens Axboe	} while (stream.avail_in);
12991b42725f06f8906b9b99381da3490484f59df28aJens Axboe
130053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboeerr_zlib:
13011b42725f06f8906b9b99381da3490484f59df28aJens Axboe	deflateEnd(&stream);
130253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboeerr:
130353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	free(out_pdu);
13043989b14303458519192f4ace8caf091d587f5e6eJens Axboe#endif
130553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	return ret;
13061b42725f06f8906b9b99381da3490484f59df28aJens Axboe}
13071b42725f06f8906b9b99381da3490484f59df28aJens Axboe
13083989b14303458519192f4ace8caf091d587f5e6eJens Axboeint fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
13093989b14303458519192f4ace8caf091d587f5e6eJens Axboe{
13103989b14303458519192f4ace8caf091d587f5e6eJens Axboe	struct cmd_iolog_pdu pdu;
13113989b14303458519192f4ace8caf091d587f5e6eJens Axboe	int i, ret = 0;
13123989b14303458519192f4ace8caf091d587f5e6eJens Axboe
1313ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe	pdu.nr_samples = cpu_to_le64(log->nr_samples);
13143989b14303458519192f4ace8caf091d587f5e6eJens Axboe	pdu.thread_number = cpu_to_le32(td->thread_number);
13153989b14303458519192f4ace8caf091d587f5e6eJens Axboe	pdu.log_type = cpu_to_le32(log->log_type);
13163989b14303458519192f4ace8caf091d587f5e6eJens Axboe	pdu.compressed = cpu_to_le32(use_zlib);
13179bdb9265ed6cfd95fc217a9030b188a5a345cc89Jens Axboe
13189bdb9265ed6cfd95fc217a9030b188a5a345cc89Jens Axboe	strncpy((char *) pdu.name, name, FIO_NET_NAME_MAX);
13199bdb9265ed6cfd95fc217a9030b188a5a345cc89Jens Axboe	pdu.name[FIO_NET_NAME_MAX - 1] = '\0';
13203989b14303458519192f4ace8caf091d587f5e6eJens Axboe
13213989b14303458519192f4ace8caf091d587f5e6eJens Axboe	for (i = 0; i < log->nr_samples; i++) {
1322ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe		struct io_sample *s = get_sample(log, i);
13233989b14303458519192f4ace8caf091d587f5e6eJens Axboe
1324bac4af11424ddeb340968c4ba4fc88df4f5c1ad0Jens Axboe		s->time		= cpu_to_le64(s->time);
1325bac4af11424ddeb340968c4ba4fc88df4f5c1ad0Jens Axboe		s->val		= cpu_to_le64(s->val);
1326bac4af11424ddeb340968c4ba4fc88df4f5c1ad0Jens Axboe		s->__ddir	= cpu_to_le32(s->__ddir);
1327bac4af11424ddeb340968c4ba4fc88df4f5c1ad0Jens Axboe		s->bs		= cpu_to_le32(s->bs);
1328ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe
1329ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe		if (log->log_offset) {
1330ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe			struct io_sample_offset *so = (void *) s;
1331ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe
1332ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe			so->offset = cpu_to_le64(so->offset);
1333ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe		}
13343989b14303458519192f4ace8caf091d587f5e6eJens Axboe	}
13353989b14303458519192f4ace8caf091d587f5e6eJens Axboe
13363989b14303458519192f4ace8caf091d587f5e6eJens Axboe	/*
13373989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 * Send header first, it's not compressed.
13383989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 */
13393989b14303458519192f4ace8caf091d587f5e6eJens Axboe	ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, &pdu,
13403989b14303458519192f4ace8caf091d587f5e6eJens Axboe					sizeof(pdu), 0, FIO_NET_CMD_F_MORE);
13413989b14303458519192f4ace8caf091d587f5e6eJens Axboe	if (ret)
13423989b14303458519192f4ace8caf091d587f5e6eJens Axboe		return ret;
13433989b14303458519192f4ace8caf091d587f5e6eJens Axboe
13443989b14303458519192f4ace8caf091d587f5e6eJens Axboe	/*
13453989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 * Now send actual log, compress if we can, otherwise just plain
13463989b14303458519192f4ace8caf091d587f5e6eJens Axboe	 */
13473989b14303458519192f4ace8caf091d587f5e6eJens Axboe	if (use_zlib)
13483989b14303458519192f4ace8caf091d587f5e6eJens Axboe		return fio_send_iolog_gz(&pdu, log);
13493989b14303458519192f4ace8caf091d587f5e6eJens Axboe
13503989b14303458519192f4ace8caf091d587f5e6eJens Axboe	return fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, log->log,
1351ccefd5fea1de87a83db9c372985b69f4fbbe922cJens Axboe			log->nr_samples * log_entry_sz(log), 0, 0);
13523989b14303458519192f4ace8caf091d587f5e6eJens Axboe}
13533989b14303458519192f4ace8caf091d587f5e6eJens Axboe
13542f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboevoid fio_server_send_add_job(struct thread_data *td)
1355807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe{
1356807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe	struct cmd_add_job_pdu pdu;
1357807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1358731e30a2551315c609c23ac107377b63c02d51faJens Axboe	memset(&pdu, 0, sizeof(pdu));
13592f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.thread_number = cpu_to_le32(td->thread_number);
13602f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.groupid = cpu_to_le32(td->groupid);
13612f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	convert_thread_options_to_net(&pdu.top, &td->o);
1362807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
136340c605169e60d32fc321a2f9f465e76cba745489Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ADD_JOB, &pdu, sizeof(pdu), NULL, NULL);
1364807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe}
1365807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1366122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboevoid fio_server_send_start(struct thread_data *td)
1367122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
1368122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	assert(server_fd != -1);
1369122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
1370122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_SERVER_START, 0, NULL);
1371122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
1372122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
1373de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboeint fio_server_get_verify_state(const char *name, int threadnumber,
1374de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe				void **datap)
1375de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe{
1376de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	struct thread_io_list *s;
1377de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	struct cmd_sendfile out;
1378de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	struct cmd_reply *rep;
1379de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	uint64_t tag;
1380de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	void *data;
1381de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
1382de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	dprint(FD_NET, "server: request verify state\n");
1383de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
1384de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	rep = smalloc(sizeof(*rep));
1385de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	if (!rep) {
1386de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		log_err("fio: smalloc pool too small\n");
1387de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		return 1;
1388de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	}
1389de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
1390de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	__fio_mutex_init(&rep->lock, FIO_MUTEX_LOCKED);
1391de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	rep->data = NULL;
1392de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	rep->error = 0;
1393de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
13943ebcfd56868fd11f66bee3a9792811c02d66db04Jens Axboe	verify_state_gen_name((char *) out.path, sizeof(out.path), name, me,
13953ebcfd56868fd11f66bee3a9792811c02d66db04Jens Axboe				threadnumber);
1396de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	tag = (uint64_t) (uintptr_t) rep;
1397de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_SENDFILE, &out, sizeof(out),
1398de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe				&tag, NULL);
1399de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
1400de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	/*
1401de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	 * Wait for the backend to receive the reply
1402de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	 */
1403de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	if (fio_mutex_down_timeout(&rep->lock, 10)) {
1404de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		log_err("fio: timed out waiting for reply\n");
1405de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		goto fail;
1406de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	}
1407de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
1408de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	if (rep->error) {
1409de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		log_err("fio: failure on receiving state file: %s\n", strerror(rep->error));
1410de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboefail:
1411de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		*datap = NULL;
1412de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		sfree(rep);
1413de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		fio_net_send_quit(server_fd);
1414de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		return 1;
1415de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	}
1416de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
1417de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	/*
1418de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	 * The format is verify_state_hdr, then thread_io_list. Verify
1419de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	 * the header, and the thread_io_list checksum
1420de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	 */
1421de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	s = rep->data + sizeof(struct verify_state_hdr);
1422de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	if (verify_state_hdr(rep->data, s))
1423de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe		goto fail;
1424de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
1425de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	/*
1426de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	 * Don't need the header from now, copy just the thread_io_list
1427de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	 */
1428de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	rep->size -= sizeof(struct verify_state_hdr);
1429de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	data = malloc(rep->size);
1430de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	memcpy(data, s, rep->size);
1431de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	*datap = data;
1432de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
1433de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	sfree(rep->data);
1434c180342e1293259ca8d23ed0298aa6c32815fee5Jens Axboe	__fio_mutex_remove(&rep->lock);
1435de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	sfree(rep);
1436de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe	return 0;
1437de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe}
1438de54cfd8b8e93d2a32a02961f1587b83f0763aa8Jens Axboe
143987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_ip(void)
144081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
1441811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	struct sockaddr *addr;
144267bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	socklen_t socklen;
144317e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe	char buf[80];
144417e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe	const char *str;
144587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, opt;
144681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1447811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6)
1448811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET6, SOCK_STREAM, 0);
1449811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	else
1450811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET, SOCK_STREAM, 0);
1451811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
145281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (sk < 0) {
145381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
145481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
145581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
145681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
145781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	opt = 1;
14581f81991ed356dd7257aef2c715ba9a24d9af93a5Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt)) < 0) {
145981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
1460b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
146181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
146281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
146381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT
14646eb2479194603184f393057ea10326643edc7169Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
146581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
1466b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
146781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
146881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
146981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif
147081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1471811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6) {
147217e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		const void *src = &saddr_in6.sin6_addr;
147317e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe
1474811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in6;
1475811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in6);
1476811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in6.sin6_family = AF_INET6;
147717e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		str = inet_ntop(AF_INET6, src, buf, sizeof(buf));
1478811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else {
147917e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		const void *src = &saddr_in.sin_addr;
148017e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe
1481811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in;
1482811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in);
1483811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in.sin_family = AF_INET;
148417e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		str = inet_ntop(AF_INET, src, buf, sizeof(buf));
1485811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	}
148681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1487811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (bind(sk, addr, socklen) < 0) {
148881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
148917e3531ad6dcd6d0d8f1191f7fe484a345f26f52Jens Axboe		log_info("fio: failed with IPv%c %s\n", use_ipv6 ? '6' : '4', str);
1490b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
149181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
149281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
149381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
149487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
149587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
149687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
149787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_sock(void)
149887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
149987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un addr;
150067bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	socklen_t len;
150187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode_t mode;
150287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
150387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
150487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = socket(AF_UNIX, SOCK_STREAM, 0);
150587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0) {
150687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: socket: %s\n", strerror(errno));
150787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
150887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
150987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
151087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode = umask(000);
151187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
151287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	memset(&addr, 0, sizeof(addr));
151387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	addr.sun_family = AF_UNIX;
1514a48fddbcb33991f9b2d1be1fa0a5e5cfb9ea9faeJens Axboe	strncpy(addr.sun_path, bind_sock, sizeof(addr.sun_path) - 1);
151587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
151687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	len = sizeof(addr.sun_family) + strlen(bind_sock) + 1;
151787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
151887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (bind(sk, (struct sockaddr *) &addr, len) < 0) {
151987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: bind: %s\n", strerror(errno));
1520b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
152187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
152287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
152387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
152487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	umask(mode);
152587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
152687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
152787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
152887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_connection(void)
152987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
1530bebe639808147d587bbe776566d390b9ff98773fJens Axboe	char bind_str[128];
153187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
153287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
153387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
153487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
153587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!bind_sock)
153687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_ip();
153787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	else
153887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_sock();
153987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
154087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
154187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return sk;
154287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1543afdcad2315c22200d594a29885053d7671881ebbJens Axboe	memset(bind_str, 0, sizeof(bind_str));
1544afdcad2315c22200d594a29885053d7671881ebbJens Axboe
1545811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (!bind_sock) {
1546811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		char *p, port[16];
1547811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		const void *src;
1548811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		int af;
1549811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1550811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (use_ipv6) {
1551811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET6;
1552811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in6.sin6_addr;
1553811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		} else {
1554811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET;
1555811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in.sin_addr;
1556811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		}
1557811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1558811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		p = (char *) inet_ntop(af, src, bind_str, sizeof(bind_str));
1559811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1560811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sprintf(port, ",%u", fio_net_port);
1561811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (p)
1562811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcat(p, port);
1563811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		else
1564afdcad2315c22200d594a29885053d7671881ebbJens Axboe			strncpy(bind_str, port, sizeof(bind_str) - 1);
1565811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else
1566afdcad2315c22200d594a29885053d7671881ebbJens Axboe		strncpy(bind_str, bind_sock, sizeof(bind_str) - 1);
1567bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1568bebe639808147d587bbe776566d390b9ff98773fJens Axboe	log_info("fio: server listening on %s\n", bind_str);
1569bebe639808147d587bbe776566d390b9ff98773fJens Axboe
157089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (listen(sk, 0) < 0) {
157181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
15722fd973c9e7bbbf88d52a55ee1daa2568d4bf5f41Jens Axboe		close(sk);
157381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
157481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
157581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
157687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
157787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
157887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
15793aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboeint fio_server_parse_host(const char *host, int ipv6, struct in_addr *inp,
15803ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			  struct in6_addr *inp6)
15813ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
15823ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe{
15833ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	int ret = 0;
15843ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
15853aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboe	if (ipv6)
15863ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = inet_pton(AF_INET6, host, inp6);
15873ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	else
15883ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = inet_pton(AF_INET, host, inp);
15893ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
15903ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	if (ret != 1) {
1591479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		struct addrinfo hints, *res;
1592479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe
1593479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		memset(&hints, 0, sizeof(hints));
15943aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboe		hints.ai_family = ipv6 ? AF_INET6 : AF_INET;
1595479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		hints.ai_socktype = SOCK_STREAM;
15963ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
1597479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		ret = getaddrinfo(host, NULL, &hints, &res);
1598479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		if (ret) {
1599479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			log_err("fio: failed to resolve <%s> (%s)\n", host,
1600479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe					gai_strerror(ret));
16013caf43e3a1567affb2e35f4577d7c51c606187f1Jens Axboe			return 1;
16023ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		}
16033ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
16043aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboe		if (ipv6)
1605479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			memcpy(inp6, &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr, sizeof(*inp6));
1606479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		else
1607479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe			memcpy(inp, &((struct sockaddr_in *) res->ai_addr)->sin_addr, sizeof(*inp));
1608479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe
16093ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = 1;
1610479471c409a61d01290ac9444042357b03f8d0b0Jens Axboe		freeaddrinfo(res);
16113ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	}
16123ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
16133ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	return !(ret == 1);
16143ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe}
16153ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
1616660a2bfb0858f94633f9e567b81968981541f079Jens Axboe/*
1617660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Parse a host/ip/port string. Reads from 'str'.
1618660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
1619660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Outputs:
1620660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
1621660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv4:
1622660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp is the destination.
1623660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv6:
1624660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp6 is the dest, and *ipv6 is 1.
1625660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For local domain sockets:
1626660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the filename, *is_sock is 1.
1627660a2bfb0858f94633f9e567b81968981541f079Jens Axboe */
1628bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_server_parse_string(const char *str, char **ptr, int *is_sock,
1629811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    int *port, struct in_addr *inp,
1630811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    struct in6_addr *inp6, int *ipv6)
1631bebe639808147d587bbe776566d390b9ff98773fJens Axboe{
163276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	const char *host = str;
163376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	char *portp;
16343ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	int lport = 0;
163576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
1636bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*ptr = NULL;
1637bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*is_sock = 0;
16386d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	*port = fio_net_port;
1639811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	*ipv6 = 0;
1640bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1641bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!strncmp(str, "sock:", 5)) {
1642bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*ptr = strdup(str + 5);
1643bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*is_sock = 1;
164476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
164576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
164676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
164776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
164876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
164976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * Is it ip:<ip or host>:port
165076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
165176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strncmp(host, "ip:", 3))
165276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 3;
165376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip4:", 4))
165476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
165576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip6:", 4)) {
165676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
165776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*ipv6 = 1;
165876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	} else if (host[0] == ':') {
165976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* String is :port */
166076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host++;
166176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		lport = atoi(host);
166276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!lport || lport > 65535) {
16634e0a8fa2593006505b7f4e18931a201d221b49e9Jens Axboe			log_err("fio: bad server port %u\n", lport);
166476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			return 1;
166576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
166676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* no hostname given, we are done */
166776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
166876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
166976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
167076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
167176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
1672b96b90c383b25f4d0a002f672c3ff3dc02fdbf7bJens Axboe	 * If no port seen yet, check if there's a last ',' at the end
167376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
167476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!lport) {
167576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		portp = strchr(host, ',');
167676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (portp) {
167776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			*portp = '\0';
167876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			portp++;
167976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			lport = atoi(portp);
1680bebe639808147d587bbe776566d390b9ff98773fJens Axboe			if (!lport || lport > 65535) {
16814e0a8fa2593006505b7f4e18931a201d221b49e9Jens Axboe				log_err("fio: bad server port %u\n", lport);
1682bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
1683bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
1684bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
168576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
1686bebe639808147d587bbe776566d390b9ff98773fJens Axboe
168776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (lport)
168876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
1689bebe639808147d587bbe776566d390b9ff98773fJens Axboe
169076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strlen(host))
169176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
1692bebe639808147d587bbe776566d390b9ff98773fJens Axboe
169376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	*ptr = strdup(host);
1694811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
16953aa3ceeb5c93f05e50d13a0e8f374843e6cb8ec5Jens Axboe	if (fio_server_parse_host(*ptr, *ipv6, inp, inp6)) {
16963ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		free(*ptr);
16973ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		*ptr = NULL;
16983ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		return 1;
1699bebe639808147d587bbe776566d390b9ff98773fJens Axboe	}
1700bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1701bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (*port == 0)
1702bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*port = fio_net_port;
1703bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1704bebe639808147d587bbe776566d390b9ff98773fJens Axboe	return 0;
1705bebe639808147d587bbe776566d390b9ff98773fJens Axboe}
1706bebe639808147d587bbe776566d390b9ff98773fJens Axboe
170787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe/*
170887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Server arg should be one of:
170987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
171087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * sock:/path/to/socket
171187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *   ip:1.2.3.4
171287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *      1.2.3.4
171387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
171487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Where sock uses unix domain sockets, and ip binds the server to
171587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * a specific interface. If no arguments are given to the server, it
171687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * uses IP and binds to 0.0.0.0.
171787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
171887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe */
171987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_handle_server_arg(void)
172087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
17216d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	int port = fio_net_port;
1722a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe	int is_sock, ret = 0;
1723bebe639808147d587bbe776566d390b9ff98773fJens Axboe
172487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
172587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
172687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!fio_server_arg)
1727a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe		goto out;
172887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
17294e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock,
1730811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&port, &saddr_in.sin_addr,
1731811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&saddr_in6.sin6_addr, &use_ipv6);
17324e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
17334e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	if (!is_sock && bind_sock) {
17344e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		free(bind_sock);
17354e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		bind_sock = NULL;
17364e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	}
17374e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
1738a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboeout:
17396d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	fio_net_port = port;
17406d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	saddr_in.sin_port = htons(port);
1741811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	saddr_in6.sin6_port = htons(port);
17424e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	return ret;
174387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
174487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
174543cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboestatic void sig_int(int sig)
174643cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe{
174743cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	if (bind_sock)
174843cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe		unlink(bind_sock);
174943cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe}
175043cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe
175143cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboestatic void set_sig_handlers(void)
175243cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe{
175343cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	struct sigaction act;
175443cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe
175543cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	memset(&act, 0, sizeof(act));
175643cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	act.sa_handler = sig_int;
175743cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	act.sa_flags = SA_RESTART;
175843cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	sigaction(SIGINT, &act, NULL);
175943cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe}
176043cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe
176187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_server(void)
176287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
176387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, ret;
176487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
176587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
176687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
176787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_handle_server_arg())
176887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
176987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
177087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = fio_init_server_connection();
177187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
177287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
177381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
177443cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe	set_sig_handlers();
177543cdea1d0d62fe57c0b1017c55b4700cd95f63b0Jens Axboe
177681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	ret = accept_loop(sk);
177787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
177881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	close(sk);
177987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
178087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_server_arg) {
178187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		free(fio_server_arg);
178287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fio_server_arg = NULL;
178387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
1784bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (bind_sock)
1785bebe639808147d587bbe776566d390b9ff98773fJens Axboe		free(bind_sock);
178687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
178781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
178881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
178981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
17907b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboevoid fio_server_got_signal(int signal)
17919abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{
17927b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	if (signal == SIGPIPE)
17937b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		server_fd = -1;
17947b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	else {
17957b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		log_info("\nfio: terminating on signal %d\n", signal);
17967b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		exit_backend = 1;
17977b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	}
17989abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe}
17999abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe
180013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int check_existing_pidfile(const char *pidfile)
180113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe{
180213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	struct stat sb;
180313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	char buf[16];
180413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid_t pid;
180513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	FILE *f;
180613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
180713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (stat(pidfile, &sb))
180813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
180913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
181013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	f = fopen(pidfile, "r");
181113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (!f)
181213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
181313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1814bfc3b17986fb80aeb5a6ea962bb38fc1509d60a8Jens Axboe	if (fread(buf, sb.st_size, 1, f) <= 0) {
181513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		fclose(f);
181613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
181713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
181813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(f);
181913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
182013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid = atoi(buf);
182113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (kill(pid, SIGCONT) < 0)
1822ea5aa1be68de71f9f02eb3d6f4db726adcafb40aJens Axboe		return errno != ESRCH;
182313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
182413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 1;
182513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe}
182613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
182713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int write_pid(pid_t pid, const char *pidfile)
1828402668f3e05259bfc135fc097136428feda01006Jens Axboe{
1829402668f3e05259bfc135fc097136428feda01006Jens Axboe	FILE *fpid;
1830402668f3e05259bfc135fc097136428feda01006Jens Axboe
1831402668f3e05259bfc135fc097136428feda01006Jens Axboe	fpid = fopen(pidfile, "w");
1832402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!fpid) {
1833402668f3e05259bfc135fc097136428feda01006Jens Axboe		log_err("fio: failed opening pid file %s\n", pidfile);
183413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
1835402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1836402668f3e05259bfc135fc097136428feda01006Jens Axboe
1837402668f3e05259bfc135fc097136428feda01006Jens Axboe	fprintf(fpid, "%u\n", (unsigned int) pid);
183813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(fpid);
183913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 0;
1840402668f3e05259bfc135fc097136428feda01006Jens Axboe}
1841402668f3e05259bfc135fc097136428feda01006Jens Axboe
1842402668f3e05259bfc135fc097136428feda01006Jens Axboe/*
1843402668f3e05259bfc135fc097136428feda01006Jens Axboe * If pidfile is specified, background us.
1844402668f3e05259bfc135fc097136428feda01006Jens Axboe */
1845402668f3e05259bfc135fc097136428feda01006Jens Axboeint fio_start_server(char *pidfile)
1846e46d809110bd4ad2980ca64931b683673444454bJens Axboe{
1847e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid_t pid;
1848402668f3e05259bfc135fc097136428feda01006Jens Axboe	int ret;
1849e46d809110bd4ad2980ca64931b683673444454bJens Axboe
185093bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#if defined(WIN32)
1851905c78b90f92bab91555313f7b4bd83d18246139Jens Axboe	WSADATA wsd;
18523c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe	WSAStartup(MAKEWORD(2, 2), &wsd);
185393bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#endif
185493bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran
1855402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!pidfile)
1856e46d809110bd4ad2980ca64931b683673444454bJens Axboe		return fio_server();
1857e46d809110bd4ad2980ca64931b683673444454bJens Axboe
185813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (check_existing_pidfile(pidfile)) {
185913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: pidfile %s exists and server appears alive\n",
186013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe								pidfile);
1861b8ba87ac231c3facccb1e5b0e8b1b88dd162f8f3Jens Axboe		free(pidfile);
186213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return -1;
186313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
186413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1865e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid = fork();
1866e46d809110bd4ad2980ca64931b683673444454bJens Axboe	if (pid < 0) {
186713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: failed server fork: %s", strerror(errno));
1868402668f3e05259bfc135fc097136428feda01006Jens Axboe		free(pidfile);
1869c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
1870402668f3e05259bfc135fc097136428feda01006Jens Axboe	} else if (pid) {
18710f7f9a918590b45589224568245f75e2dbff9e14Jens Axboe		ret = write_pid(pid, pidfile);
1872b8ba87ac231c3facccb1e5b0e8b1b88dd162f8f3Jens Axboe		free(pidfile);
18735ea735526bba5a6471a8b3bb347d5700cc868bdfJens Axboe		_exit(ret);
1874402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1875e46d809110bd4ad2980ca64931b683673444454bJens Axboe
1876e46d809110bd4ad2980ca64931b683673444454bJens Axboe	setsid();
187713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
187813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	log_syslog = 1;
1879e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDIN_FILENO);
1880e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDOUT_FILENO);
1881e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDERR_FILENO);
1882e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_out = NULL;
1883e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_err = NULL;
1884402668f3e05259bfc135fc097136428feda01006Jens Axboe
1885402668f3e05259bfc135fc097136428feda01006Jens Axboe	ret = fio_server();
1886402668f3e05259bfc135fc097136428feda01006Jens Axboe
1887402668f3e05259bfc135fc097136428feda01006Jens Axboe	closelog();
1888402668f3e05259bfc135fc097136428feda01006Jens Axboe	unlink(pidfile);
1889402668f3e05259bfc135fc097136428feda01006Jens Axboe	free(pidfile);
1890402668f3e05259bfc135fc097136428feda01006Jens Axboe	return ret;
1891e46d809110bd4ad2980ca64931b683673444454bJens Axboe}
189287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1893bebe639808147d587bbe776566d390b9ff98773fJens Axboevoid fio_server_set_arg(const char *arg)
189487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
189587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_server_arg = strdup(arg);
189687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
1897