server.c revision f58bd2a4fc0ba558fd90878fe7db5f2d4809990b
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
398f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboestatic int fio_net_send_ack(int sk, struct fio_net_cmd *cmd, int error,
399f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe			    int signal)
400132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
40111e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	struct cmd_end_pdu epdu;
402f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	uint64_t tag = 0;
403122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
404f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	if (cmd)
405f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		tag = cmd->tag;
406122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
407122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	epdu.error = __cpu_to_le32(error);
408122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	epdu.signal = __cpu_to_le32(signal);
409f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	return fio_net_send_cmd(sk, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), tag);
410f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe}
411f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
412f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboeint fio_net_send_stop(int sk, int error, int signal)
413f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe{
414f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	dprint(FD_NET, "server: sending stop (%d, %d)\n", error, signal);
415f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	return fio_net_send_ack(sk, NULL, error, signal);
416122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
417122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
418122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_add_fork_item(pid_t pid, struct flist_head *list)
419122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
420122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct fio_fork_item *ffi;
421122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
422122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi = malloc(sizeof(*ffi));
423122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->exitval = 0;
424122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->signal = 0;
425122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->exited = 0;
426122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ffi->pid = pid;
427122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_add_tail(&ffi->list, list);
428122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
429122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
430122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_add_conn_pid(pid_t pid)
431122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
432122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	dprint(FD_NET, "server: forked off connection job (pid=%u)\n", pid);
433122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_server_add_fork_item(pid, &conn_list);
434122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
435122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
436122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_add_job_pid(pid_t pid)
437122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
438122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	dprint(FD_NET, "server: forked off job job (pid=%u)\n", pid);
439122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_server_add_fork_item(pid, &job_list);
440122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
441122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
442122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_check_fork_item(struct fio_fork_item *ffi)
443122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
444122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int ret, status;
445122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
446122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ret = waitpid(ffi->pid, &status, WNOHANG);
447122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	if (ret < 0) {
448122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (errno == ECHILD) {
449122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: connection pid %u disappeared\n", ffi->pid);
450122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
451122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		} else
452122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: waitpid: %s\n", strerror(errno));
453122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	} else if (ret == ffi->pid) {
454122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (WIFSIGNALED(status)) {
455122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->signal = WTERMSIG(status);
456122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
457122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
458122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (WIFEXITED(status)) {
459122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (WEXITSTATUS(status))
460122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				ffi->exitval = WEXITSTATUS(status);
461122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			ffi->exited = 1;
462122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
463122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
464122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
465122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
466122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_fork_item_done(struct fio_fork_item *ffi)
467122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
468122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	dprint(FD_NET, "pid %u exited, sig=%u, exitval=%d\n", ffi->pid, ffi->signal, ffi->exitval);
469122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
470122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	/*
471122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	 * Fold STOP and QUIT...
472122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	 */
473122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_stop(server_fd, ffi->exitval, ffi->signal);
474122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_quit(server_fd);
475122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_del(&ffi->list);
476122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	free(ffi);
477122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
478122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
479541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboestatic void fio_server_check_fork_items(struct flist_head *list)
480122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
481122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct flist_head *entry, *tmp;
482122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	struct fio_fork_item *ffi;
483122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
484122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	flist_for_each_safe(entry, tmp, list) {
485122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		ffi = flist_entry(entry, struct fio_fork_item, list);
486122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
487122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_check_fork_item(ffi);
488122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
489122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (ffi->exited)
490122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			fio_server_fork_item_done(ffi);
491122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
492122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
493122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
494122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_check_jobs(void)
495122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
496541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe	fio_server_check_fork_items(&job_list);
497122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
498122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
499122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic void fio_server_check_conns(void)
500122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
501541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe	fio_server_check_fork_items(&conn_list);
502122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
503122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
504122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic int handle_run_cmd(struct fio_net_cmd *cmd)
505122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
506122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid_t pid;
507a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret;
508132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
509122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	set_genesis_time();
51011e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
511122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	pid = fork();
512122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	if (pid) {
513122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_add_job_pid(pid);
514122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		return 0;
515122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
51611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
517122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	ret = fio_backend();
518122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	_exit(ret);
51981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
52081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
521b9d2f30a214ebd274340f888739be250838d63c2Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd)
522b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe{
52346bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	struct cmd_job_pdu *pdu = (struct cmd_job_pdu *) cmd->payload;
52446bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	void *buf = pdu->buf;
525b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct cmd_start_pdu spdu;
526b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
52746bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->buf_len = le32_to_cpu(pdu->buf_len);
52846bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	pdu->client_type = le32_to_cpu(pdu->client_type);
52946bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe
53046bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	if (parse_jobs_ini(buf, 1, 0, pdu->client_type)) {
531122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_net_send_quit(server_fd);
532b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		return -1;
533b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	}
534b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
535b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
536b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
537b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return 0;
538b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe}
539b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe
54081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd)
54181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
542fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	void *pdu = cmd->payload;
543fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_single_line_pdu *cslp;
544fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_line_pdu *clp;
545fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	unsigned long offset;
546b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	struct cmd_start_pdu spdu;
547fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	char **argv;
548b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	int i;
54981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
550fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp = pdu;
551fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp->lines = le16_to_cpu(clp->lines);
55246bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	clp->client_type = le16_to_cpu(clp->client_type);
553fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	argv = malloc(clp->lines * sizeof(char *));
554fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	offset = sizeof(*clp);
55581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
556fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	dprint(FD_NET, "server: %d command line args\n", clp->lines);
55739e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe
558fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	for (i = 0; i < clp->lines; i++) {
559fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp = pdu + offset;
560fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		argv[i] = (char *) cslp->text;
561fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
562fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		offset += sizeof(*cslp) + le16_to_cpu(cslp->len);
56339e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe		dprint(FD_NET, "server: %d: %s\n", i, argv[i]);
56439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	}
56581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
56646bcd498f7b3fb55f7f048bf299f36bd8c8f7db1Jens Axboe	if (parse_cmd_line(clp->lines, argv, clp->client_type)) {
567122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_net_send_quit(server_fd);
568fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		free(argv);
56981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
570e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
57181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
572fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	free(argv);
573fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
574b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
575b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
576b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	return 0;
577132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
578132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
579c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd)
580c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{
581c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	struct cmd_probe_pdu probe;
582c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
58389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: sending probe reply\n");
58489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
585c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	memset(&probe, 0, sizeof(probe));
586c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	gethostname((char *) probe.hostname, sizeof(probe.hostname));
5876eb2479194603184f393057ea10326643edc7169Jens Axboe#ifdef FIO_BIG_ENDIAN
5886eb2479194603184f393057ea10326643edc7169Jens Axboe	probe.bigendian = 1;
5896eb2479194603184f393057ea10326643edc7169Jens Axboe#endif
59081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_major = FIO_MAJOR;
59181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_minor = FIO_MINOR;
59281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_patch = FIO_PATCH;
593c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
594cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.os	= FIO_OS;
595cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.arch	= FIO_ARCH;
596cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe
59738fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe	probe.bpp	= sizeof(void *);
59838fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe
59989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), cmd->tag);
600af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe}
601af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
602af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic int handle_send_eta_cmd(struct fio_net_cmd *cmd)
603af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{
604af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct jobs_eta *je;
605af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	size_t size;
606af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	int i;
607af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
608b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	if (!thread_number)
609b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe		return 0;
610b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe
611b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	size = sizeof(*je) + thread_number * sizeof(char) + 1;
6127f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	je = malloc(size);
6137f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	memset(je, 0, size);
614af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
615af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	if (!calc_thread_status(je, 1)) {
616af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		free(je);
617af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return 0;
618af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
619af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
620af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "server sending status\n");
621af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
622af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_running		= cpu_to_le32(je->nr_running);
623af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_ramp		= cpu_to_le32(je->nr_ramp);
624af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_pending		= cpu_to_le32(je->nr_pending);
625af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->files_open		= cpu_to_le32(je->files_open);
626af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
627af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	for (i = 0; i < 2; i++) {
6283e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->m_rate[i]	= cpu_to_le32(je->m_rate[i]);
6293e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->t_rate[i]	= cpu_to_le32(je->t_rate[i]);
6303e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->m_iops[i]	= cpu_to_le32(je->m_iops[i]);
6313e47bd250cac5fb81a5c0ad578dfbe90c6ddf6deJens Axboe		je->t_iops[i]	= cpu_to_le32(je->t_iops[i]);
632af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->rate[i]	= cpu_to_le32(je->rate[i]);
633af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->iops[i]	= cpu_to_le32(je->iops[i]);
634af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
635af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
636c1970b907ff0cb819de5607bc120d8acb527eb98Jens Axboe	je->elapsed_sec		= cpu_to_le64(je->elapsed_sec);
637af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->eta_sec		= cpu_to_le64(je->eta_sec);
6388c621fb2aa4b99c8a8b6b62435d713ab39b52c62Jens Axboe	je->nr_threads		= cpu_to_le32(je->nr_threads);
639af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
6407f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, cmd->tag);
641af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	free(je);
642af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	return 0;
643c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe}
644c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
645f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboestatic int handle_update_job_cmd(struct fio_net_cmd *cmd)
646f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe{
647f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	struct cmd_add_job_pdu *pdu = (struct cmd_add_job_pdu *) cmd->payload;
648f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	struct thread_data *td;
649f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	uint32_t tnumber;
650f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
651f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	tnumber = le32_to_cpu(pdu->thread_number);
652f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
653f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	dprint(FD_NET, "server: updating options for job %u\n", tnumber);
654f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
655f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	if (tnumber >= thread_number) {
656f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		fio_net_send_ack(server_fd, cmd, ENODEV, 0);
657f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		return 0;
658f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	}
659f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
660f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	td = &threads[tnumber];
661f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	convert_thread_options_to_cpu(&td->o, &pdu->top);
662f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	fio_net_send_ack(server_fd, cmd, 0, 0);
663f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	return 0;
664f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe}
665f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe
666132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd)
667132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
668132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret;
669132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
67089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%lx\n",
67189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			fio_server_op(cmd->opcode), cmd->pdu_len, cmd->tag);
67246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
673132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->opcode) {
674132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_QUIT:
675cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe		fio_terminate_threads(TERMINATE_ALL);
676c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
677d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe	case FIO_NET_CMD_EXIT:
678132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		exit_backend = 1;
679c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
680132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_JOB:
6810b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		ret = handle_job_cmd(cmd);
682132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
68381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	case FIO_NET_CMD_JOBLINE:
68481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		ret = handle_jobline_cmd(cmd);
68581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		break;
686c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	case FIO_NET_CMD_PROBE:
687c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		ret = handle_probe_cmd(cmd);
688c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		break;
689af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	case FIO_NET_CMD_SEND_ETA:
690af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		ret = handle_send_eta_cmd(cmd);
691af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		break;
692b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe	case FIO_NET_CMD_RUN:
693b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		ret = handle_run_cmd(cmd);
694b9d2f30a214ebd274340f888739be250838d63c2Jens Axboe		break;
695f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe	case FIO_NET_CMD_UPDATE_JOB:
696f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		ret = handle_update_job_cmd(cmd);
697f58bd2a4fc0ba558fd90878fe7db5f2d4809990bJens Axboe		break;
698132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
6993c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe		log_err("fio: unknown opcode: %s\n", fio_server_op(cmd->opcode));
700132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = 1;
701132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
702132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
703132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
704132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
705132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
706122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboestatic int handle_connection(int sk)
707132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
708132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd *cmd = NULL;
709132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
710132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
711122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	reset_fio_state();
712122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	INIT_FLIST_HEAD(&job_list);
713122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	server_fd = sk;
714122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
715132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* read forever */
716132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	while (!exit_backend) {
717e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		struct pollfd pfd = {
718e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.fd	= sk,
719e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.events	= POLLIN,
720e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		};
721e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
722e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		ret = 0;
723e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		do {
724541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			int timeout = 1000;
725541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
726541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			if (!flist_empty(&job_list))
727541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe				timeout = 100;
7283c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe
729541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			ret = poll(&pfd, 1, timeout);
730e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (ret < 0) {
731e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				if (errno == EINTR)
732e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe					break;
733e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
734e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
73519c65179fad3e0a32a450401ba7d312169627fddJens Axboe			} else if (!ret) {
736122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				fio_server_check_jobs();
737e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				continue;
73819c65179fad3e0a32a450401ba7d312169627fddJens Axboe			}
739e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
740e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & POLLIN)
741e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
742e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & (POLLERR|POLLHUP)) {
743e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				ret = 1;
744e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
745e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			}
74619c65179fad3e0a32a450401ba7d312169627fddJens Axboe		} while (!exit_backend);
747e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
748122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_check_jobs();
749122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
750e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		if (ret < 0)
751e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			break;
752e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
753e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		cmd = fio_net_recv_cmd(sk);
754132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (!cmd) {
755c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe			ret = -1;
756132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
757132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		}
758132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
759132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = handle_command(cmd);
760132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
761132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
762132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
763132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
764c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe		cmd = NULL;
765132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
766132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
767132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd)
768132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
769132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
770122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	close(sk);
771122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	_exit(ret);
772cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
773cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
77450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
77550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
776bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	struct sockaddr_in addr;
7775ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe	fio_socklen_t len = sizeof(addr);
778009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
779122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	int ret = 0, sk, flags, exitval = 0;
78050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
78160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server enter accept loop\n");
78260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
783009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags = fcntl(listen_sk, F_GETFL);
784009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags |= O_NONBLOCK;
785009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	fcntl(listen_sk, F_SETFL, flags);
786009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
787122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	while (!exit_backend) {
788122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pid_t pid;
789009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
790122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pfd.fd = listen_sk;
791122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pfd.events = POLLIN;
792122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		do {
793541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			int timeout = 1000;
794541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
795541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			if (!flist_empty(&conn_list))
796541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe				timeout = 100;
797541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe
798541632558a949e80f678d0d45bdeab5f9d3d4335Jens Axboe			ret = poll(&pfd, 1, timeout);
799122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (ret < 0) {
800122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				if (errno == EINTR)
801122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe					break;
802122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
803122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				break;
804122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			} else if (!ret) {
805122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				fio_server_check_conns();
806122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				continue;
807122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			}
808009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
809122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			if (pfd.revents & POLLIN)
810122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe				break;
811122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		} while (!exit_backend);
81250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
813122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		fio_server_check_conns();
81446c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
815122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (exit_backend || ret < 0)
816122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			break;
817122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
818122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		sk = accept(listen_sk, (struct sockaddr *) &addr, &len);
819122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (sk < 0) {
820122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			log_err("fio: accept: %s\n", strerror(errno));
821122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			return -1;
822122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
82337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
824122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr));
82550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
826122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		pid = fork();
827122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		if (pid) {
828122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			close(sk);
829122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			fio_server_add_conn_pid(pid);
830122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe			continue;
831122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		}
8325c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
833122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		/* exits */
834122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe		handle_connection(sk);
835122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	}
8365c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
837132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return exitval;
83850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
83950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
840084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboeint fio_server_text_output(int level, const char *buf, size_t len)
84137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
842084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	struct cmd_text_pdu *pdu;
843084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	unsigned int tlen;
844084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	struct timeval tv;
845084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
846084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	if (server_fd == -1)
847084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe		return log_local_buf(buf, len);
848084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
849084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	tlen = sizeof(*pdu) + len;
850084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu = malloc(tlen);
851084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
852084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->level	= __cpu_to_le32(level);
853084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->buf_len	= __cpu_to_le32(len);
854084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
855084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	gettimeofday(&tv, NULL);
856084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_sec	= __cpu_to_le64(tv.tv_sec);
857084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	pdu->log_usec	= __cpu_to_le64(tv.tv_usec);
858337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe
859084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	memcpy(pdu->buf, buf, len);
860084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe
861084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, pdu, tlen, 0);
862084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	free(pdu);
863084d1c6f817eacaaefa1de4f0637ef6c1405d74bJens Axboe	return len;
864142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe}
865142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
866a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src)
867a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
868a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->max_val	= cpu_to_le64(src->max_val);
869a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->min_val	= cpu_to_le64(src->min_val);
870a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->samples	= cpu_to_le64(src->samples);
871802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
872802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	/*
873802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 * Encode to IEEE 754 for network transfer
874802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 */
875802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->mean.u.i	= __cpu_to_le64(fio_double_to_uint64(src->mean.u.f));
876802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->S.u.i	= __cpu_to_le64(fio_double_to_uint64(src->S.u.f));
877a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
878a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
879a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
880a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
881a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i;
882a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
883a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
884a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_run[i]		= cpu_to_le64(src->max_run[i]);
885a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_run[i]		= cpu_to_le64(src->min_run[i]);
886a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_bw[i]		= cpu_to_le64(src->max_bw[i]);
887a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_bw[i]		= cpu_to_le64(src->min_bw[i]);
888a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_kb[i]		= cpu_to_le64(src->io_kb[i]);
889a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->agg[i]		= cpu_to_le64(src->agg[i]);
890a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
891a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
892a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->kb_base	= cpu_to_le32(src->kb_base);
893a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= cpu_to_le32(src->groupid);
894a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
895a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
896a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
897a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats
898a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload.
899a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
900a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
901a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
902a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct cmd_ts_pdu p;
903a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i, j;
904a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
90560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending end stats\n");
90660efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
907317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe	memset(&p, 0, sizeof(p));
908317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe
909a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.name, ts->name);
910a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.verror, ts->verror);
911a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.description, ts->description);
912a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
9132f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.error		= cpu_to_le32(ts->error);
9142f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.thread_number	= cpu_to_le32(ts->thread_number);
9152f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.groupid		= cpu_to_le32(ts->groupid);
9162f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.pid		= cpu_to_le32(ts->pid);
9172f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	p.ts.members		= cpu_to_le32(ts->members);
918a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
919a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
920a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]);
921a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]);
922a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]);
923a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]);
924a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
925a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
926a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.usr_time		= cpu_to_le64(ts->usr_time);
927a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.sys_time		= cpu_to_le64(ts->sys_time);
928a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.ctx		= cpu_to_le64(ts->ctx);
929a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.minf		= cpu_to_le64(ts->minf);
930a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.majf		= cpu_to_le64(ts->majf);
931a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.clat_percentiles	= cpu_to_le64(ts->clat_percentiles);
932802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
933802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
934cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *src = &ts->percentile_list[i];
935cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *dst = &p.ts.percentile_list[i];
936802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
937cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		dst->u.i = __cpu_to_le64(fio_double_to_uint64(src->u.f));
938802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	}
939a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
940a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
941a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_map[i]	= cpu_to_le32(ts->io_u_map[i]);
942a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_submit[i]	= cpu_to_le32(ts->io_u_submit[i]);
943a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_complete[i]	= cpu_to_le32(ts->io_u_complete[i]);
944a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
945a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
946a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
947a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_u[i]	= cpu_to_le32(ts->io_u_lat_u[i]);
948a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_m[i]	= cpu_to_le32(ts->io_u_lat_m[i]);
949a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
950a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
951a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++)
952a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
953a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]);
954a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
955a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 3; i++) {
956a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.total_io_u[i]	= cpu_to_le64(ts->total_io_u[i]);
95793eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe		p.ts.short_io_u[i]	= cpu_to_le64(ts->short_io_u[i]);
958a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
959a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
96093eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe	p.ts.total_submit	= cpu_to_le64(ts->total_submit);
961a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_complete	= cpu_to_le64(ts->total_complete);
962a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
963a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
964a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_bytes[i]	= cpu_to_le64(ts->io_bytes[i]);
965a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.runtime[i]		= cpu_to_le64(ts->runtime[i]);
966a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
967a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
968a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_run_time	= cpu_to_le64(ts->total_run_time);
969a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.continue_on_error	= cpu_to_le16(ts->continue_on_error);
970a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_err_count	= cpu_to_le64(ts->total_err_count);
971ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.first_error	= cpu_to_le32(ts->first_error);
972ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.kb_base		= cpu_to_le32(ts->kb_base);
973a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
974a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&p.rs, rs);
975a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
976af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0);
977a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
978a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
979a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs)
980a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
981a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct group_run_stats gs;
982a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
98360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending group run stats\n");
98460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
985a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&gs, rs);
986af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0);
987cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe}
988cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
989d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src)
990d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
991d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
992d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
993d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
994d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ios[i]	= cpu_to_le32(src->ios[i]);
995d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->merges[i]	= cpu_to_le32(src->merges[i]);
996d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
997d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
998d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
999d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1000d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->io_ticks		= cpu_to_le32(src->io_ticks);
1001d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
1002d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->slavecount		= cpu_to_le32(src->slavecount);
1003d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->max_util.u.i	= __cpu_to_le64(fio_double_to_uint64(src->max_util.u.f));
1004d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1005d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1006d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src)
1007d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
1008d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
1009d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1010d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	strcpy((char *) dst->name, (char *) src->name);
1011d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1012d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
1013d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ios[i]	= cpu_to_le32(src->ios[i]);
1014d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->merges[i]	= cpu_to_le32(src->merges[i]);
1015d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
1016d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
1017d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
1018d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1019d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->io_ticks		= cpu_to_le32(src->io_ticks);
1020d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
1021d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->msec		= cpu_to_le64(src->msec);
1022d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1023d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1024d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboevoid fio_server_send_du(void)
1025d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
1026d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct disk_util *du;
1027d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct flist_head *entry;
1028d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct cmd_du_pdu pdu;
1029d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1030d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dprint(FD_NET, "server: sending disk_util %d\n", !flist_empty(&disk_list));
1031d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
10320766d92e06a119eea489e74d80d5840813559752Jens Axboe	memset(&pdu, 0, sizeof(pdu));
10330766d92e06a119eea489e74d80d5840813559752Jens Axboe
1034d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	flist_for_each(entry, &disk_list) {
1035d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		du = flist_entry(entry, struct disk_util, list);
1036d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1037d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_dus(&pdu.dus, &du->dus);
1038d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_agg(&pdu.agg, &du->agg);
1039d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
1040d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), 0);
1041d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
1042d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
1043d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
104453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe/*
104553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe * Send a command with a separate PDU, not inlined in the command
104653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe */
104753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboestatic int fio_send_cmd_ext_pdu(int sk, uint16_t opcode, const void *buf,
104853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe				off_t size, uint64_t tag, uint32_t flags)
104953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe{
105053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	struct fio_net_cmd cmd;
105153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	struct iovec iov[2];
105253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
105353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[0].iov_base = &cmd;
105453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[0].iov_len = sizeof(cmd);
105553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[1].iov_base = (void *) buf;
105653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	iov[1].iov_len = size;
105753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
105853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	__fio_init_net_cmd(&cmd, opcode, size, tag);
105953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	cmd.flags = __cpu_to_le32(flags);
106053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	fio_net_cmd_crc_pdu(&cmd, buf);
106153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
10628c95307bd5f72720460ee4a46519b9a1b474e7cdJens Axboe	return fio_sendv_data(sk, iov, 2);
106353bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe}
106453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe
10651b42725f06f8906b9b99381da3490484f59df28aJens Axboeint fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
10661b42725f06f8906b9b99381da3490484f59df28aJens Axboe{
1067f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	struct cmd_iolog_pdu pdu;
10681b42725f06f8906b9b99381da3490484f59df28aJens Axboe	z_stream stream;
10691b42725f06f8906b9b99381da3490484f59df28aJens Axboe	void *out_pdu;
107053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	int i, ret = 0;
10711b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10722f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.thread_number = cpu_to_le32(td->thread_number);
1073f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	pdu.nr_samples = __cpu_to_le32(log->nr_samples);
1074f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	pdu.log_type = cpu_to_le32(log->log_type);
1075f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	strcpy((char *) pdu.name, name);
10761b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10771b42725f06f8906b9b99381da3490484f59df28aJens Axboe	for (i = 0; i < log->nr_samples; i++) {
1078f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		struct io_sample *s = &log->log[i];
10791b42725f06f8906b9b99381da3490484f59df28aJens Axboe
1080f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->time	= cpu_to_le64(s->time);
1081f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->val	= cpu_to_le64(s->val);
1082f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->ddir	= cpu_to_le32(s->ddir);
1083f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe		s->bs	= cpu_to_le32(s->bs);
10841b42725f06f8906b9b99381da3490484f59df28aJens Axboe	}
10851b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10861b42725f06f8906b9b99381da3490484f59df28aJens Axboe	/*
10871b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * Dirty - since the log is potentially huge, compress it into
10881b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * FIO_SERVER_MAX_FRAGMENT_PDU chunks and let the receiving
10891b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 * side defragment it.
10901b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 */
10911b42725f06f8906b9b99381da3490484f59df28aJens Axboe	out_pdu = malloc(FIO_SERVER_MAX_FRAGMENT_PDU);
10921b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10931b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zalloc = Z_NULL;
10941b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.zfree = Z_NULL;
10951b42725f06f8906b9b99381da3490484f59df28aJens Axboe	stream.opaque = Z_NULL;
10961b42725f06f8906b9b99381da3490484f59df28aJens Axboe
10971b42725f06f8906b9b99381da3490484f59df28aJens Axboe	if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
109853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		ret = 1;
109953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		goto err;
11001b42725f06f8906b9b99381da3490484f59df28aJens Axboe	}
11011b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11021b42725f06f8906b9b99381da3490484f59df28aJens Axboe	/*
1103f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	 * Send header first, it's not compressed.
11041b42725f06f8906b9b99381da3490484f59df28aJens Axboe	 */
110553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, &pdu,
110653bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe					sizeof(pdu), 0, FIO_NET_CMD_F_MORE);
110753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	if (ret)
110853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		goto err_zlib;
11091b42725f06f8906b9b99381da3490484f59df28aJens Axboe
1110f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	stream.next_in = (void *) log->log;
1111f5ed765adadc5dca61efb5fc103fa5cd0310bcecJens Axboe	stream.avail_in = log->nr_samples * sizeof(struct io_sample);
11121b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11131b42725f06f8906b9b99381da3490484f59df28aJens Axboe	do {
111453bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		unsigned int this_len, flags = 0;
111553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		int ret;
11161b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11171b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.avail_out = FIO_SERVER_MAX_FRAGMENT_PDU;
11181b42725f06f8906b9b99381da3490484f59df28aJens Axboe		stream.next_out = out_pdu;
11193c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		ret = deflate(&stream, Z_FINISH);
11203c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		/* may be Z_OK, or Z_STREAM_END */
11213c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe		if (ret < 0)
11223c547fe0547c924ca5174d9aa36720ddb441480aJens Axboe			goto err_zlib;
11231b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11241b42725f06f8906b9b99381da3490484f59df28aJens Axboe		this_len = FIO_SERVER_MAX_FRAGMENT_PDU - stream.avail_out;
11251b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11261b42725f06f8906b9b99381da3490484f59df28aJens Axboe		if (stream.avail_in)
112753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe			flags = FIO_NET_CMD_F_MORE;
11281b42725f06f8906b9b99381da3490484f59df28aJens Axboe
112953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG,
113053bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe					   out_pdu, this_len, 0, flags);
113153bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe		if (ret)
113253bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe			goto err_zlib;
11331b42725f06f8906b9b99381da3490484f59df28aJens Axboe	} while (stream.avail_in);
11341b42725f06f8906b9b99381da3490484f59df28aJens Axboe
113553bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboeerr_zlib:
11361b42725f06f8906b9b99381da3490484f59df28aJens Axboe	deflateEnd(&stream);
113753bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboeerr:
113853bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	free(out_pdu);
113953bd8dbcbf692d1f622d6c9e62284121e710fdc3Jens Axboe	return ret;
11401b42725f06f8906b9b99381da3490484f59df28aJens Axboe}
11411b42725f06f8906b9b99381da3490484f59df28aJens Axboe
11422f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboevoid fio_server_send_add_job(struct thread_data *td)
1143807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe{
1144807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe	struct cmd_add_job_pdu pdu;
1145807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1146731e30a2551315c609c23ac107377b63c02d51faJens Axboe	memset(&pdu, 0, sizeof(pdu));
11472f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.thread_number = cpu_to_le32(td->thread_number);
11482f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	pdu.groupid = cpu_to_le32(td->groupid);
11492f122b135b7319ff8dd04dadf31ff28b301051a3Jens Axboe	convert_thread_options_to_net(&pdu.top, &td->o);
1150807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1151807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ADD_JOB, &pdu, sizeof(pdu), 0);
1152807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe}
1153807f9971e7bfedfc905d2cb2c38a6e558db2f343Jens Axboe
1154122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboevoid fio_server_send_start(struct thread_data *td)
1155122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe{
1156122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	assert(server_fd != -1);
1157122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
1158122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_SERVER_START, 0, NULL);
1159122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe}
1160122c772599f1b0a3148a5790775698d3fa92cc10Jens Axboe
116187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_ip(void)
116281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
1163811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	struct sockaddr *addr;
1164811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	fio_socklen_t socklen;
116587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, opt;
116681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1167811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6)
1168811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET6, SOCK_STREAM, 0);
1169811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	else
1170811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET, SOCK_STREAM, 0);
1171811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
117281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (sk < 0) {
117381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
117481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
117581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
117681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
117781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	opt = 1;
117881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
117981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
1180b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
118181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
118281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
118381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT
11846eb2479194603184f393057ea10326643edc7169Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
118581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
1186b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
118781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
118881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
118981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif
119081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1191811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6) {
1192811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in6;
1193811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in6);
1194811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in6.sin6_family = AF_INET6;
1195811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else {
1196811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in;
1197811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in);
1198811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in.sin_family = AF_INET;
1199811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	}
120081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
1201811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (bind(sk, addr, socklen) < 0) {
120281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
1203b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
120481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
120581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
120681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
120787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
120887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
120987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
121087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_sock(void)
121187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
121287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un addr;
121387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_socklen_t len;
121487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode_t mode;
121587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
121687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
121787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = socket(AF_UNIX, SOCK_STREAM, 0);
121887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0) {
121987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: socket: %s\n", strerror(errno));
122087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
122187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
122287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
122387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode = umask(000);
122487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
122587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	memset(&addr, 0, sizeof(addr));
122687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	addr.sun_family = AF_UNIX;
122787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	strcpy(addr.sun_path, bind_sock);
122887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	unlink(bind_sock);
122987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
123087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	len = sizeof(addr.sun_family) + strlen(bind_sock) + 1;
123187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
123287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (bind(sk, (struct sockaddr *) &addr, len) < 0) {
123387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: bind: %s\n", strerror(errno));
1234b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
123587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
123687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
123787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
123887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	umask(mode);
123987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
124087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
124187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
124287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_connection(void)
124387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
1244bebe639808147d587bbe776566d390b9ff98773fJens Axboe	char bind_str[128];
124587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
124687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
124787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
124887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
124987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!bind_sock)
125087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_ip();
125187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	else
125287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_sock();
125387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
125487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
125587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return sk;
125687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1257811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (!bind_sock) {
1258811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		char *p, port[16];
1259811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		const void *src;
1260811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		int af;
1261811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1262811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (use_ipv6) {
1263811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET6;
1264811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in6.sin6_addr;
1265811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		} else {
1266811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET;
1267811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in.sin_addr;
1268811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		}
1269811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1270811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		p = (char *) inet_ntop(af, src, bind_str, sizeof(bind_str));
1271811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
1272811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sprintf(port, ",%u", fio_net_port);
1273811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (p)
1274811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcat(p, port);
1275811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		else
1276811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcpy(bind_str, port);
1277811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else
1278bebe639808147d587bbe776566d390b9ff98773fJens Axboe		strcpy(bind_str, bind_sock);
1279bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1280bebe639808147d587bbe776566d390b9ff98773fJens Axboe	log_info("fio: server listening on %s\n", bind_str);
1281bebe639808147d587bbe776566d390b9ff98773fJens Axboe
128289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (listen(sk, 0) < 0) {
128381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
128481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
128581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
128681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
128787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
128887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
128987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
12903ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboeint fio_server_parse_host(const char *host, int *ipv6, struct in_addr *inp,
12913ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			  struct in6_addr *inp6)
12923ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
12933ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe{
12943ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	int ret = 0;
12953ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
12963ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	if (*ipv6)
12973ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = inet_pton(AF_INET6, host, inp6);
12983ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	else
12993ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = inet_pton(AF_INET, host, inp);
13003ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
13013ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	if (ret != 1) {
13023ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		struct hostent *hent;
13033ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
13043ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		hent = gethostbyname(host);
13053ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		if (!hent) {
13063ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			log_err("fio: failed to resolve <%s>\n", host);
13073ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			return 0;
13083ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		}
13093ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
13103ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		if (*ipv6) {
13113ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			if (hent->h_addrtype != AF_INET6) {
13123ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				log_info("fio: falling back to IPv4\n");
13133ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				*ipv6 = 0;
13143ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			} else
13153ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				memcpy(inp6, hent->h_addr_list[0], 16);
13163ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		}
13173ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		if (!*ipv6) {
13183ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			if (hent->h_addrtype != AF_INET) {
13193ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				log_err("fio: lookup type mismatch\n");
13203ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe				return 0;
13213ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			}
13223ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe			memcpy(inp, hent->h_addr_list[0], 4);
13233ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		}
13243ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		ret = 1;
13253ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	}
13263ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
13273ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	return !(ret == 1);
13283ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe}
13293ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe
1330660a2bfb0858f94633f9e567b81968981541f079Jens Axboe/*
1331660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Parse a host/ip/port string. Reads from 'str'.
1332660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
1333660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Outputs:
1334660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
1335660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv4:
1336660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp is the destination.
1337660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv6:
1338660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp6 is the dest, and *ipv6 is 1.
1339660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For local domain sockets:
1340660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the filename, *is_sock is 1.
1341660a2bfb0858f94633f9e567b81968981541f079Jens Axboe */
1342bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_server_parse_string(const char *str, char **ptr, int *is_sock,
1343811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    int *port, struct in_addr *inp,
1344811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    struct in6_addr *inp6, int *ipv6)
1345bebe639808147d587bbe776566d390b9ff98773fJens Axboe{
134676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	const char *host = str;
134776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	char *portp;
13483ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	int lport = 0;
134976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
1350bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*ptr = NULL;
1351bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*is_sock = 0;
13526d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	*port = fio_net_port;
1353811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	*ipv6 = 0;
1354bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1355bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!strncmp(str, "sock:", 5)) {
1356bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*ptr = strdup(str + 5);
1357bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*is_sock = 1;
135876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
135976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
136076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
136176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
136276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
136376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * Is it ip:<ip or host>:port
136476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
136576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strncmp(host, "ip:", 3))
136676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 3;
136776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip4:", 4))
136876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
136976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip6:", 4)) {
137076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
137176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*ipv6 = 1;
137276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	} else if (host[0] == ':') {
137376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* String is :port */
137476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host++;
137576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		lport = atoi(host);
137676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!lport || lport > 65535) {
137776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			log_err("fio: bad server port %u\n", port);
137876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			return 1;
137976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
138076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* no hostname given, we are done */
138176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
138276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
138376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
138476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
138576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
138676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * If no port seen yet, check if there's a last ':' at the end
138776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
138876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!lport) {
138976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		portp = strchr(host, ',');
139076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (portp) {
139176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			*portp = '\0';
139276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			portp++;
139376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			lport = atoi(portp);
1394bebe639808147d587bbe776566d390b9ff98773fJens Axboe			if (!lport || lport > 65535) {
1395bebe639808147d587bbe776566d390b9ff98773fJens Axboe				log_err("fio: bad server port %u\n", port);
1396bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
1397bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
1398bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
139976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
1400bebe639808147d587bbe776566d390b9ff98773fJens Axboe
140176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (lport)
140276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
1403bebe639808147d587bbe776566d390b9ff98773fJens Axboe
140476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strlen(host))
140576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
1406bebe639808147d587bbe776566d390b9ff98773fJens Axboe
140776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	*ptr = strdup(host);
1408811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
14093ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe	if (fio_server_parse_host(*ptr, ipv6, inp, inp6)) {
14103ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		free(*ptr);
14113ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		*ptr = NULL;
14123ec62ec45ce971b76dd3029412dfd3d0c6221384Jens Axboe		return 1;
1413bebe639808147d587bbe776566d390b9ff98773fJens Axboe	}
1414bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1415bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (*port == 0)
1416bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*port = fio_net_port;
1417bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1418bebe639808147d587bbe776566d390b9ff98773fJens Axboe	return 0;
1419bebe639808147d587bbe776566d390b9ff98773fJens Axboe}
1420bebe639808147d587bbe776566d390b9ff98773fJens Axboe
142187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe/*
142287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Server arg should be one of:
142387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
142487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * sock:/path/to/socket
142587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *   ip:1.2.3.4
142687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *      1.2.3.4
142787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
142887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Where sock uses unix domain sockets, and ip binds the server to
142987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * a specific interface. If no arguments are given to the server, it
143087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * uses IP and binds to 0.0.0.0.
143187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
143287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe */
143387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_handle_server_arg(void)
143487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
14356d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	int port = fio_net_port;
1436a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe	int is_sock, ret = 0;
1437bebe639808147d587bbe776566d390b9ff98773fJens Axboe
143887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
143987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
144087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!fio_server_arg)
1441a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe		goto out;
144287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
14434e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock,
1444811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&port, &saddr_in.sin_addr,
1445811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&saddr_in6.sin6_addr, &use_ipv6);
14464e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
14474e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	if (!is_sock && bind_sock) {
14484e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		free(bind_sock);
14494e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		bind_sock = NULL;
14504e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	}
14514e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
1452a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboeout:
14536d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	fio_net_port = port;
14546d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	saddr_in.sin_port = htons(port);
1455811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	saddr_in6.sin6_port = htons(port);
14564e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	return ret;
145787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
145887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
145987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_server(void)
146087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
146187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, ret;
146287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
146387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
146487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
146587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_handle_server_arg())
146687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
146787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
146887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = fio_init_server_connection();
146987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
147087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
147181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
147281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	ret = accept_loop(sk);
147387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
147481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	close(sk);
147587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
147687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_server_arg) {
147787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		free(fio_server_arg);
147887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fio_server_arg = NULL;
147987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
1480bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (bind_sock)
1481bebe639808147d587bbe776566d390b9ff98773fJens Axboe		free(bind_sock);
148287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
148381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
148481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
148581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
14867b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboevoid fio_server_got_signal(int signal)
14879abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{
14887b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	if (signal == SIGPIPE)
14897b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		server_fd = -1;
14907b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	else {
14917b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		log_info("\nfio: terminating on signal %d\n", signal);
14927b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		exit_backend = 1;
14937b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	}
14949abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe}
14959abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe
149613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int check_existing_pidfile(const char *pidfile)
149713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe{
149813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	struct stat sb;
149913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	char buf[16];
150013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid_t pid;
150113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	FILE *f;
150213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
150313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (stat(pidfile, &sb))
150413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
150513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
150613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	f = fopen(pidfile, "r");
150713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (!f)
150813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
150913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1510bfc3b17986fb80aeb5a6ea962bb38fc1509d60a8Jens Axboe	if (fread(buf, sb.st_size, 1, f) <= 0) {
151113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		fclose(f);
151213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
151313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
151413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(f);
151513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
151613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid = atoi(buf);
151713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (kill(pid, SIGCONT) < 0)
1518ea5aa1be68de71f9f02eb3d6f4db726adcafb40aJens Axboe		return errno != ESRCH;
151913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
152013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 1;
152113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe}
152213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
152313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int write_pid(pid_t pid, const char *pidfile)
1524402668f3e05259bfc135fc097136428feda01006Jens Axboe{
1525402668f3e05259bfc135fc097136428feda01006Jens Axboe	FILE *fpid;
1526402668f3e05259bfc135fc097136428feda01006Jens Axboe
1527402668f3e05259bfc135fc097136428feda01006Jens Axboe	fpid = fopen(pidfile, "w");
1528402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!fpid) {
1529402668f3e05259bfc135fc097136428feda01006Jens Axboe		log_err("fio: failed opening pid file %s\n", pidfile);
153013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
1531402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1532402668f3e05259bfc135fc097136428feda01006Jens Axboe
1533402668f3e05259bfc135fc097136428feda01006Jens Axboe	fprintf(fpid, "%u\n", (unsigned int) pid);
153413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(fpid);
153513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 0;
1536402668f3e05259bfc135fc097136428feda01006Jens Axboe}
1537402668f3e05259bfc135fc097136428feda01006Jens Axboe
1538402668f3e05259bfc135fc097136428feda01006Jens Axboe/*
1539402668f3e05259bfc135fc097136428feda01006Jens Axboe * If pidfile is specified, background us.
1540402668f3e05259bfc135fc097136428feda01006Jens Axboe */
1541402668f3e05259bfc135fc097136428feda01006Jens Axboeint fio_start_server(char *pidfile)
1542e46d809110bd4ad2980ca64931b683673444454bJens Axboe{
1543e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid_t pid;
1544402668f3e05259bfc135fc097136428feda01006Jens Axboe	int ret;
1545e46d809110bd4ad2980ca64931b683673444454bJens Axboe
154693bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#if defined(WIN32)
1547905c78b90f92bab91555313f7b4bd83d18246139Jens Axboe	WSADATA wsd;
15483c3ed070502bbfec387ded2c43d5e4559ca24a63Jens Axboe	WSAStartup(MAKEWORD(2, 2), &wsd);
154993bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#endif
155093bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran
1551402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!pidfile)
1552e46d809110bd4ad2980ca64931b683673444454bJens Axboe		return fio_server();
1553e46d809110bd4ad2980ca64931b683673444454bJens Axboe
155413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (check_existing_pidfile(pidfile)) {
155513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: pidfile %s exists and server appears alive\n",
155613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe								pidfile);
155713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return -1;
155813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
155913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1560e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid = fork();
1561e46d809110bd4ad2980ca64931b683673444454bJens Axboe	if (pid < 0) {
156213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: failed server fork: %s", strerror(errno));
1563402668f3e05259bfc135fc097136428feda01006Jens Axboe		free(pidfile);
1564c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
1565402668f3e05259bfc135fc097136428feda01006Jens Axboe	} else if (pid) {
156613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		int ret = write_pid(pid, pidfile);
156713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
156813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		exit(ret);
1569402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1570e46d809110bd4ad2980ca64931b683673444454bJens Axboe
1571e46d809110bd4ad2980ca64931b683673444454bJens Axboe	setsid();
157213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
157313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	log_syslog = 1;
1574e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDIN_FILENO);
1575e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDOUT_FILENO);
1576e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDERR_FILENO);
1577e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_out = NULL;
1578e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_err = NULL;
1579402668f3e05259bfc135fc097136428feda01006Jens Axboe
1580402668f3e05259bfc135fc097136428feda01006Jens Axboe	ret = fio_server();
1581402668f3e05259bfc135fc097136428feda01006Jens Axboe
1582402668f3e05259bfc135fc097136428feda01006Jens Axboe	closelog();
1583402668f3e05259bfc135fc097136428feda01006Jens Axboe	unlink(pidfile);
1584402668f3e05259bfc135fc097136428feda01006Jens Axboe	free(pidfile);
1585402668f3e05259bfc135fc097136428feda01006Jens Axboe	return ret;
1586e46d809110bd4ad2980ca64931b683673444454bJens Axboe}
158787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1588bebe639808147d587bbe776566d390b9ff98773fJens Axboevoid fio_server_set_arg(const char *arg)
158987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
159087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_server_arg = strdup(arg);
159187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
1592