server.c revision 3c3ed070502bbfec387ded2c43d5e4559ca24a63
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 <fcntl.h>
850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/poll.h>
950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/types.h>
1050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/wait.h>
11d05c4a03365f1b677c05840865e67ffaf2c5b05bJens Axboe#include <sys/socket.h>
1287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/stat.h>
1387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe#include <sys/un.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>
191b42725f06f8906b9b99381da3490484f59df28aJens Axboe#include <zlib.h>
2050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
2150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h"
22132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h"
23fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h"
24c7c6cb4cb3114ec4ce3107e15c184e161b50122eJens Axboe#include "lib/ieee754.h"
2589cf1480594858ad4e02499834c04fe48ff0a89dJens Axboe
2689cf1480594858ad4e02499834c04fe48ff0a89dJens Axboe#include "fio_version.h"
2750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
285adc2447a8d52322981da4cd364a560bbd9d8351Stephen M. Cameronint fio_net_port = FIO_NET_PORT;
2950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
30009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0;
31009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
3246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1;
3387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *fio_server_arg;
3487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *bind_sock;
3587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic struct sockaddr_in saddr_in;
36811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic struct sockaddr_in6 saddr_in6;
37811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic int use_ipv6;
3837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
39122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestruct fio_fork_item {
40122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct flist_head list;
41122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int exitval;
42122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int signal;
43122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int exited;
44122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid_t pid;
45122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe};
46122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
47122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe/* Created on fork on new connection */
48122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic FLIST_HEAD(conn_list);
49122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
50122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe/* Created on job fork from connection */
51122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic FLIST_HEAD(job_list);
52122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
5389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic const char *fio_server_ops[FIO_NET_CMD_NR] = {
5489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"",
5589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"QUIT",
5689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"EXIT",
5789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOB",
5889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOBLINE",
5989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TEXT",
6089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TS",
6189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"GS",
6289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"SEND_ETA",
6389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"ETA",
6489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"PROBE",
6589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"START",
66d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"STOP",
67d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"DISK_UTIL",
68b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	"SERVER_START",
69807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe	"ADD_JOB",
70b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	"CMD_RUN"
71c70e63e5a86e524a60662d6538803c5e18ab7a4fJens Axboe	"CMD_IOLOG",
7289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe};
7389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
7489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeconst char *fio_server_op(unsigned int op)
7589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
7689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	static char buf[32];
7789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
7889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (op < FIO_NET_CMD_NR)
7989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_server_ops[op];
8089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
8189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	sprintf(buf, "UNKNOWN/%d", op);
8289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return buf;
8389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
8489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
855235f62680ba4be74d56805eb54c3af4de28e556Jens Axboestatic ssize_t iov_total_len(const struct iovec *iov, int count)
86132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
875235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	ssize_t ret = 0;
88794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
895235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	while (count--) {
905235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe		ret += iov->iov_len;
915235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe		iov++;
925235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	}
935235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
945235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	return ret;
955235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe}
96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
975235f62680ba4be74d56805eb54c3af4de28e556Jens Axboestatic int fio_sendv_data(int sk, struct iovec *iov, int count)
985235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe{
995235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	ssize_t total_len = iov_total_len(iov, count);
1005235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	ssize_t ret;
1015235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1025235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	do {
1035235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe		ret = writev(sk, iov, count);
104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
1055235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			total_len -= ret;
1065235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			if (!total_len)
107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
1085235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1095235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			while (ret) {
1105235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				if (ret >= iov->iov_len) {
1115235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe					ret -= iov->iov_len;
1125235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe					iov++;
1135235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe					continue;
1145235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				}
1155235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				iov->iov_base += ret;
1165235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				iov->iov_len -= ret;
1175235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe				ret = 0;
1185235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe			}
119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
120132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
122132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
1237b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
1247b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
125132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
126132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1275235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	if (!total_len)
128132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1308b4e61b27203fff2cc68a967ae3f6cacaca71e43Jens Axboe	if (errno)
1318b4e61b27203fff2cc68a967ae3f6cacaca71e43Jens Axboe		return -errno;
1328b4e61b27203fff2cc68a967ae3f6cacaca71e43Jens Axboe
133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 1;
134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1365235f62680ba4be74d56805eb54c3af4de28e556Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len)
1375235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe{
1385235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	struct iovec iov = { .iov_base = (void *) p, .iov_len = len };
1395235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1405235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_FRAGMENT_PDU);
1415235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
1425235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe	return fio_sendv_data(sk, &iov, 1);
1435235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe}
1445235f62680ba4be74d56805eb54c3af4de28e556Jens Axboe
145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len)
146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = recv(sk, p, len, MSG_WAITALL);
149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
154132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
155132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
156132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
157132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
158132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
159132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
1607b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
1617b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
162132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
163132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
164132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
165132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
166132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
167132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return -1;
168132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
169132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
170132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd)
171132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
172fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
173132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
174fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16);
175fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16);
176132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
17725dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	crc = fio_crc16(cmd, FIO_NET_CMD_CRC_SZ);
178fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != cmd->cmd_crc16) {
179132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on command (got %x, wanted %x)\n",
180fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				cmd->cmd_crc16, crc);
181132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
182132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
183132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
184132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->version	= le16_to_cpu(cmd->version);
185132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->opcode	= le16_to_cpu(cmd->opcode);
186132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->flags	= le32_to_cpu(cmd->flags);
187af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	cmd->tag	= le64_to_cpu(cmd->tag);
188132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->pdu_len	= le32_to_cpu(cmd->pdu_len);
189132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
190132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->version) {
191fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	case FIO_SERVER_VER:
192132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
193132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
194132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: bad server cmd version %d\n", cmd->version);
195132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
196132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
197132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
198b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	if (cmd->pdu_len > FIO_SERVER_MAX_FRAGMENT_PDU) {
199132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: command payload too large: %u\n", cmd->pdu_len);
200132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
201132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
202132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
203132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
204132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
205132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
206a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
207a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands
208a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
209e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk)
210132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
211a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct fio_net_cmd cmd, *cmdret = NULL;
212a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	size_t cmd_size = 0, pdu_offset = 0;
213fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
214a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret, first = 1;
215a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	void *pdu = NULL;
216132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
217a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	do {
218a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, &cmd, sizeof(cmd));
219a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
220a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
221132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
222a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* We have a command, verify it and swap if need be */
223a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = verify_convert_cmd(&cmd);
224a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
225a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
226132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
2270b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (first) {
2280b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			/* if this is text, add room for \0 at the end */
2290b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			cmd_size = sizeof(cmd) + cmd.pdu_len + 1;
2300b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			assert(!cmdret);
2310b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		} else
232a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			cmd_size += cmd.pdu_len;
233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
234a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = realloc(cmdret, cmd_size);
235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
236a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (first)
237a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			memcpy(cmdret, &cmd, sizeof(cmd));
23867f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		else if (cmdret->opcode != cmd.opcode) {
23967f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			log_err("fio: fragment opcode mismatch (%d != %d)\n",
24067f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe					cmdret->opcode, cmd.opcode);
24167f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			ret = 1;
24267f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			break;
24367f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		}
244a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
245a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (!cmd.pdu_len)
246a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
247a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
248a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* There's payload, get it */
249a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu = (void *) cmdret->payload + pdu_offset;
250a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, pdu, cmd.pdu_len);
251a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
252a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
253a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
254a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* Verify payload crc */
25525dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe		crc = fio_crc16(pdu, cmd.pdu_len);
256a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (crc != cmd.pdu_crc16) {
257a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("fio: server bad crc on payload ");
258a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc);
259a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			ret = 1;
260a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
261a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		}
262a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
263a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu_offset += cmd.pdu_len;
264817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe		if (!first)
265817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe			cmdret->pdu_len += cmd.pdu_len;
266a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		first = 0;
267a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	} while (cmd.flags & FIO_NET_CMD_F_MORE);
268132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
269a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	if (ret) {
270a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		free(cmdret);
271a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = NULL;
2720b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	} else if (cmdret) {
2730b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* zero-terminate text input */
274084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe		if (cmdret->pdu_len) {
275084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe			if (cmdret->opcode == FIO_NET_CMD_TEXT) {
276084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe				struct cmd_text_pdu *pdu = (struct cmd_text_pdu *) cmdret->payload;
277084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe				char *buf = (char *) pdu->buf;
2780b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
2793c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe				buf[pdu->buf_len] = '\0';
280084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe			} else if (cmdret->opcode == FIO_NET_CMD_JOB) {
28146bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe				struct cmd_job_pdu *pdu = (struct cmd_job_pdu *) cmdret->payload;
28246bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe				char *buf = (char *) pdu->buf;
28346bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe				int len = le32_to_cpu(pdu->buf_len);
284084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
28546bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe				buf[len] = '\0';
286084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe			}
2870b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		}
288084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
2890b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* frag flag is internal */
290a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret->flags &= ~FIO_NET_CMD_F_MORE;
2910b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	}
292a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
293a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	return cmdret;
294132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
295132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
29653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboevoid fio_net_cmd_crc_pdu(struct fio_net_cmd *cmd, const void *pdu)
297132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
298132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	uint32_t pdu_len;
299132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
30025dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	cmd->cmd_crc16 = __cpu_to_le16(fio_crc16(cmd, FIO_NET_CMD_CRC_SZ));
301132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
302132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	pdu_len = le32_to_cpu(cmd->pdu_len);
3031b42725f06f8906b9b99381da3490484f59df28aJens Axboe	cmd->pdu_crc16 = __cpu_to_le16(fio_crc16(pdu, pdu_len));
3041b42725f06f8906b9b99381da3490484f59df28aJens Axboe}
3051b42725f06f8906b9b99381da3490484f59df28aJens Axboe
3061b42725f06f8906b9b99381da3490484f59df28aJens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd)
3071b42725f06f8906b9b99381da3490484f59df28aJens Axboe{
3081b42725f06f8906b9b99381da3490484f59df28aJens Axboe	fio_net_cmd_crc_pdu(cmd, cmd->payload);
309132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
310132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
311af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
312af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		     uint64_t tag)
313794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{
3147f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	struct fio_net_cmd *cmd = NULL;
3157f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	size_t this_len, cur_len = 0;
316794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	int ret;
317794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
318794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	do {
319794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		this_len = size;
320b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		if (this_len > FIO_SERVER_MAX_FRAGMENT_PDU)
321b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe			this_len = FIO_SERVER_MAX_FRAGMENT_PDU;
322794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
3237f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		if (!cmd || cur_len < sizeof(*cmd) + this_len) {
3247f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			if (cmd)
3257f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe				free(cmd);
3267f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
3277f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cur_len = sizeof(*cmd) + this_len;
3287f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cmd = malloc(cur_len);
3297f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		}
330794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
331af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		fio_init_net_cmd(cmd, opcode, buf, this_len, tag);
332794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
333794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len < size)
334ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe			cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE);
335794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
336794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_net_cmd_crc(cmd);
337794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
338794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
339794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		size -= this_len;
340794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		buf += this_len;
341794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	} while (!ret && size);
342794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
3437f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	if (cmd)
3447f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		free(cmd);
3457f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
346794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	return ret;
347794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe}
348794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
34989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag)
350132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
351178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe	struct fio_net_cmd cmd;
352132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
353af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_init_net_cmd(&cmd, opcode, NULL, 0, tag);
354132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fio_net_cmd_crc(&cmd);
355132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
356132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return fio_send_data(sk, &cmd, sizeof(cmd));
357132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
358132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
35989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe/*
36089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * If 'list' is non-NULL, then allocate and store the sent command for
36189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * later verification.
36289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe */
36389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag,
36489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			    struct flist_head *list)
36589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
36689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct fio_net_int_cmd *cmd;
36789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret;
36889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
36989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (!list)
37089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_net_send_simple_stack_cmd(sk, opcode, tag);
37189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
37289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	cmd = malloc(sizeof(*cmd));
37389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
374df380934e53c645b4b7cdec882b512b4d20ebc14Jens Axboe	fio_init_net_cmd(&cmd->cmd, opcode, NULL, 0, (uintptr_t) cmd);
37589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_net_cmd_crc(&cmd->cmd);
37689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
37789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	INIT_FLIST_HEAD(&cmd->list);
37889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	gettimeofday(&cmd->tv, NULL);
37989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	cmd->saved_tag = tag;
38089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
38189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	ret = fio_send_data(sk, &cmd->cmd, sizeof(cmd->cmd));
38289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (ret) {
38389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		free(cmd);
38489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return ret;
38589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
38689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
38789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_add_tail(&cmd->list, list);
38889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return 0;
38989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
39089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
391122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboeint fio_net_send_quit(int sk)
392437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{
39346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: sending quit\n");
394122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
3958c95307bd5f72720460ee4a46519b9a1b474e7cdJens Axboe	return fio_net_send_simple_cmd(sk, FIO_NET_CMD_QUIT, 0, NULL);
396437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe}
397437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe
398122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboeint fio_net_send_stop(int sk, int error, int signal)
399132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
40011e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	struct cmd_end_pdu epdu;
401122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
402122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	dprint(FD_NET, "server: sending stop (%d, %d)\n", error, signal);
403122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
404122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	epdu.error = __cpu_to_le32(error);
405122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	epdu.signal = __cpu_to_le32(signal);
4068c95307bd5f72720460ee4a46519b9a1b474e7cdJens Axboe	return fio_net_send_cmd(sk, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), 0);
407122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
408122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
409122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_add_fork_item(pid_t pid, struct flist_head *list)
410122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
411122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct fio_fork_item *ffi;
412122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
413122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi = malloc(sizeof(*ffi));
414122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->exitval = 0;
415122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->signal = 0;
416122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->exited = 0;
417122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->pid = pid;
418122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_add_tail(&ffi->list, list);
419122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
420122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
421122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_add_conn_pid(pid_t pid)
422122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
423122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	dprint(FD_NET, "server: forked off connection job (pid=%u)\n", pid);
424122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_server_add_fork_item(pid, &conn_list);
425122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
426122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
427122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_add_job_pid(pid_t pid)
428122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
429122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	dprint(FD_NET, "server: forked off job job (pid=%u)\n", pid);
430122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_server_add_fork_item(pid, &job_list);
431122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
432122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
433122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_check_fork_item(struct fio_fork_item *ffi)
434122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
435122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int ret, status;
436122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
437122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ret = waitpid(ffi->pid, &status, WNOHANG);
438122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	if (ret < 0) {
439122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (errno == ECHILD) {
440122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: connection pid %u disappeared\n", ffi->pid);
441122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
442122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		} else
443122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: waitpid: %s\n", strerror(errno));
444122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	} else if (ret == ffi->pid) {
445122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (WIFSIGNALED(status)) {
446122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->signal = WTERMSIG(status);
447122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
448122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
449122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (WIFEXITED(status)) {
450122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (WEXITSTATUS(status))
451122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				ffi->exitval = WEXITSTATUS(status);
452122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
453122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
454122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
455122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
456122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
457122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_fork_item_done(struct fio_fork_item *ffi)
458122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
459122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	dprint(FD_NET, "pid %u exited, sig=%u, exitval=%d\n", ffi->pid, ffi->signal, ffi->exitval);
460122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
461122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	/*
462122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	 * Fold STOP and QUIT...
463122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	 */
464122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_stop(server_fd, ffi->exitval, ffi->signal);
465122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_quit(server_fd);
466122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_del(&ffi->list);
467122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	free(ffi);
468122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
469122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
470541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboestatic void fio_server_check_fork_items(struct flist_head *list)
471122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
472122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct flist_head *entry, *tmp;
473122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct fio_fork_item *ffi;
474122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
475122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_for_each_safe(entry, tmp, list) {
476122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		ffi = flist_entry(entry, struct fio_fork_item, list);
477122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
478122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_check_fork_item(ffi);
479122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
480122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (ffi->exited)
481122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			fio_server_fork_item_done(ffi);
482122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
483122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
484122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
485122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_check_jobs(void)
486122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
487541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe	fio_server_check_fork_items(&job_list);
488122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
489122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
490122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_check_conns(void)
491122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
492541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe	fio_server_check_fork_items(&conn_list);
493122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
494122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
495122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic int handle_run_cmd(struct fio_net_cmd *cmd)
496122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
497122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid_t pid;
498a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret;
499132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
500122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	set_genesis_time();
50111e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
502122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid = fork();
503122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	if (pid) {
504122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_add_job_pid(pid);
505122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		return 0;
506122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
50711e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
508122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ret = fio_backend();
509122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	_exit(ret);
51081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
51181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
512b9d2f30a214ebd274340f888739be250838d63c2Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd)
513b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe{
51446bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	struct cmd_job_pdu *pdu = (struct cmd_job_pdu *) cmd->payload;
51546bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	void *buf = pdu->buf;
516b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct cmd_start_pdu spdu;
517b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
51846bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->buf_len = le32_to_cpu(pdu->buf_len);
51946bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->client_type = le32_to_cpu(pdu->client_type);
52046bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe
52146bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	if (parse_jobs_ini(buf, 1, 0, pdu->client_type)) {
522122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_net_send_quit(server_fd);
523b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		return -1;
524b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	}
525b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
526b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
527b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
528b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return 0;
529b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe}
530b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
53181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd)
53281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
533fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	void *pdu = cmd->payload;
534fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_single_line_pdu *cslp;
535fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_line_pdu *clp;
536fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	unsigned long offset;
537b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct cmd_start_pdu spdu;
538fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	char **argv;
539b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	int i;
54081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
541fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp = pdu;
542fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp->lines = le16_to_cpu(clp->lines);
54346bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	clp->client_type = le16_to_cpu(clp->client_type);
544fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	argv = malloc(clp->lines * sizeof(char *));
545fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	offset = sizeof(*clp);
54681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
547fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	dprint(FD_NET, "server: %d command line args\n", clp->lines);
54839e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe
549fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	for (i = 0; i < clp->lines; i++) {
550fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp = pdu + offset;
551fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		argv[i] = (char *) cslp->text;
552fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
553fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		offset += sizeof(*cslp) + le16_to_cpu(cslp->len);
55439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe		dprint(FD_NET, "server: %d: %s\n", i, argv[i]);
55539e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	}
55681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
55746bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	if (parse_cmd_line(clp->lines, argv, clp->client_type)) {
558122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_net_send_quit(server_fd);
559fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		free(argv);
56081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
561e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
56281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
563fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	free(argv);
564fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
565b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
566b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
567b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return 0;
568132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
569132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
570c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd)
571c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{
572c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	struct cmd_probe_pdu probe;
573c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
57489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: sending probe reply\n");
57589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
576c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	memset(&probe, 0, sizeof(probe));
577c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	gethostname((char *) probe.hostname, sizeof(probe.hostname));
5786eb2479194603184f393057ea10326643edc7169Jens Axboe#ifdef FIO_BIG_ENDIAN
5796eb2479194603184f393057ea10326643edc7169Jens Axboe	probe.bigendian = 1;
5806eb2479194603184f393057ea10326643edc7169Jens Axboe#endif
58181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_major = FIO_MAJOR;
58281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_minor = FIO_MINOR;
58381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_patch = FIO_PATCH;
584c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
585cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.os	= FIO_OS;
586cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.arch	= FIO_ARCH;
587cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe
58838fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe	probe.bpp	= sizeof(void *);
58938fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe
59089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), cmd->tag);
591af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe}
592af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
593af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic int handle_send_eta_cmd(struct fio_net_cmd *cmd)
594af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{
595af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct jobs_eta *je;
596af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	size_t size;
597af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	int i;
598af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
599b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	if (!thread_number)
600b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe		return 0;
601b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe
602b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	size = sizeof(*je) + thread_number * sizeof(char) + 1;
6037f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	je = malloc(size);
6047f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	memset(je, 0, size);
605af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
606af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	if (!calc_thread_status(je, 1)) {
607af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		free(je);
608af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return 0;
609af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
610af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
611af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "server sending status\n");
612af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
613af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_running		= cpu_to_le32(je->nr_running);
614af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_ramp		= cpu_to_le32(je->nr_ramp);
615af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_pending		= cpu_to_le32(je->nr_pending);
616af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->files_open		= cpu_to_le32(je->files_open);
617af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
618af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	for (i = 0; i < 2; i++) {
6193e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->m_rate[i]	= cpu_to_le32(je->m_rate[i]);
6203e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->t_rate[i]	= cpu_to_le32(je->t_rate[i]);
6213e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->m_iops[i]	= cpu_to_le32(je->m_iops[i]);
6223e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->t_iops[i]	= cpu_to_le32(je->t_iops[i]);
623af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->rate[i]	= cpu_to_le32(je->rate[i]);
624af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->iops[i]	= cpu_to_le32(je->iops[i]);
625af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
626af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
627c1970b907ff0cb819de5607bc120d8acb527eb98Jens Axboe	je->elapsed_sec		= cpu_to_le64(je->elapsed_sec);
628af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->eta_sec		= cpu_to_le64(je->eta_sec);
6298c621fb2aa4b99c8a8b6b62435d713ab39b52c62Jens Axboe	je->nr_threads		= cpu_to_le32(je->nr_threads);
630af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
6317f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, cmd->tag);
632af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	free(je);
633af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	return 0;
634c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe}
635c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
636132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd)
637132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
638132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret;
639132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
64089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%lx\n",
64189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			fio_server_op(cmd->opcode), cmd->pdu_len, cmd->tag);
64246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
643132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->opcode) {
644132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_QUIT:
645cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe		fio_terminate_threads(TERMINATE_ALL);
646c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
647d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe	case FIO_NET_CMD_EXIT:
648132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		exit_backend = 1;
649c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
650132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_JOB:
6510b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		ret = handle_job_cmd(cmd);
652132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
65381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	case FIO_NET_CMD_JOBLINE:
65481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		ret = handle_jobline_cmd(cmd);
65581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		break;
656c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	case FIO_NET_CMD_PROBE:
657c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		ret = handle_probe_cmd(cmd);
658c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		break;
659af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	case FIO_NET_CMD_SEND_ETA:
660af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		ret = handle_send_eta_cmd(cmd);
661af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		break;
662b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	case FIO_NET_CMD_RUN:
663b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		ret = handle_run_cmd(cmd);
664b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		break;
665132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
6663c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe		log_err("fio: unknown opcode: %s\n", fio_server_op(cmd->opcode));
667132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = 1;
668132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
669132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
670132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
671132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
672132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
673122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic int handle_connection(int sk)
674132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
675132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd *cmd = NULL;
676132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
677132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
678122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	reset_fio_state();
679122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	INIT_FLIST_HEAD(&job_list);
680122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	server_fd = sk;
681122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
682132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* read forever */
683132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	while (!exit_backend) {
684e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		struct pollfd pfd = {
685e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.fd	= sk,
686e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.events	= POLLIN,
687e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		};
688e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
689e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		ret = 0;
690e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		do {
691541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			int timeout = 1000;
692541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
693541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			if (!flist_empty(&job_list))
694541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe				timeout = 100;
6953c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe
696541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			ret = poll(&pfd, 1, timeout);
697e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (ret < 0) {
698e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				if (errno == EINTR)
699e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe					break;
700e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
701e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
70219c65179fad3e0a32a450401ba7d312169627fddJens Axboe			} else if (!ret) {
703122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				fio_server_check_jobs();
704e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				continue;
70519c65179fad3e0a32a450401ba7d312169627fddJens Axboe			}
706e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
707e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & POLLIN)
708e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
709e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & (POLLERR|POLLHUP)) {
710e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				ret = 1;
711e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
712e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			}
71319c65179fad3e0a32a450401ba7d312169627fddJens Axboe		} while (!exit_backend);
714e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
715122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_check_jobs();
716122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
717e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		if (ret < 0)
718e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			break;
719e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
720e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		cmd = fio_net_recv_cmd(sk);
721132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (!cmd) {
722c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe			ret = -1;
723132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
724132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		}
725132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
726132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = handle_command(cmd);
727132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
728132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
729132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
730132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
731c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe		cmd = NULL;
732132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
733132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
734132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd)
735132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
736132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
737122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	close(sk);
738122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	_exit(ret);
739cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
740cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
74150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
74250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
743bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	struct sockaddr_in addr;
7445ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe	fio_socklen_t len = sizeof(addr);
745009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
746122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int ret = 0, sk, flags, exitval = 0;
74750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
74860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server enter accept loop\n");
74960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
750009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags = fcntl(listen_sk, F_GETFL);
751009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags |= O_NONBLOCK;
752009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	fcntl(listen_sk, F_SETFL, flags);
753009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
754122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	while (!exit_backend) {
755122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pid_t pid;
756009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
757122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pfd.fd = listen_sk;
758122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pfd.events = POLLIN;
759122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		do {
760541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			int timeout = 1000;
761541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
762541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			if (!flist_empty(&conn_list))
763541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe				timeout = 100;
764541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
765541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			ret = poll(&pfd, 1, timeout);
766122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (ret < 0) {
767122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				if (errno == EINTR)
768122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe					break;
769122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
770122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				break;
771122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			} else if (!ret) {
772122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				fio_server_check_conns();
773122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				continue;
774122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			}
775009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
776122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (pfd.revents & POLLIN)
777122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				break;
778122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		} while (!exit_backend);
77950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
780122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_check_conns();
78146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
782122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (exit_backend || ret < 0)
783122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			break;
784122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
785122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		sk = accept(listen_sk, (struct sockaddr *) &addr, &len);
786122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (sk < 0) {
787122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: accept: %s\n", strerror(errno));
788122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			return -1;
789122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
79037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
791122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr));
79250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
793122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pid = fork();
794122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (pid) {
795122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			close(sk);
796122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			fio_server_add_conn_pid(pid);
797122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			continue;
798122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
7995c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
800122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		/* exits */
801122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		handle_connection(sk);
802122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
8035c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
804132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return exitval;
80550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
80650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
807084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboeint fio_server_text_output(int level, const char *buf, size_t len)
80837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
809084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	struct cmd_text_pdu *pdu;
810084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	unsigned int tlen;
811084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	struct timeval tv;
812084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
813084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	if (server_fd == -1)
814084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe		return log_local_buf(buf, len);
815084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
816084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	tlen = sizeof(*pdu) + len;
817084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu = malloc(tlen);
818084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
819084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->level	= __cpu_to_le32(level);
820084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->buf_len	= __cpu_to_le32(len);
821084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
822084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	gettimeofday(&tv, NULL);
823084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_sec	= __cpu_to_le64(tv.tv_sec);
824084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_usec	= __cpu_to_le64(tv.tv_usec);
825337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe
826084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	memcpy(pdu->buf, buf, len);
827084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
828084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, pdu, tlen, 0);
829084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	free(pdu);
830084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	return len;
831142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe}
832142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
833a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src)
834a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
835a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->max_val	= cpu_to_le64(src->max_val);
836a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->min_val	= cpu_to_le64(src->min_val);
837a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->samples	= cpu_to_le64(src->samples);
838802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
839802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	/*
840802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 * Encode to IEEE 754 for network transfer
841802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 */
842802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->mean.u.i	= __cpu_to_le64(fio_double_to_uint64(src->mean.u.f));
843802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->S.u.i	= __cpu_to_le64(fio_double_to_uint64(src->S.u.f));
844a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
845a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
846a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
847a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
848a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i;
849a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
850a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
851a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_run[i]		= cpu_to_le64(src->max_run[i]);
852a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_run[i]		= cpu_to_le64(src->min_run[i]);
853a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_bw[i]		= cpu_to_le64(src->max_bw[i]);
854a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_bw[i]		= cpu_to_le64(src->min_bw[i]);
855a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_kb[i]		= cpu_to_le64(src->io_kb[i]);
856a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->agg[i]		= cpu_to_le64(src->agg[i]);
857a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
858a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
859a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->kb_base	= cpu_to_le32(src->kb_base);
860a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= cpu_to_le32(src->groupid);
861a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
862a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
863a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
864a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats
865a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload.
866a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
867a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
868a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
869a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct cmd_ts_pdu p;
870a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i, j;
871a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
87260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending end stats\n");
87360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
874317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe	memset(&p, 0, sizeof(p));
875317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe
876a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.name, ts->name);
877a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.verror, ts->verror);
878a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.description, ts->description);
879a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
8802f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.error		= cpu_to_le32(ts->error);
8812f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.thread_number	= cpu_to_le32(ts->thread_number);
8822f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.groupid		= cpu_to_le32(ts->groupid);
8832f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.pid		= cpu_to_le32(ts->pid);
8842f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.members		= cpu_to_le32(ts->members);
885a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
886a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
887a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]);
888a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]);
889a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]);
890a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]);
891a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
892a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
893a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.usr_time		= cpu_to_le64(ts->usr_time);
894a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.sys_time		= cpu_to_le64(ts->sys_time);
895a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.ctx		= cpu_to_le64(ts->ctx);
896a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.minf		= cpu_to_le64(ts->minf);
897a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.majf		= cpu_to_le64(ts->majf);
898a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.clat_percentiles	= cpu_to_le64(ts->clat_percentiles);
899802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
900802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
901cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *src = &ts->percentile_list[i];
902cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *dst = &p.ts.percentile_list[i];
903802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
904cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		dst->u.i = __cpu_to_le64(fio_double_to_uint64(src->u.f));
905802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	}
906a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
907a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
908a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_map[i]	= cpu_to_le32(ts->io_u_map[i]);
909a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_submit[i]	= cpu_to_le32(ts->io_u_submit[i]);
910a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_complete[i]	= cpu_to_le32(ts->io_u_complete[i]);
911a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
912a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
913a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
914a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_u[i]	= cpu_to_le32(ts->io_u_lat_u[i]);
915a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_m[i]	= cpu_to_le32(ts->io_u_lat_m[i]);
916a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
917a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
918a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++)
919a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
920a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]);
921a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
922a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 3; i++) {
923a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.total_io_u[i]	= cpu_to_le64(ts->total_io_u[i]);
92493eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe		p.ts.short_io_u[i]	= cpu_to_le64(ts->short_io_u[i]);
925a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
926a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
92793eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe	p.ts.total_submit	= cpu_to_le64(ts->total_submit);
928a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_complete	= cpu_to_le64(ts->total_complete);
929a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
930a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
931a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_bytes[i]	= cpu_to_le64(ts->io_bytes[i]);
932a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.runtime[i]		= cpu_to_le64(ts->runtime[i]);
933a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
934a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
935a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_run_time	= cpu_to_le64(ts->total_run_time);
936a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.continue_on_error	= cpu_to_le16(ts->continue_on_error);
937a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_err_count	= cpu_to_le64(ts->total_err_count);
938ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.first_error	= cpu_to_le32(ts->first_error);
939ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.kb_base		= cpu_to_le32(ts->kb_base);
940a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
941a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&p.rs, rs);
942a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
943af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0);
944a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
945a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
946a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs)
947a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
948a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct group_run_stats gs;
949a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
95060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending group run stats\n");
95160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
952a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&gs, rs);
953af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0);
954cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe}
955cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
956d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src)
957d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
958d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
959d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
960d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
961d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ios[i]	= cpu_to_le32(src->ios[i]);
962d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->merges[i]	= cpu_to_le32(src->merges[i]);
963d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
964d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
965d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
966d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
967d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->io_ticks		= cpu_to_le32(src->io_ticks);
968d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
969d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->slavecount		= cpu_to_le32(src->slavecount);
970d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->max_util.u.i	= __cpu_to_le64(fio_double_to_uint64(src->max_util.u.f));
971d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
972d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
973d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src)
974d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
975d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
976d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
977d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	strcpy((char *) dst->name, (char *) src->name);
978d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
979d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
980d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ios[i]	= cpu_to_le32(src->ios[i]);
981d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->merges[i]	= cpu_to_le32(src->merges[i]);
982d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
983d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
984d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
985d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
986d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->io_ticks		= cpu_to_le32(src->io_ticks);
987d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
988d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->msec		= cpu_to_le64(src->msec);
989d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
990d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
991d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboevoid fio_server_send_du(void)
992d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
993d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct disk_util *du;
994d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct flist_head *entry;
995d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct cmd_du_pdu pdu;
996d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
997d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dprint(FD_NET, "server: sending disk_util %d\n", !flist_empty(&disk_list));
998d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
9990766d92e06a119eea489e74d80d5840813559752Jens Axboe	memset(&pdu, 0, sizeof(pdu));
10000766d92e06a119eea489e74d80d5840813559752Jens Axboe
1001d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	flist_for_each(entry, &disk_list) {
1002d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		du = flist_entry(entry, struct disk_util, list);
1003d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1004d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_dus(&pdu.dus, &du->dus);
1005d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_agg(&pdu.agg, &du->agg);
1006d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1007d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), 0);
1008d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
1009d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1010d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
101153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe/*
101253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe * Send a command with a separate PDU, not inlined in the command
101353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe */
101453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboestatic int fio_send_cmd_ext_pdu(int sk, uint16_t opcode, const void *buf,
101553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe				off_t size, uint64_t tag, uint32_t flags)
101653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe{
101753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	struct fio_net_cmd cmd;
101853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	struct iovec iov[2];
101953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
102053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[0].iov_base = &cmd;
102153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[0].iov_len = sizeof(cmd);
102253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[1].iov_base = (void *) buf;
102353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[1].iov_len = size;
102453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
102553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	__fio_init_net_cmd(&cmd, opcode, size, tag);
102653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	cmd.flags = __cpu_to_le32(flags);
102753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	fio_net_cmd_crc_pdu(&cmd, buf);
102853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
10298c95307bd5f72720460ee4a46519b9a1b474e7cdJens Axboe	return fio_sendv_data(sk, iov, 2);
103053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe}
103153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
10321b42725f06f8906b9b99381da3490484f59df28aJens Axboeint fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
10331b42725f06f8906b9b99381da3490484f59df28aJens Axboe{
1034f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	struct cmd_iolog_pdu pdu;
10351b42725f06f8906b9b99381da3490484f59df28aJens Axboe	z_stream stream;
10361b42725f06f8906b9b99381da3490484f59df28aJens Axboe	void *out_pdu;
103753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	int i, ret = 0;
10381b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10392f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.thread_number = cpu_to_le32(td->thread_number);
1040f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	pdu.nr_samples = __cpu_to_le32(log->nr_samples);
1041f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	pdu.log_type = cpu_to_le32(log->log_type);
1042f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	strcpy((char *) pdu.name, name);
10431b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10441b42725f06f8906b9b99381da3490484f59df28aJens Axboe	for (i = 0; i < log->nr_samples; i++) {
1045f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		struct io_sample *s = &log->log[i];
10461b42725f06f8906b9b99381da3490484f59df28aJens Axboe
1047f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->time	= cpu_to_le64(s->time);
1048f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->val	= cpu_to_le64(s->val);
1049f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->ddir	= cpu_to_le32(s->ddir);
1050f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->bs	= cpu_to_le32(s->bs);
10511b42725f06f8906b9b99381da3490484f59df28aJens Axboe	}
10521b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10531b42725f06f8906b9b99381da3490484f59df28aJens Axboe	/*
10541b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * Dirty - since the log is potentially huge, compress it into
10551b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * FIO_SERVER_MAX_FRAGMENT_PDU chunks and let the receiving
10561b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * side defragment it.
10571b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 */
10581b42725f06f8906b9b99381da3490484f59df28aJens Axboe	out_pdu = malloc(FIO_SERVER_MAX_FRAGMENT_PDU);
10591b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10601b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zalloc = Z_NULL;
10611b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zfree = Z_NULL;
10621b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.opaque = Z_NULL;
10631b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10641b42725f06f8906b9b99381da3490484f59df28aJens Axboe	if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
106553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		ret = 1;
106653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		goto err;
10671b42725f06f8906b9b99381da3490484f59df28aJens Axboe	}
10681b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10691b42725f06f8906b9b99381da3490484f59df28aJens Axboe	/*
1070f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	 * Send header first, it's not compressed.
10711b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 */
107253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, &pdu,
107353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe					sizeof(pdu), 0, FIO_NET_CMD_F_MORE);
107453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	if (ret)
107553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		goto err_zlib;
10761b42725f06f8906b9b99381da3490484f59df28aJens Axboe
1077f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	stream.next_in = (void *) log->log;
1078f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	stream.avail_in = log->nr_samples * sizeof(struct io_sample);
10791b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10801b42725f06f8906b9b99381da3490484f59df28aJens Axboe	do {
108153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		unsigned int this_len, flags = 0;
108253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		int ret;
10831b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10841b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.avail_out = FIO_SERVER_MAX_FRAGMENT_PDU;
10851b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.next_out = out_pdu;
10863c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		ret = deflate(&stream, Z_FINISH);
10873c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		/* may be Z_OK, or Z_STREAM_END */
10883c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		if (ret < 0)
10893c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe			goto err_zlib;
10901b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10911b42725f06f8906b9b99381da3490484f59df28aJens Axboe		this_len = FIO_SERVER_MAX_FRAGMENT_PDU - stream.avail_out;
10921b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10931b42725f06f8906b9b99381da3490484f59df28aJens Axboe		if (stream.avail_in)
109453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe			flags = FIO_NET_CMD_F_MORE;
10951b42725f06f8906b9b99381da3490484f59df28aJens Axboe
109653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG,
109753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe					   out_pdu, this_len, 0, flags);
109853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		if (ret)
109953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe			goto err_zlib;
11001b42725f06f8906b9b99381da3490484f59df28aJens Axboe	} while (stream.avail_in);
11011b42725f06f8906b9b99381da3490484f59df28aJens Axboe
110253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboeerr_zlib:
11031b42725f06f8906b9b99381da3490484f59df28aJens Axboe	deflateEnd(&stream);
110453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboeerr:
110553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	free(out_pdu);
110653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	return ret;
11071b42725f06f8906b9b99381da3490484f59df28aJens Axboe}
11081b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11092f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboevoid fio_server_send_add_job(struct thread_data *td)
1110807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe{
1111807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe	struct cmd_add_job_pdu pdu;
1112807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1113731e30a2551315c609c23ac107377b63c02d51faJens Axboe	memset(&pdu, 0, sizeof(pdu));
11142f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.thread_number = cpu_to_le32(td->thread_number);
11152f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.groupid = cpu_to_le32(td->groupid);
11162f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	convert_thread_options_to_net(&pdu.top, &td->o);
1117807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1118807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ADD_JOB, &pdu, sizeof(pdu), 0);
1119807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe}
1120807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1121122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboevoid fio_server_send_start(struct thread_data *td)
1122122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
1123122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	assert(server_fd != -1);
1124122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
1125122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_SERVER_START, 0, NULL);
1126122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
1127122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
112887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_ip(void)
112981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
1130811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	struct sockaddr *addr;
1131811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	fio_socklen_t socklen;
113287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, opt;
113381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1134811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6)
1135811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET6, SOCK_STREAM, 0);
1136811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	else
1137811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET, SOCK_STREAM, 0);
1138811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
113981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (sk < 0) {
114081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
114181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
114281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
114381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
114481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	opt = 1;
114581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
114681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
1147b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
114881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
114981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
115081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT
11516eb2479194603184f393057ea10326643edc7169Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
115281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
1153b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
115481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
115581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
115681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif
115781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1158811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6) {
1159811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in6;
1160811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in6);
1161811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in6.sin6_family = AF_INET6;
1162811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else {
1163811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in;
1164811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in);
1165811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in.sin_family = AF_INET;
1166811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	}
116781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1168811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (bind(sk, addr, socklen) < 0) {
116981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
1170b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
117181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
117281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
117381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
117487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
117587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
117687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
117787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_sock(void)
117887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
117987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un addr;
118087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_socklen_t len;
118187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode_t mode;
118287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
118387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
118487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = socket(AF_UNIX, SOCK_STREAM, 0);
118587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0) {
118687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: socket: %s\n", strerror(errno));
118787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
118887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
118987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
119087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode = umask(000);
119187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
119287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	memset(&addr, 0, sizeof(addr));
119387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	addr.sun_family = AF_UNIX;
119487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	strcpy(addr.sun_path, bind_sock);
119587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	unlink(bind_sock);
119687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
119787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	len = sizeof(addr.sun_family) + strlen(bind_sock) + 1;
119887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
119987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (bind(sk, (struct sockaddr *) &addr, len) < 0) {
120087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: bind: %s\n", strerror(errno));
1201b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
120287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
120387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
120487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
120587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	umask(mode);
120687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
120787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
120887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
120987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_connection(void)
121087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
1211bebe639808147d587bbe776566d390b9ff98773fJens Axboe	char bind_str[128];
121287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
121387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
121487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
121587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
121687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!bind_sock)
121787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_ip();
121887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	else
121987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_sock();
122087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
122187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
122287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return sk;
122387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1224811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (!bind_sock) {
1225811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		char *p, port[16];
1226811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		const void *src;
1227811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		int af;
1228811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1229811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (use_ipv6) {
1230811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET6;
1231811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in6.sin6_addr;
1232811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		} else {
1233811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET;
1234811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in.sin_addr;
1235811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		}
1236811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1237811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		p = (char *) inet_ntop(af, src, bind_str, sizeof(bind_str));
1238811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1239811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sprintf(port, ",%u", fio_net_port);
1240811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (p)
1241811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcat(p, port);
1242811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		else
1243811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcpy(bind_str, port);
1244811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else
1245bebe639808147d587bbe776566d390b9ff98773fJens Axboe		strcpy(bind_str, bind_sock);
1246bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1247bebe639808147d587bbe776566d390b9ff98773fJens Axboe	log_info("fio: server listening on %s\n", bind_str);
1248bebe639808147d587bbe776566d390b9ff98773fJens Axboe
124989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (listen(sk, 0) < 0) {
125081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
125181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
125281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
125381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
125487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
125587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
125687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
12573ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboeint fio_server_parse_host(const char *host, int *ipv6, struct in_addr *inp,
12583ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			  struct in6_addr *inp6)
12593ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
12603ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe{
12613ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	int ret = 0;
12623ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
12633ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	if (*ipv6)
12643ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = inet_pton(AF_INET6, host, inp6);
12653ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	else
12663ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = inet_pton(AF_INET, host, inp);
12673ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
12683ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	if (ret != 1) {
12693ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		struct hostent *hent;
12703ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
12713ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		hent = gethostbyname(host);
12723ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		if (!hent) {
12733ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			log_err("fio: failed to resolve <%s>\n", host);
12743ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			return 0;
12753ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		}
12763ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
12773ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		if (*ipv6) {
12783ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			if (hent->h_addrtype != AF_INET6) {
12793ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				log_info("fio: falling back to IPv4\n");
12803ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				*ipv6 = 0;
12813ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			} else
12823ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				memcpy(inp6, hent->h_addr_list[0], 16);
12833ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		}
12843ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		if (!*ipv6) {
12853ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			if (hent->h_addrtype != AF_INET) {
12863ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				log_err("fio: lookup type mismatch\n");
12873ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				return 0;
12883ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			}
12893ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			memcpy(inp, hent->h_addr_list[0], 4);
12903ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		}
12913ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = 1;
12923ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	}
12933ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
12943ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	return !(ret == 1);
12953ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe}
12963ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
1297660a2bfb0858f94633f9e567b81968981541f079Jens Axboe/*
1298660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Parse a host/ip/port string. Reads from 'str'.
1299660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
1300660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Outputs:
1301660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
1302660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv4:
1303660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp is the destination.
1304660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv6:
1305660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp6 is the dest, and *ipv6 is 1.
1306660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For local domain sockets:
1307660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the filename, *is_sock is 1.
1308660a2bfb0858f94633f9e567b81968981541f079Jens Axboe */
1309bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_server_parse_string(const char *str, char **ptr, int *is_sock,
1310811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    int *port, struct in_addr *inp,
1311811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    struct in6_addr *inp6, int *ipv6)
1312bebe639808147d587bbe776566d390b9ff98773fJens Axboe{
131376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	const char *host = str;
131476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	char *portp;
13153ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	int lport = 0;
131676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
1317bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*ptr = NULL;
1318bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*is_sock = 0;
13196d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	*port = fio_net_port;
1320811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	*ipv6 = 0;
1321bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1322bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!strncmp(str, "sock:", 5)) {
1323bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*ptr = strdup(str + 5);
1324bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*is_sock = 1;
132576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
132676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
132776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
132876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
132976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
133076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * Is it ip:<ip or host>:port
133176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
133276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strncmp(host, "ip:", 3))
133376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 3;
133476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip4:", 4))
133576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
133676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip6:", 4)) {
133776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
133876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*ipv6 = 1;
133976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	} else if (host[0] == ':') {
134076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* String is :port */
134176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host++;
134276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		lport = atoi(host);
134376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!lport || lport > 65535) {
134476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			log_err("fio: bad server port %u\n", port);
134576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			return 1;
134676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
134776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* no hostname given, we are done */
134876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
134976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
135076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
135176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
135276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
135376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * If no port seen yet, check if there's a last ':' at the end
135476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
135576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!lport) {
135676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		portp = strchr(host, ',');
135776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (portp) {
135876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			*portp = '\0';
135976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			portp++;
136076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			lport = atoi(portp);
1361bebe639808147d587bbe776566d390b9ff98773fJens Axboe			if (!lport || lport > 65535) {
1362bebe639808147d587bbe776566d390b9ff98773fJens Axboe				log_err("fio: bad server port %u\n", port);
1363bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
1364bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
1365bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
136676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
1367bebe639808147d587bbe776566d390b9ff98773fJens Axboe
136876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (lport)
136976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
1370bebe639808147d587bbe776566d390b9ff98773fJens Axboe
137176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strlen(host))
137276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
1373bebe639808147d587bbe776566d390b9ff98773fJens Axboe
137476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	*ptr = strdup(host);
1375811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
13763ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	if (fio_server_parse_host(*ptr, ipv6, inp, inp6)) {
13773ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		free(*ptr);
13783ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		*ptr = NULL;
13793ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		return 1;
1380bebe639808147d587bbe776566d390b9ff98773fJens Axboe	}
1381bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1382bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (*port == 0)
1383bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*port = fio_net_port;
1384bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1385bebe639808147d587bbe776566d390b9ff98773fJens Axboe	return 0;
1386bebe639808147d587bbe776566d390b9ff98773fJens Axboe}
1387bebe639808147d587bbe776566d390b9ff98773fJens Axboe
138887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe/*
138987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Server arg should be one of:
139087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
139187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * sock:/path/to/socket
139287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *   ip:1.2.3.4
139387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *      1.2.3.4
139487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
139587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Where sock uses unix domain sockets, and ip binds the server to
139687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * a specific interface. If no arguments are given to the server, it
139787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * uses IP and binds to 0.0.0.0.
139887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
139987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe */
140087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_handle_server_arg(void)
140187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
14026d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	int port = fio_net_port;
1403a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe	int is_sock, ret = 0;
1404bebe639808147d587bbe776566d390b9ff98773fJens Axboe
140587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
140687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
140787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!fio_server_arg)
1408a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe		goto out;
140987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
14104e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock,
1411811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&port, &saddr_in.sin_addr,
1412811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&saddr_in6.sin6_addr, &use_ipv6);
14134e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
14144e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	if (!is_sock && bind_sock) {
14154e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		free(bind_sock);
14164e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		bind_sock = NULL;
14174e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	}
14184e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
1419a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboeout:
14206d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	fio_net_port = port;
14216d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	saddr_in.sin_port = htons(port);
1422811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	saddr_in6.sin6_port = htons(port);
14234e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	return ret;
142487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
142587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
142687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_server(void)
142787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
142887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, ret;
142987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
143087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
143187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
143287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_handle_server_arg())
143387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
143487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
143587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = fio_init_server_connection();
143687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
143787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
143881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
143981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	ret = accept_loop(sk);
144087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
144181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	close(sk);
144287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
144387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_server_arg) {
144487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		free(fio_server_arg);
144587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fio_server_arg = NULL;
144687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
1447bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (bind_sock)
1448bebe639808147d587bbe776566d390b9ff98773fJens Axboe		free(bind_sock);
144987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
145081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
145181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
145281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
14537b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboevoid fio_server_got_signal(int signal)
14549abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{
14557b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	if (signal == SIGPIPE)
14567b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		server_fd = -1;
14577b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	else {
14587b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		log_info("\nfio: terminating on signal %d\n", signal);
14597b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		exit_backend = 1;
14607b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	}
14619abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe}
14629abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe
146313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int check_existing_pidfile(const char *pidfile)
146413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe{
146513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	struct stat sb;
146613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	char buf[16];
146713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid_t pid;
146813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	FILE *f;
146913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
147013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (stat(pidfile, &sb))
147113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
147213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
147313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	f = fopen(pidfile, "r");
147413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (!f)
147513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
147613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1477bfc3b17986fb80aeb5a6ea962bb38fc1509d60a8Jens Axboe	if (fread(buf, sb.st_size, 1, f) <= 0) {
147813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		fclose(f);
147913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
148013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
148113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(f);
148213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
148313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid = atoi(buf);
148413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (kill(pid, SIGCONT) < 0)
1485ea5aa1be68de71f9f02eb3d6f4db726adcafb40aJens Axboe		return errno != ESRCH;
148613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
148713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 1;
148813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe}
148913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
149013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int write_pid(pid_t pid, const char *pidfile)
1491402668f3e05259bfc135fc097136428feda01006Jens Axboe{
1492402668f3e05259bfc135fc097136428feda01006Jens Axboe	FILE *fpid;
1493402668f3e05259bfc135fc097136428feda01006Jens Axboe
1494402668f3e05259bfc135fc097136428feda01006Jens Axboe	fpid = fopen(pidfile, "w");
1495402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!fpid) {
1496402668f3e05259bfc135fc097136428feda01006Jens Axboe		log_err("fio: failed opening pid file %s\n", pidfile);
149713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
1498402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1499402668f3e05259bfc135fc097136428feda01006Jens Axboe
1500402668f3e05259bfc135fc097136428feda01006Jens Axboe	fprintf(fpid, "%u\n", (unsigned int) pid);
150113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(fpid);
150213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 0;
1503402668f3e05259bfc135fc097136428feda01006Jens Axboe}
1504402668f3e05259bfc135fc097136428feda01006Jens Axboe
1505402668f3e05259bfc135fc097136428feda01006Jens Axboe/*
1506402668f3e05259bfc135fc097136428feda01006Jens Axboe * If pidfile is specified, background us.
1507402668f3e05259bfc135fc097136428feda01006Jens Axboe */
1508402668f3e05259bfc135fc097136428feda01006Jens Axboeint fio_start_server(char *pidfile)
1509e46d809110bd4ad2980ca64931b683673444454bJens Axboe{
1510e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid_t pid;
1511402668f3e05259bfc135fc097136428feda01006Jens Axboe	int ret;
1512e46d809110bd4ad2980ca64931b683673444454bJens Axboe
151393bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#if defined(WIN32)
1514905c78b90f92bab91555313f7b4bd83d18246139Jens Axboe	WSADATA wsd;
15153c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe	WSAStartup(MAKEWORD(2, 2), &wsd);
151693bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#endif
151793bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran
1518402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!pidfile)
1519e46d809110bd4ad2980ca64931b683673444454bJens Axboe		return fio_server();
1520e46d809110bd4ad2980ca64931b683673444454bJens Axboe
152113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (check_existing_pidfile(pidfile)) {
152213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: pidfile %s exists and server appears alive\n",
152313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe								pidfile);
152413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return -1;
152513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
152613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1527e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid = fork();
1528e46d809110bd4ad2980ca64931b683673444454bJens Axboe	if (pid < 0) {
152913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: failed server fork: %s", strerror(errno));
1530402668f3e05259bfc135fc097136428feda01006Jens Axboe		free(pidfile);
1531c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
1532402668f3e05259bfc135fc097136428feda01006Jens Axboe	} else if (pid) {
153313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		int ret = write_pid(pid, pidfile);
153413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
153513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		exit(ret);
1536402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1537e46d809110bd4ad2980ca64931b683673444454bJens Axboe
1538e46d809110bd4ad2980ca64931b683673444454bJens Axboe	setsid();
153913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
154013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	log_syslog = 1;
1541e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDIN_FILENO);
1542e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDOUT_FILENO);
1543e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDERR_FILENO);
1544e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_out = NULL;
1545e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_err = NULL;
1546402668f3e05259bfc135fc097136428feda01006Jens Axboe
1547402668f3e05259bfc135fc097136428feda01006Jens Axboe	ret = fio_server();
1548402668f3e05259bfc135fc097136428feda01006Jens Axboe
1549402668f3e05259bfc135fc097136428feda01006Jens Axboe	closelog();
1550402668f3e05259bfc135fc097136428feda01006Jens Axboe	unlink(pidfile);
1551402668f3e05259bfc135fc097136428feda01006Jens Axboe	free(pidfile);
1552402668f3e05259bfc135fc097136428feda01006Jens Axboe	return ret;
1553e46d809110bd4ad2980ca64931b683673444454bJens Axboe}
155487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1555bebe639808147d587bbe776566d390b9ff98773fJens Axboevoid fio_server_set_arg(const char *arg)
155687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
155787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_server_arg = strdup(arg);
155887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
1559