server.c revision 25dfa848abbb6c35b4d45fabd5a8e82cb77fb285
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>
1950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
2050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h"
21132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h"
22fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h"
23c7c6cb4cb3114ec4ce3107e15c184e161b50122eJens Axboe#include "lib/ieee754.h"
2489cf1480594858ad4e02499834c04fe48ff0a89dJens Axboe
2589cf1480594858ad4e02499834c04fe48ff0a89dJens Axboe#include "fio_version.h"
2650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
27132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765;
2850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
29009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0;
30009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
3146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1;
3287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *fio_server_arg;
3387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *bind_sock;
3487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic struct sockaddr_in saddr_in;
35811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic struct sockaddr_in6 saddr_in6;
3601be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboestatic int first_cmd_check;
37811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic int use_ipv6;
3837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
3989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic const char *fio_server_ops[FIO_NET_CMD_NR] = {
4089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"",
4189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"QUIT",
4289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"EXIT",
4389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOB",
4489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOBLINE",
4589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TEXT",
4689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TS",
4789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"GS",
4889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"SEND_ETA",
4989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"ETA",
5089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"PROBE",
5189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"START",
52d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"STOP",
53d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"DISK_UTIL",
5401be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe	"RUN",
5589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe};
5689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
5789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeconst char *fio_server_op(unsigned int op)
5889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
5989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	static char buf[32];
6089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
6189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (op < FIO_NET_CMD_NR)
6289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_server_ops[op];
6389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
6489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	sprintf(buf, "UNKNOWN/%d", op);
6589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return buf;
6689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
6789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len)
69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
70794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU);
71794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = send(sk, p, len, 0);
74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
80132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
81132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
82132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
83132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
84132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
857b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
867b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
87132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 1;
93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len)
96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = recv(sk, p, len, MSG_WAITALL);
99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
1107b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
1117b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
113132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
114132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
115132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
117132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return -1;
118132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
120132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd)
121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
122fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
123132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
124fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16);
125fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16);
126132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
12725dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	crc = fio_crc16(cmd, FIO_NET_CMD_CRC_SZ);
128fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != cmd->cmd_crc16) {
129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on command (got %x, wanted %x)\n",
130fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				cmd->cmd_crc16, crc);
131132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
132132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->version	= le16_to_cpu(cmd->version);
135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->opcode	= le16_to_cpu(cmd->opcode);
136132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->flags	= le32_to_cpu(cmd->flags);
137af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	cmd->tag	= le64_to_cpu(cmd->tag);
138132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->pdu_len	= le32_to_cpu(cmd->pdu_len);
139132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
140132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->version) {
141fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	case FIO_SERVER_VER:
142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
143132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
144132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: bad server cmd version %d\n", cmd->version);
145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd->pdu_len > FIO_SERVER_MAX_PDU) {
149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: command payload too large: %u\n", cmd->pdu_len);
150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
154132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
155132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
156a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
157a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands
158a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
159e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk)
160132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
161a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct fio_net_cmd cmd, *cmdret = NULL;
162a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	size_t cmd_size = 0, pdu_offset = 0;
163fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
164a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret, first = 1;
165a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	void *pdu = NULL;
166132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
167a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	do {
168a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, &cmd, sizeof(cmd));
169a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
170a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
171132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
172a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* We have a command, verify it and swap if need be */
173a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = verify_convert_cmd(&cmd);
174a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
175a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
176132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1770b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (first) {
1780b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			/* if this is text, add room for \0 at the end */
1790b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			cmd_size = sizeof(cmd) + cmd.pdu_len + 1;
1800b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			assert(!cmdret);
1810b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		} else
182a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			cmd_size += cmd.pdu_len;
183132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
184a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = realloc(cmdret, cmd_size);
185132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
186a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (first)
187a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			memcpy(cmdret, &cmd, sizeof(cmd));
18867f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		else if (cmdret->opcode != cmd.opcode) {
18967f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			log_err("fio: fragment opcode mismatch (%d != %d)\n",
19067f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe					cmdret->opcode, cmd.opcode);
19167f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			ret = 1;
19267f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			break;
19367f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		}
194a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
195a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (!cmd.pdu_len)
196a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
197a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
198a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* There's payload, get it */
199a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu = (void *) cmdret->payload + pdu_offset;
200a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, pdu, cmd.pdu_len);
201a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
202a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
203a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
204a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* Verify payload crc */
20525dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe		crc = fio_crc16(pdu, cmd.pdu_len);
206a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (crc != cmd.pdu_crc16) {
207a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("fio: server bad crc on payload ");
208a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc);
209a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			ret = 1;
210a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
211a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		}
212a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
213a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu_offset += cmd.pdu_len;
214817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe		if (!first)
215817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe			cmdret->pdu_len += cmd.pdu_len;
216a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		first = 0;
217a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	} while (cmd.flags & FIO_NET_CMD_F_MORE);
218132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
219a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	if (ret) {
220a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		free(cmdret);
221a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = NULL;
2220b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	} else if (cmdret) {
2230b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* zero-terminate text input */
2240b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT ||
2250b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		    cmdret->opcode == FIO_NET_CMD_JOB)) {
2260b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			char *buf = (char *) cmdret->payload;
2270b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
2280b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			buf[cmdret->pdu_len ] = '\0';
2290b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		}
2300b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* frag flag is internal */
231a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret->flags &= ~FIO_NET_CMD_F_MORE;
2320b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	}
233a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
234a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	return cmdret;
235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd)
238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
239132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	uint32_t pdu_len;
240132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
24125dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	cmd->cmd_crc16 = __cpu_to_le16(fio_crc16(cmd, FIO_NET_CMD_CRC_SZ));
242132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
243132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	pdu_len = le32_to_cpu(cmd->pdu_len);
244132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (pdu_len)
24525dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe		cmd->pdu_crc16 = __cpu_to_le16(fio_crc16(cmd->payload, pdu_len));
246132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
247132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
248af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
249af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		     uint64_t tag)
250794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{
2517f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	struct fio_net_cmd *cmd = NULL;
2527f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	size_t this_len, cur_len = 0;
253794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	int ret;
254794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
255794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	do {
256794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		this_len = size;
257794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len > FIO_SERVER_MAX_PDU)
258794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe			this_len = FIO_SERVER_MAX_PDU;
259794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
2607f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		if (!cmd || cur_len < sizeof(*cmd) + this_len) {
2617f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			if (cmd)
2627f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe				free(cmd);
2637f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
2647f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cur_len = sizeof(*cmd) + this_len;
2657f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cmd = malloc(cur_len);
2667f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		}
267794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
268af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		fio_init_net_cmd(cmd, opcode, buf, this_len, tag);
269794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
270794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len < size)
271ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe			cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE);
272794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
273794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_net_cmd_crc(cmd);
274794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
275794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
276794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		size -= this_len;
277794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		buf += this_len;
278794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	} while (!ret && size);
279794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
2807f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	if (cmd)
2817f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		free(cmd);
2827f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
283794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	return ret;
284794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe}
285794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
28689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag)
287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
288178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe	struct fio_net_cmd cmd;
289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
290af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_init_net_cmd(&cmd, opcode, NULL, 0, tag);
291132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fio_net_cmd_crc(&cmd);
292132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
293132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return fio_send_data(sk, &cmd, sizeof(cmd));
294132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
295132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
29689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe/*
29789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * If 'list' is non-NULL, then allocate and store the sent command for
29889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * later verification.
29989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe */
30089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag,
30189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			    struct flist_head *list)
30289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
30389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct fio_net_int_cmd *cmd;
30489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret;
30589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
30689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (!list)
30789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_net_send_simple_stack_cmd(sk, opcode, tag);
30889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
30989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	cmd = malloc(sizeof(*cmd));
31089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
311df380934e53c645b4b7cdec882b512b4d20ebc14Jens Axboe	fio_init_net_cmd(&cmd->cmd, opcode, NULL, 0, (uintptr_t) cmd);
31289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_net_cmd_crc(&cmd->cmd);
31389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
31489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	INIT_FLIST_HEAD(&cmd->list);
31589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	gettimeofday(&cmd->tv, NULL);
31689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	cmd->saved_tag = tag;
31789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
31889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	ret = fio_send_data(sk, &cmd->cmd, sizeof(cmd->cmd));
31989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (ret) {
32089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		free(cmd);
32189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return ret;
32289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
32389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
32489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_add_tail(&cmd->list, list);
32589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return 0;
32689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
32789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
3289abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic int fio_server_send_quit_cmd(void)
329437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{
33046c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: sending quit\n");
33189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0, NULL);
332437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe}
333437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe
3340b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd)
335132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
3360b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	char *buf = (char *) cmd->payload;
33711e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	struct cmd_start_pdu spdu;
33811e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	struct cmd_end_pdu epdu;
339a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret;
340132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
341e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	if (parse_jobs_ini(buf, 1, 0)) {
342e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe		fio_server_send_quit_cmd();
34381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
344e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
34581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
34611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
34711e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
34881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
3492e1df07d1ea30e0304cc65370f3ed161a6f22cd4Jens Axboe	ret = fio_backend();
35011e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
35111e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	epdu.error = ret;
35211e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), 0);
35311e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
3549abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe	fio_server_send_quit_cmd();
35581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	reset_fio_state();
35681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
35781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
35881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
35981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd)
36081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
361fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	void *pdu = cmd->payload;
362fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_single_line_pdu *cslp;
363fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_line_pdu *clp;
364fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	unsigned long offset;
365fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	char **argv;
36681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	int ret, i;
36781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
368fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp = pdu;
369fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp->lines = le16_to_cpu(clp->lines);
370fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	argv = malloc(clp->lines * sizeof(char *));
371fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	offset = sizeof(*clp);
37281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
373fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	dprint(FD_NET, "server: %d command line args\n", clp->lines);
37439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe
375fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	for (i = 0; i < clp->lines; i++) {
376fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp = pdu + offset;
377fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		argv[i] = (char *) cslp->text;
378fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
379fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		offset += sizeof(*cslp) + le16_to_cpu(cslp->len);
38039e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe		dprint(FD_NET, "server: %d: %s\n", i, argv[i]);
38139e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	}
38281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
383fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	if (parse_cmd_line(clp->lines, argv)) {
384e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe		fio_server_send_quit_cmd();
385fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		free(argv);
38681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
387e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
38881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
389fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	free(argv);
390fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
39189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0, NULL);
39281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
3932e1df07d1ea30e0304cc65370f3ed161a6f22cd4Jens Axboe	ret = fio_backend();
3949abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe	fio_server_send_quit_cmd();
395794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	reset_fio_state();
396132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
397132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
398132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
399c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd)
400c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{
401c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	struct cmd_probe_pdu probe;
402c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
40389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: sending probe reply\n");
40489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
405c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	memset(&probe, 0, sizeof(probe));
406c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	gethostname((char *) probe.hostname, sizeof(probe.hostname));
4076eb2479194603184f393057ea10326643edc7169Jens Axboe#ifdef FIO_BIG_ENDIAN
4086eb2479194603184f393057ea10326643edc7169Jens Axboe	probe.bigendian = 1;
4096eb2479194603184f393057ea10326643edc7169Jens Axboe#endif
41081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_major = FIO_MAJOR;
41181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_minor = FIO_MINOR;
41281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_patch = FIO_PATCH;
413c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
414cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.os	= FIO_OS;
415cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.arch	= FIO_ARCH;
416cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe
41738fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe	probe.bpp	= sizeof(void *);
41838fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe
41989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), cmd->tag);
420af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe}
421af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
422af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic int handle_send_eta_cmd(struct fio_net_cmd *cmd)
423af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{
424af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct jobs_eta *je;
425af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	size_t size;
426af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	int i;
427af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
428b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	if (!thread_number)
429b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe		return 0;
430b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe
431b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	size = sizeof(*je) + thread_number * sizeof(char) + 1;
4327f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	je = malloc(size);
4337f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	memset(je, 0, size);
434af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
435af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	if (!calc_thread_status(je, 1)) {
436af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		free(je);
437af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return 0;
438af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
439af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
440af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "server sending status\n");
441af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
442af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_running		= cpu_to_le32(je->nr_running);
443af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_ramp		= cpu_to_le32(je->nr_ramp);
444af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_pending		= cpu_to_le32(je->nr_pending);
445af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->files_open		= cpu_to_le32(je->files_open);
446af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->m_rate		= cpu_to_le32(je->m_rate);
447af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->t_rate		= cpu_to_le32(je->t_rate);
448af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->m_iops		= cpu_to_le32(je->m_iops);
449af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->t_iops		= cpu_to_le32(je->t_iops);
450af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
451af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	for (i = 0; i < 2; i++) {
452af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->rate[i]	= cpu_to_le32(je->rate[i]);
453af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->iops[i]	= cpu_to_le32(je->iops[i]);
454af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
455af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
456af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->elapsed_sec		= cpu_to_le32(je->nr_running);
457af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->eta_sec		= cpu_to_le64(je->eta_sec);
458af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
4597f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, cmd->tag);
460af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	free(je);
461af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	return 0;
462c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe}
463c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
464132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd)
465132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
466132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret;
467132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
46889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%lx\n",
46989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			fio_server_op(cmd->opcode), cmd->pdu_len, cmd->tag);
47046c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
471132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->opcode) {
472132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_QUIT:
473cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe		fio_terminate_threads(TERMINATE_ALL);
474c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
475d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe	case FIO_NET_CMD_EXIT:
476132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		exit_backend = 1;
477c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
478132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_JOB:
4790b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		ret = handle_job_cmd(cmd);
480132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
48181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	case FIO_NET_CMD_JOBLINE:
48281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		ret = handle_jobline_cmd(cmd);
48381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		break;
484c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	case FIO_NET_CMD_PROBE:
485c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		ret = handle_probe_cmd(cmd);
486c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		break;
487af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	case FIO_NET_CMD_SEND_ETA:
488af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		ret = handle_send_eta_cmd(cmd);
489af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		break;
490132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
49189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		log_err("fio: unknown opcode: %s\n",fio_server_op(cmd->opcode));
492132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = 1;
493132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
494132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
495132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
496132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
497132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
49870e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboestatic int handle_connection(int sk, int block)
499132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
500132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd *cmd = NULL;
501132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
502132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
503132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* read forever */
504132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	while (!exit_backend) {
505e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		struct pollfd pfd = {
506e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.fd	= sk,
507e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.events	= POLLIN,
508e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		};
509e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
510e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		ret = 0;
511e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		do {
512e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			ret = poll(&pfd, 1, 100);
513e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (ret < 0) {
514e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				if (errno == EINTR)
515e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe					break;
516e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
517e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
51819c65179fad3e0a32a450401ba7d312169627fddJens Axboe			} else if (!ret) {
51919c65179fad3e0a32a450401ba7d312169627fddJens Axboe				if (!block)
52019c65179fad3e0a32a450401ba7d312169627fddJens Axboe					return 0;
521e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				continue;
52219c65179fad3e0a32a450401ba7d312169627fddJens Axboe			}
523e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
524e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & POLLIN)
525e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
526e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & (POLLERR|POLLHUP)) {
527e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				ret = 1;
528e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
529e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			}
53019c65179fad3e0a32a450401ba7d312169627fddJens Axboe		} while (!exit_backend);
531e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
532e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		if (ret < 0)
533e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			break;
534e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
535e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		cmd = fio_net_recv_cmd(sk);
536132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (!cmd) {
537c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe			ret = -1;
538132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
539132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		}
540132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
541132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = handle_command(cmd);
542132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
543132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
544132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
545132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
546c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe		cmd = NULL;
547132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
548132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
549132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd)
550132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
551132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
552132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
553132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
554132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
555cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_server_idle_loop(void)
556cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{
55701be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe	if (!first_cmd_check)
55801be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe		fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_RUN, 0, NULL);
559cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	if (server_fd != -1)
56070e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe		handle_connection(server_fd, 0);
561cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
562cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
56350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
56450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
565bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	struct sockaddr_in addr;
5665ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe	fio_socklen_t len = sizeof(addr);
567009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
568132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret, sk, flags, exitval = 0;
56950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
57060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server enter accept loop\n");
57160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
572009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags = fcntl(listen_sk, F_GETFL);
573009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags |= O_NONBLOCK;
574009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	fcntl(listen_sk, F_SETFL, flags);
57550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain:
576009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.fd = listen_sk;
577009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.events = POLLIN;
578009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	do {
579009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		ret = poll(&pfd, 1, 100);
580009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (ret < 0) {
581009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			if (errno == EINTR)
582009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe				break;
583fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe			log_err("fio: poll: %s\n", strerror(errno));
584009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			goto out;
585009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		} else if (!ret)
586009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			continue;
587009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
588009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (pfd.revents & POLLIN)
589009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			break;
590009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	} while (!exit_backend);
591009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
592009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (exit_backend)
593009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		goto out;
594009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
5956b976bfcda733ad9a05ce28526f670a51096a771Jens Axboe	sk = accept(listen_sk, (struct sockaddr *) &addr, &len);
59650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (sk < 0) {
597690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: accept: %s\n", strerror(errno));
59850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
59950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
60050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
601bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr));
60246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
60337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = sk;
60437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
60570e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe	exitval = handle_connection(sk, 1);
60650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
60737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = -1;
60850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	close(sk);
6095c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
610009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (!exit_backend)
6115c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe		goto again;
6125c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
613009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout:
614132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return exitval;
61550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
61650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
61713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboeint fio_server_text_output(const char *buf, size_t len)
61837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
619337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe	if (server_fd != -1)
620af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len, 0);
621337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe
62213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return log_local_buf(buf, len);
623142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe}
624142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
625a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src)
626a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
627a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->max_val	= cpu_to_le64(src->max_val);
628a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->min_val	= cpu_to_le64(src->min_val);
629a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->samples	= cpu_to_le64(src->samples);
630802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
631802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	/*
632802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 * Encode to IEEE 754 for network transfer
633802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 */
634802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->mean.u.i	= __cpu_to_le64(fio_double_to_uint64(src->mean.u.f));
635802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->S.u.i	= __cpu_to_le64(fio_double_to_uint64(src->S.u.f));
636a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
637a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
638a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
639a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
640a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i;
641a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
642a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
643a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_run[i]		= cpu_to_le64(src->max_run[i]);
644a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_run[i]		= cpu_to_le64(src->min_run[i]);
645a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_bw[i]		= cpu_to_le64(src->max_bw[i]);
646a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_bw[i]		= cpu_to_le64(src->min_bw[i]);
647a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_kb[i]		= cpu_to_le64(src->io_kb[i]);
648a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->agg[i]		= cpu_to_le64(src->agg[i]);
649a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
650a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
651a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->kb_base	= cpu_to_le32(src->kb_base);
652a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= cpu_to_le32(src->groupid);
653a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
654a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
655a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
656a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats
657a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload.
658a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
659a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
660a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
661a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct cmd_ts_pdu p;
662a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i, j;
663a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
66460efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending end stats\n");
66560efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
666317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe	memset(&p, 0, sizeof(p));
667317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe
668a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.name, ts->name);
669a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.verror, ts->verror);
670a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.description, ts->description);
671a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
672ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.error	= cpu_to_le32(ts->error);
673a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.groupid	= cpu_to_le32(ts->groupid);
674ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.pid	= cpu_to_le32(ts->pid);
675a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.members	= cpu_to_le32(ts->members);
676a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
677a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
678a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]);
679a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]);
680a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]);
681a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]);
682a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
683a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
684a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.usr_time		= cpu_to_le64(ts->usr_time);
685a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.sys_time		= cpu_to_le64(ts->sys_time);
686a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.ctx		= cpu_to_le64(ts->ctx);
687a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.minf		= cpu_to_le64(ts->minf);
688a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.majf		= cpu_to_le64(ts->majf);
689a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.clat_percentiles	= cpu_to_le64(ts->clat_percentiles);
690802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
691802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
692cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *src = &ts->percentile_list[i];
693cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *dst = &p.ts.percentile_list[i];
694802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
695cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		dst->u.i = __cpu_to_le64(fio_double_to_uint64(src->u.f));
696802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	}
697a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
698a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
699a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_map[i]	= cpu_to_le32(ts->io_u_map[i]);
700a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_submit[i]	= cpu_to_le32(ts->io_u_submit[i]);
701a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_complete[i]	= cpu_to_le32(ts->io_u_complete[i]);
702a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
703a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
704a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
705a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_u[i]	= cpu_to_le32(ts->io_u_lat_u[i]);
706a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_m[i]	= cpu_to_le32(ts->io_u_lat_m[i]);
707a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
708a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
709a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++)
710a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
711a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]);
712a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
713a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 3; i++) {
714a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.total_io_u[i]	= cpu_to_le64(ts->total_io_u[i]);
71593eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe		p.ts.short_io_u[i]	= cpu_to_le64(ts->short_io_u[i]);
716a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
717a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
71893eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe	p.ts.total_submit	= cpu_to_le64(ts->total_submit);
719a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_complete	= cpu_to_le64(ts->total_complete);
720a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
721a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
722a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_bytes[i]	= cpu_to_le64(ts->io_bytes[i]);
723a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.runtime[i]		= cpu_to_le64(ts->runtime[i]);
724a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
725a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
726a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_run_time	= cpu_to_le64(ts->total_run_time);
727a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.continue_on_error	= cpu_to_le16(ts->continue_on_error);
728a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_err_count	= cpu_to_le64(ts->total_err_count);
729ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.first_error	= cpu_to_le32(ts->first_error);
730ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.kb_base		= cpu_to_le32(ts->kb_base);
731a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
732a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&p.rs, rs);
733a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
734af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0);
735a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
736a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
737a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs)
738a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
739a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct group_run_stats gs;
740a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
74160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending group run stats\n");
74260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
743a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&gs, rs);
744af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0);
745cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe}
746cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
747d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src)
748d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
749d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
750d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
751d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
752d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ios[i]	= cpu_to_le32(src->ios[i]);
753d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->merges[i]	= cpu_to_le32(src->merges[i]);
754d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
755d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
756d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
757d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
758d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->io_ticks		= cpu_to_le32(src->io_ticks);
759d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
760d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->slavecount		= cpu_to_le32(src->slavecount);
761d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->max_util.u.i	= __cpu_to_le64(fio_double_to_uint64(src->max_util.u.f));
762d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
763d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
764d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src)
765d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
766d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
767d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
768d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	strcpy((char *) dst->name, (char *) src->name);
769d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
770d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
771d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ios[i]	= cpu_to_le32(src->ios[i]);
772d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->merges[i]	= cpu_to_le32(src->merges[i]);
773d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
774d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
775d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
776d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
777d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->io_ticks		= cpu_to_le32(src->io_ticks);
778d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
779d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->msec		= cpu_to_le64(src->msec);
780d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
781d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
782d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboevoid fio_server_send_du(void)
783d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
784d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct disk_util *du;
785d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct flist_head *entry;
786d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct cmd_du_pdu pdu;
787d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
788d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dprint(FD_NET, "server: sending disk_util %d\n", !flist_empty(&disk_list));
789d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
7900766d92e06a119eea489e74d80d5840813559752Jens Axboe	memset(&pdu, 0, sizeof(pdu));
7910766d92e06a119eea489e74d80d5840813559752Jens Axboe
792d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	flist_for_each(entry, &disk_list) {
793d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		du = flist_entry(entry, struct disk_util, list);
794d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
795d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_dus(&pdu.dus, &du->dus);
796d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_agg(&pdu.agg, &du->agg);
797d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
798d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), 0);
799d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
800d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
801d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
802142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...)
803142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{
804142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	char buffer[1024];
805142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_list args;
80682fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	size_t len;
807142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
80860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server log\n");
80960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
810142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_start(args, format);
81182fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	len = vsnprintf(buffer, sizeof(buffer), format, args);
812142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_end(args);
813142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
81482fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	return fio_server_text_output(buffer, len);
81537db14feece08eb6e43de87c404180650ed5aa6fJens Axboe}
816e46d809110bd4ad2980ca64931b683673444454bJens Axboe
81787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_ip(void)
81881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
819811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	struct sockaddr *addr;
820811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	fio_socklen_t socklen;
82187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, opt;
82281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
823811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6)
824811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET6, SOCK_STREAM, 0);
825811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	else
826811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET, SOCK_STREAM, 0);
827811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
82881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (sk < 0) {
82981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
83081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
83181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
83281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
83381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	opt = 1;
83481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
83581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
836b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
83781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
83881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
83981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT
8406eb2479194603184f393057ea10326643edc7169Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
84181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
842b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
84381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
84481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
84581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif
84681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
847811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6) {
848811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in6;
849811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in6);
850811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in6.sin6_family = AF_INET6;
851811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else {
852811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in;
853811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in);
854811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in.sin_family = AF_INET;
855811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	}
85681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
857811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (bind(sk, addr, socklen) < 0) {
85881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
859b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
86081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
86181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
86281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
86387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
86487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
86587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
86687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_sock(void)
86787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
86887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un addr;
86987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_socklen_t len;
87087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode_t mode;
87187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
87287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
87387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = socket(AF_UNIX, SOCK_STREAM, 0);
87487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0) {
87587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: socket: %s\n", strerror(errno));
87687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
87787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
87887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
87987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode = umask(000);
88087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
88187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	memset(&addr, 0, sizeof(addr));
88287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	addr.sun_family = AF_UNIX;
88387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	strcpy(addr.sun_path, bind_sock);
88487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	unlink(bind_sock);
88587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
88687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	len = sizeof(addr.sun_family) + strlen(bind_sock) + 1;
88787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
88887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (bind(sk, (struct sockaddr *) &addr, len) < 0) {
88987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: bind: %s\n", strerror(errno));
890b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
89187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
89287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
89387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
89487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	umask(mode);
89587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
89687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
89787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
89887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_connection(void)
89987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
900bebe639808147d587bbe776566d390b9ff98773fJens Axboe	char bind_str[128];
90187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
90287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
90387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
90487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
90587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!bind_sock)
90687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_ip();
90787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	else
90887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_sock();
90987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
91087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
91187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return sk;
91287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
913811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (!bind_sock) {
914811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		char *p, port[16];
915811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		const void *src;
916811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		int af;
917811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
918811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (use_ipv6) {
919811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET6;
920811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in6.sin6_addr;
921811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		} else {
922811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET;
923811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in.sin_addr;
924811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		}
925811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
926811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		p = (char *) inet_ntop(af, src, bind_str, sizeof(bind_str));
927811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
928811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sprintf(port, ",%u", fio_net_port);
929811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (p)
930811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcat(p, port);
931811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		else
932811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcpy(bind_str, port);
933811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else
934bebe639808147d587bbe776566d390b9ff98773fJens Axboe		strcpy(bind_str, bind_sock);
935bebe639808147d587bbe776566d390b9ff98773fJens Axboe
936bebe639808147d587bbe776566d390b9ff98773fJens Axboe	log_info("fio: server listening on %s\n", bind_str);
937bebe639808147d587bbe776566d390b9ff98773fJens Axboe
93889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (listen(sk, 0) < 0) {
93981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
94081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
94181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
94281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
94387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
94487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
94587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
946660a2bfb0858f94633f9e567b81968981541f079Jens Axboe/*
947660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Parse a host/ip/port string. Reads from 'str'.
948660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
949660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Outputs:
950660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
951660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv4:
952660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp is the destination.
953660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv6:
954660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp6 is the dest, and *ipv6 is 1.
955660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For local domain sockets:
956660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the filename, *is_sock is 1.
957660a2bfb0858f94633f9e567b81968981541f079Jens Axboe */
958bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_server_parse_string(const char *str, char **ptr, int *is_sock,
959811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    int *port, struct in_addr *inp,
960811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    struct in6_addr *inp6, int *ipv6)
961bebe639808147d587bbe776566d390b9ff98773fJens Axboe{
96276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	const char *host = str;
96376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	char *portp;
96476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	int ret, lport = 0;
96576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
966bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*ptr = NULL;
967bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*is_sock = 0;
9686d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	*port = fio_net_port;
969811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	*ipv6 = 0;
970bebe639808147d587bbe776566d390b9ff98773fJens Axboe
971bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!strncmp(str, "sock:", 5)) {
972bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*ptr = strdup(str + 5);
973bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*is_sock = 1;
97476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
97576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
97676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
97776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
97876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
97976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * Is it ip:<ip or host>:port
98076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
98176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strncmp(host, "ip:", 3))
98276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 3;
98376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip4:", 4))
98476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
98576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip6:", 4)) {
98676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
98776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*ipv6 = 1;
98876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	} else if (host[0] == ':') {
98976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* String is :port */
99076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host++;
99176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		lport = atoi(host);
99276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!lport || lport > 65535) {
99376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			log_err("fio: bad server port %u\n", port);
99476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			return 1;
99576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
99676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* no hostname given, we are done */
99776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
99876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
99976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
100076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
100176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
100276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * If no port seen yet, check if there's a last ':' at the end
100376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
100476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!lport) {
100576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		portp = strchr(host, ',');
100676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (portp) {
100776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			*portp = '\0';
100876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			portp++;
100976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			lport = atoi(portp);
1010bebe639808147d587bbe776566d390b9ff98773fJens Axboe			if (!lport || lport > 65535) {
1011bebe639808147d587bbe776566d390b9ff98773fJens Axboe				log_err("fio: bad server port %u\n", port);
1012bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
1013bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
1014bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
101576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
1016bebe639808147d587bbe776566d390b9ff98773fJens Axboe
101776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (lport)
101876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
1019bebe639808147d587bbe776566d390b9ff98773fJens Axboe
102076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strlen(host))
102176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
1022bebe639808147d587bbe776566d390b9ff98773fJens Axboe
102376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	*ptr = strdup(host);
1024811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
102576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (*ipv6)
102676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		ret = inet_pton(AF_INET6, host, inp6);
102776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else
102876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		ret = inet_pton(AF_INET, host, inp);
1029bebe639808147d587bbe776566d390b9ff98773fJens Axboe
103076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (ret != 1) {
103176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		struct hostent *hent;
1032811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
103376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		hent = gethostbyname(host);
103476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!hent) {
103576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			log_err("fio: failed to resolve <%s>\n", host);
103676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			free(*ptr);
103776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			*ptr = NULL;
103876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			return 1;
103976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
1040bebe639808147d587bbe776566d390b9ff98773fJens Axboe
104176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (*ipv6) {
104276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			if (hent->h_addrtype != AF_INET6) {
104376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe				log_info("fio: falling back to IPv4\n");
104476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe				*ipv6 = 0;
104576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			} else
104676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe				memcpy(inp6, hent->h_addr_list[0], 16);
104776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
104876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!*ipv6) {
104976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			if (hent->h_addrtype != AF_INET) {
105076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe				log_err("fio: lookup type mismatch\n");
1051bebe639808147d587bbe776566d390b9ff98773fJens Axboe				free(*ptr);
1052bebe639808147d587bbe776566d390b9ff98773fJens Axboe				*ptr = NULL;
1053bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
1054bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
105576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			memcpy(inp, hent->h_addr_list[0], 4);
1056bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
1057bebe639808147d587bbe776566d390b9ff98773fJens Axboe	}
1058bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1059bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (*port == 0)
1060bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*port = fio_net_port;
1061bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1062bebe639808147d587bbe776566d390b9ff98773fJens Axboe	return 0;
1063bebe639808147d587bbe776566d390b9ff98773fJens Axboe}
1064bebe639808147d587bbe776566d390b9ff98773fJens Axboe
106587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe/*
106687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Server arg should be one of:
106787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
106887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * sock:/path/to/socket
106987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *   ip:1.2.3.4
107087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *      1.2.3.4
107187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
107287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Where sock uses unix domain sockets, and ip binds the server to
107387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * a specific interface. If no arguments are given to the server, it
107487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * uses IP and binds to 0.0.0.0.
107587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
107687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe */
107787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_handle_server_arg(void)
107887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
10796d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	int port = fio_net_port;
1080a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe	int is_sock, ret = 0;
1081bebe639808147d587bbe776566d390b9ff98773fJens Axboe
108287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
108387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
108487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!fio_server_arg)
1085a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe		goto out;
108687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
10874e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock,
1088811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&port, &saddr_in.sin_addr,
1089811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&saddr_in6.sin6_addr, &use_ipv6);
10904e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
10914e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	if (!is_sock && bind_sock) {
10924e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		free(bind_sock);
10934e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		bind_sock = NULL;
10944e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	}
10954e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
1096a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboeout:
10976d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	fio_net_port = port;
10986d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	saddr_in.sin_port = htons(port);
1099811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	saddr_in6.sin6_port = htons(port);
11004e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	return ret;
110187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
110287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
110387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_server(void)
110487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
110587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, ret;
110687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
110787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
110887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
110987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_handle_server_arg())
111087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
111187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
111287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = fio_init_server_connection();
111387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
111487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
111581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
111681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	ret = accept_loop(sk);
111787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
111881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	close(sk);
111987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
112087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_server_arg) {
112187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		free(fio_server_arg);
112287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fio_server_arg = NULL;
112387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
1124bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (bind_sock)
1125bebe639808147d587bbe776566d390b9ff98773fJens Axboe		free(bind_sock);
112687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
112781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
112881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
112981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
11307b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboevoid fio_server_got_signal(int signal)
11319abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{
11327b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	if (signal == SIGPIPE)
11337b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		server_fd = -1;
11347b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	else {
11357b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		log_info("\nfio: terminating on signal %d\n", signal);
11367b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		exit_backend = 1;
11377b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	}
11389abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe}
11399abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe
114013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int check_existing_pidfile(const char *pidfile)
114113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe{
114213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	struct stat sb;
114313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	char buf[16];
114413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid_t pid;
114513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	FILE *f;
114613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
114713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (stat(pidfile, &sb))
114813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
114913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
115013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	f = fopen(pidfile, "r");
115113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (!f)
115213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
115313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1154bfc3b17986fb80aeb5a6ea962bb38fc1509d60a8Jens Axboe	if (fread(buf, sb.st_size, 1, f) <= 0) {
115513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		fclose(f);
115613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
115713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
115813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(f);
115913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
116013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid = atoi(buf);
116113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (kill(pid, SIGCONT) < 0)
1162ea5aa1be68de71f9f02eb3d6f4db726adcafb40aJens Axboe		return errno != ESRCH;
116313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
116413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 1;
116513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe}
116613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
116713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int write_pid(pid_t pid, const char *pidfile)
1168402668f3e05259bfc135fc097136428feda01006Jens Axboe{
1169402668f3e05259bfc135fc097136428feda01006Jens Axboe	FILE *fpid;
1170402668f3e05259bfc135fc097136428feda01006Jens Axboe
1171402668f3e05259bfc135fc097136428feda01006Jens Axboe	fpid = fopen(pidfile, "w");
1172402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!fpid) {
1173402668f3e05259bfc135fc097136428feda01006Jens Axboe		log_err("fio: failed opening pid file %s\n", pidfile);
117413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
1175402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1176402668f3e05259bfc135fc097136428feda01006Jens Axboe
1177402668f3e05259bfc135fc097136428feda01006Jens Axboe	fprintf(fpid, "%u\n", (unsigned int) pid);
117813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(fpid);
117913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 0;
1180402668f3e05259bfc135fc097136428feda01006Jens Axboe}
1181402668f3e05259bfc135fc097136428feda01006Jens Axboe
1182402668f3e05259bfc135fc097136428feda01006Jens Axboe/*
1183402668f3e05259bfc135fc097136428feda01006Jens Axboe * If pidfile is specified, background us.
1184402668f3e05259bfc135fc097136428feda01006Jens Axboe */
1185402668f3e05259bfc135fc097136428feda01006Jens Axboeint fio_start_server(char *pidfile)
1186e46d809110bd4ad2980ca64931b683673444454bJens Axboe{
1187e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid_t pid;
1188402668f3e05259bfc135fc097136428feda01006Jens Axboe	int ret;
1189e46d809110bd4ad2980ca64931b683673444454bJens Axboe
119093bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#if defined(WIN32)
119193bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran    WSADATA wsd;
119293bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran    WSAStartup(MAKEWORD(2,2), &wsd);
119393bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#endif
119493bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran
1195402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!pidfile)
1196e46d809110bd4ad2980ca64931b683673444454bJens Axboe		return fio_server();
1197e46d809110bd4ad2980ca64931b683673444454bJens Axboe
119813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (check_existing_pidfile(pidfile)) {
119913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: pidfile %s exists and server appears alive\n",
120013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe								pidfile);
120113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return -1;
120213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
120313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1204e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid = fork();
1205e46d809110bd4ad2980ca64931b683673444454bJens Axboe	if (pid < 0) {
120613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: failed server fork: %s", strerror(errno));
1207402668f3e05259bfc135fc097136428feda01006Jens Axboe		free(pidfile);
1208c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
1209402668f3e05259bfc135fc097136428feda01006Jens Axboe	} else if (pid) {
121013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		int ret = write_pid(pid, pidfile);
121113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
121213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		exit(ret);
1213402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1214e46d809110bd4ad2980ca64931b683673444454bJens Axboe
1215e46d809110bd4ad2980ca64931b683673444454bJens Axboe	setsid();
121613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
121713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	log_syslog = 1;
1218e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDIN_FILENO);
1219e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDOUT_FILENO);
1220e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDERR_FILENO);
1221e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_out = NULL;
1222e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_err = NULL;
1223402668f3e05259bfc135fc097136428feda01006Jens Axboe
1224402668f3e05259bfc135fc097136428feda01006Jens Axboe	ret = fio_server();
1225402668f3e05259bfc135fc097136428feda01006Jens Axboe
1226402668f3e05259bfc135fc097136428feda01006Jens Axboe	closelog();
1227402668f3e05259bfc135fc097136428feda01006Jens Axboe	unlink(pidfile);
1228402668f3e05259bfc135fc097136428feda01006Jens Axboe	free(pidfile);
1229402668f3e05259bfc135fc097136428feda01006Jens Axboe	return ret;
1230e46d809110bd4ad2980ca64931b683673444454bJens Axboe}
123187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1232bebe639808147d587bbe776566d390b9ff98773fJens Axboevoid fio_server_set_arg(const char *arg)
123387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
123487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_server_arg = strdup(arg);
123587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
1236