server.c revision 0dcebdf4a70ef0d8144b8fcba763ae87e7fc74b5
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
25132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765;
2650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
27009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0;
28009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
2946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1;
3087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *fio_server_arg;
3187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic char *bind_sock;
3287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic struct sockaddr_in saddr_in;
33811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic struct sockaddr_in6 saddr_in6;
3401be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboestatic int first_cmd_check;
35811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboestatic int use_ipv6;
3637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
3789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic const char *fio_server_ops[FIO_NET_CMD_NR] = {
3889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"",
3989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"QUIT",
4089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"EXIT",
4189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOB",
4289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOBLINE",
4389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TEXT",
4489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TS",
4589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"GS",
4689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"SEND_ETA",
4789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"ETA",
4889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"PROBE",
4989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"START",
50d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"STOP",
51d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	"DISK_UTIL",
5201be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe	"RUN",
5389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe};
5489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
5589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeconst char *fio_server_op(unsigned int op)
5689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
5789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	static char buf[32];
5889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
5989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (op < FIO_NET_CMD_NR)
6089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_server_ops[op];
6189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
6289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	sprintf(buf, "UNKNOWN/%d", op);
6389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return buf;
6489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
6589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
66132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len)
67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
68794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU);
69794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = send(sk, p, len, 0);
72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
80132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
81132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
82132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
837b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
847b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
85132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
86132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
87132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 1;
91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len)
94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = recv(sk, p, len, MSG_WAITALL);
97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
1087b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
1097b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
111132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
113132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
114132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
115132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return -1;
116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
117132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
118132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd)
119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
120fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
122fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16);
123fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16);
124132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
12525dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	crc = fio_crc16(cmd, FIO_NET_CMD_CRC_SZ);
126fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != cmd->cmd_crc16) {
127132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on command (got %x, wanted %x)\n",
128fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				cmd->cmd_crc16, crc);
129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
130132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
131132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
132132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->version	= le16_to_cpu(cmd->version);
133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->opcode	= le16_to_cpu(cmd->opcode);
134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->flags	= le32_to_cpu(cmd->flags);
135af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	cmd->tag	= le64_to_cpu(cmd->tag);
136132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->pdu_len	= le32_to_cpu(cmd->pdu_len);
137132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
138132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->version) {
139fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	case FIO_SERVER_VER:
140132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
141132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: bad server cmd version %d\n", cmd->version);
143132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
144132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd->pdu_len > FIO_SERVER_MAX_PDU) {
147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: command payload too large: %u\n", cmd->pdu_len);
148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
154a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
155a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands
156a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
157e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk)
158132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
159a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct fio_net_cmd cmd, *cmdret = NULL;
160a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	size_t cmd_size = 0, pdu_offset = 0;
161fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
162a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret, first = 1;
163a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	void *pdu = NULL;
164132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
165a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	do {
166a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, &cmd, sizeof(cmd));
167a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
168a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
169132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
170a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* We have a command, verify it and swap if need be */
171a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = verify_convert_cmd(&cmd);
172a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
173a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
174132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1750b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (first) {
1760b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			/* if this is text, add room for \0 at the end */
1770b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			cmd_size = sizeof(cmd) + cmd.pdu_len + 1;
1780b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			assert(!cmdret);
1790b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		} else
180a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			cmd_size += cmd.pdu_len;
181132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
182a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = realloc(cmdret, cmd_size);
183132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
184a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (first)
185a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			memcpy(cmdret, &cmd, sizeof(cmd));
18667f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		else if (cmdret->opcode != cmd.opcode) {
18767f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			log_err("fio: fragment opcode mismatch (%d != %d)\n",
18867f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe					cmdret->opcode, cmd.opcode);
18967f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			ret = 1;
19067f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe			break;
19167f15dcf689815ec4fbe2cbb01f141ffc7b34c74Jens Axboe		}
192a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
193a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (!cmd.pdu_len)
194a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
195a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
196a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* There's payload, get it */
197a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu = (void *) cmdret->payload + pdu_offset;
198a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, pdu, cmd.pdu_len);
199a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
200a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
201a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
202a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* Verify payload crc */
20325dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe		crc = fio_crc16(pdu, cmd.pdu_len);
204a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (crc != cmd.pdu_crc16) {
205a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("fio: server bad crc on payload ");
206a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc);
207a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			ret = 1;
208a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
209a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		}
210a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
211a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu_offset += cmd.pdu_len;
212817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe		if (!first)
213817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe			cmdret->pdu_len += cmd.pdu_len;
214a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		first = 0;
215a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	} while (cmd.flags & FIO_NET_CMD_F_MORE);
216132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
217a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	if (ret) {
218a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		free(cmdret);
219a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = NULL;
2200b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	} else if (cmdret) {
2210b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* zero-terminate text input */
2220b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT ||
2230b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		    cmdret->opcode == FIO_NET_CMD_JOB)) {
2240b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			char *buf = (char *) cmdret->payload;
2250b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
2260b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			buf[cmdret->pdu_len ] = '\0';
2270b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		}
2280b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* frag flag is internal */
229a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret->flags &= ~FIO_NET_CMD_F_MORE;
2300b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	}
231a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
232a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	return cmdret;
233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
234132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd)
236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	uint32_t pdu_len;
238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
23925dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe	cmd->cmd_crc16 = __cpu_to_le16(fio_crc16(cmd, FIO_NET_CMD_CRC_SZ));
240132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
241132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	pdu_len = le32_to_cpu(cmd->pdu_len);
242132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (pdu_len)
24325dfa848abbb6c35b4d45fabd5a8e82cb77fb285Jens Axboe		cmd->pdu_crc16 = __cpu_to_le16(fio_crc16(cmd->payload, pdu_len));
244132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
245132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
246af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
247af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		     uint64_t tag)
248794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{
2497f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	struct fio_net_cmd *cmd = NULL;
2507f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	size_t this_len, cur_len = 0;
251794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	int ret;
252794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
253794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	do {
254794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		this_len = size;
255794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len > FIO_SERVER_MAX_PDU)
256794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe			this_len = FIO_SERVER_MAX_PDU;
257794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
2587f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		if (!cmd || cur_len < sizeof(*cmd) + this_len) {
2597f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			if (cmd)
2607f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe				free(cmd);
2617f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
2627f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cur_len = sizeof(*cmd) + this_len;
2637f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cmd = malloc(cur_len);
2647f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		}
265794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
266af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		fio_init_net_cmd(cmd, opcode, buf, this_len, tag);
267794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
268794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len < size)
269ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe			cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE);
270794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
271794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_net_cmd_crc(cmd);
272794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
273794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
274794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		size -= this_len;
275794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		buf += this_len;
276794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	} while (!ret && size);
277794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
2787f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	if (cmd)
2797f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		free(cmd);
2807f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
281794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	return ret;
282794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe}
283794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
28489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag)
285132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
286178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe	struct fio_net_cmd cmd;
287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
288af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_init_net_cmd(&cmd, opcode, NULL, 0, tag);
289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fio_net_cmd_crc(&cmd);
290132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
291132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return fio_send_data(sk, &cmd, sizeof(cmd));
292132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
293132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
29489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe/*
29589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * If 'list' is non-NULL, then allocate and store the sent command for
29689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * later verification.
29789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe */
29889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag,
29989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			    struct flist_head *list)
30089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
30189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct fio_net_int_cmd *cmd;
30289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret;
30389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
30489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (!list)
30589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_net_send_simple_stack_cmd(sk, opcode, tag);
30689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
30789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	cmd = malloc(sizeof(*cmd));
30889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
309df380934e53c645b4b7cdec882b512b4d20ebc14Jens Axboe	fio_init_net_cmd(&cmd->cmd, opcode, NULL, 0, (uintptr_t) cmd);
31089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_net_cmd_crc(&cmd->cmd);
31189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
31289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	INIT_FLIST_HEAD(&cmd->list);
31367bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	fio_gettime(&cmd->tv, NULL);
31489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	cmd->saved_tag = tag;
31589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
31689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	ret = fio_send_data(sk, &cmd->cmd, sizeof(cmd->cmd));
31789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (ret) {
31889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		free(cmd);
31989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return ret;
32089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
32189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
32289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_add_tail(&cmd->list, list);
32389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return 0;
32489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
32589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
3269abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic int fio_server_send_quit_cmd(void)
327437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{
32846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: sending quit\n");
32989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0, NULL);
330437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe}
331437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe
3320b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd)
333132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
3340b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	char *buf = (char *) cmd->payload;
33511e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	struct cmd_start_pdu spdu;
33611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	struct cmd_end_pdu epdu;
337a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret;
338132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
339e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	if (parse_jobs_ini(buf, 1, 0)) {
340e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe		fio_server_send_quit_cmd();
34181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
342e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
34381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
34411e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	spdu.jobs = cpu_to_le32(thread_number);
345108fea772db5f1dd91e2fb67737e3e0d36827b76Jens Axboe	spdu.stat_outputs = cpu_to_le32(stat_number);
34611e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_START, &spdu, sizeof(spdu), 0);
34781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
3482e1df07d1ea30e0304cc65370f3ed161a6f22cd4Jens Axboe	ret = fio_backend();
34911e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
35011e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	epdu.error = ret;
35111e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_STOP, &epdu, sizeof(epdu), 0);
35211e950bd785d9f03b7d35a8ee4b4704256217504Jens Axboe
3539abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe	fio_server_send_quit_cmd();
35481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	reset_fio_state();
35581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
35681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
35781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
35881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd)
35981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
360fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	void *pdu = cmd->payload;
361fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_single_line_pdu *cslp;
362fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_line_pdu *clp;
363fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	unsigned long offset;
364fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	char **argv;
36581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	int ret, i;
36681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
367fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp = pdu;
368fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp->lines = le16_to_cpu(clp->lines);
369fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	argv = malloc(clp->lines * sizeof(char *));
370fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	offset = sizeof(*clp);
37181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
372fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	dprint(FD_NET, "server: %d command line args\n", clp->lines);
37339e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe
374fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	for (i = 0; i < clp->lines; i++) {
375fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp = pdu + offset;
376fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		argv[i] = (char *) cslp->text;
377fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
378fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		offset += sizeof(*cslp) + le16_to_cpu(cslp->len);
37939e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe		dprint(FD_NET, "server: %d: %s\n", i, argv[i]);
38039e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	}
38181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
382fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	if (parse_cmd_line(clp->lines, argv)) {
383e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe		fio_server_send_quit_cmd();
384fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		free(argv);
38581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
386e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
38781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
388fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	free(argv);
389fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
39089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0, NULL);
39181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
3922e1df07d1ea30e0304cc65370f3ed161a6f22cd4Jens Axboe	ret = fio_backend();
3939abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe	fio_server_send_quit_cmd();
394794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	reset_fio_state();
395132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
396132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
397132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
398c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd)
399c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{
400c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	struct cmd_probe_pdu probe;
401c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
40289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: sending probe reply\n");
40389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
404c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	memset(&probe, 0, sizeof(probe));
405c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	gethostname((char *) probe.hostname, sizeof(probe.hostname));
4060dcebdf4a70ef0d8144b8fcba763ae87e7fc74b5Jens Axboe#ifdef CONFIG_BIG_ENDIAN
4076eb2479194603184f393057ea10326643edc7169Jens Axboe	probe.bigendian = 1;
4086eb2479194603184f393057ea10326643edc7169Jens Axboe#endif
4095c3f7cea8db0715b6bf8ebd79680f4a703128921Jens Axboe	strncpy((char *) probe.fio_version, fio_version_string, sizeof(probe.fio_version));
410c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
411cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.os	= FIO_OS;
412cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.arch	= FIO_ARCH;
413cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe
41438fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe	probe.bpp	= sizeof(void *);
41538fdef226f1a1fa053ab53005abbc184143bff65Jens Axboe
41689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), cmd->tag);
417af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe}
418af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
419af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic int handle_send_eta_cmd(struct fio_net_cmd *cmd)
420af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{
421af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct jobs_eta *je;
422af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	size_t size;
423af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	int i;
424af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
425b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	if (!thread_number)
426b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe		return 0;
427b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe
428b814fb2694fe178b5cb94e046b9d31944e752f4aJens Axboe	size = sizeof(*je) + thread_number * sizeof(char) + 1;
4297f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	je = malloc(size);
4307f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	memset(je, 0, size);
431af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
432af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	if (!calc_thread_status(je, 1)) {
433af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		free(je);
434af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return 0;
435af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
436af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
437af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "server sending status\n");
438af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
439af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_running		= cpu_to_le32(je->nr_running);
440af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_ramp		= cpu_to_le32(je->nr_ramp);
441af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_pending		= cpu_to_le32(je->nr_pending);
442af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->files_open		= cpu_to_le32(je->files_open);
443af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->m_rate		= cpu_to_le32(je->m_rate);
444af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->t_rate		= cpu_to_le32(je->t_rate);
445af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->m_iops		= cpu_to_le32(je->m_iops);
446af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->t_iops		= cpu_to_le32(je->t_iops);
447af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
448af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	for (i = 0; i < 2; i++) {
449af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->rate[i]	= cpu_to_le32(je->rate[i]);
450af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->iops[i]	= cpu_to_le32(je->iops[i]);
451af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
452af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
453abcf4b754bd9c863ad1e0102c8ea11e86aff85b3Jens Axboe	je->elapsed_sec		= cpu_to_le64(je->elapsed_sec);
454af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->eta_sec		= cpu_to_le64(je->eta_sec);
455b7f05eb03c84bdc1259d1bb1c348328b16164430Jens Axboe	je->is_pow2		= cpu_to_le32(je->is_pow2);
456af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
4577f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, cmd->tag);
458af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	free(je);
459af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	return 0;
460c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe}
461c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
462132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd)
463132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
464132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret;
465132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
46689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%lx\n",
46789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			fio_server_op(cmd->opcode), cmd->pdu_len, cmd->tag);
46846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
469132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->opcode) {
470132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_QUIT:
471cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe		fio_terminate_threads(TERMINATE_ALL);
472c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
473d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe	case FIO_NET_CMD_EXIT:
474132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		exit_backend = 1;
475c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
476132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_JOB:
4770b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		ret = handle_job_cmd(cmd);
478132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
47981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	case FIO_NET_CMD_JOBLINE:
48081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		ret = handle_jobline_cmd(cmd);
48181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		break;
482c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	case FIO_NET_CMD_PROBE:
483c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		ret = handle_probe_cmd(cmd);
484c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		break;
485af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	case FIO_NET_CMD_SEND_ETA:
486af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		ret = handle_send_eta_cmd(cmd);
487af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		break;
488132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
48989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		log_err("fio: unknown opcode: %s\n",fio_server_op(cmd->opcode));
490132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = 1;
491132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
492132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
493132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
494132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
495132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
49670e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboestatic int handle_connection(int sk, int block)
497132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
498132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd *cmd = NULL;
499132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
500132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
501132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* read forever */
502132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	while (!exit_backend) {
503e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		struct pollfd pfd = {
504e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.fd	= sk,
505e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.events	= POLLIN,
506e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		};
507e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
508e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		ret = 0;
509e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		do {
510e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			ret = poll(&pfd, 1, 100);
511e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (ret < 0) {
512e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				if (errno == EINTR)
513e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe					break;
514e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
515e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
51619c65179fad3e0a32a450401ba7d312169627fddJens Axboe			} else if (!ret) {
51719c65179fad3e0a32a450401ba7d312169627fddJens Axboe				if (!block)
51819c65179fad3e0a32a450401ba7d312169627fddJens Axboe					return 0;
519e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				continue;
52019c65179fad3e0a32a450401ba7d312169627fddJens Axboe			}
521e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
522e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & POLLIN)
523e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
524e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & (POLLERR|POLLHUP)) {
525e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				ret = 1;
526e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
527e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			}
52819c65179fad3e0a32a450401ba7d312169627fddJens Axboe		} while (!exit_backend);
529e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
530e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		if (ret < 0)
531e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			break;
532e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
533e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		cmd = fio_net_recv_cmd(sk);
534132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (!cmd) {
535c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe			ret = -1;
536132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
537132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		}
538132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
539132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = handle_command(cmd);
540132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
541132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
542132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
543132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
544c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe		cmd = NULL;
545132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
546132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
547132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd)
548132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
549132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
550132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
551132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
552132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
553cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_server_idle_loop(void)
554cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{
55501be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe	if (!first_cmd_check)
55601be038efc66ea1b49b4471f2ba9dd2d7121cfe7Jens Axboe		fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_RUN, 0, NULL);
557cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	if (server_fd != -1)
55870e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe		handle_connection(server_fd, 0);
559cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
560cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
56150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
56250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
563bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	struct sockaddr_in addr;
56467bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	socklen_t len = sizeof(addr);
565009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
566132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret, sk, flags, exitval = 0;
56750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
56860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server enter accept loop\n");
56960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
570009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags = fcntl(listen_sk, F_GETFL);
571009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags |= O_NONBLOCK;
572009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	fcntl(listen_sk, F_SETFL, flags);
57350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain:
574009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.fd = listen_sk;
575009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.events = POLLIN;
576009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	do {
577009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		ret = poll(&pfd, 1, 100);
578009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (ret < 0) {
579009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			if (errno == EINTR)
580009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe				break;
581fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe			log_err("fio: poll: %s\n", strerror(errno));
582009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			goto out;
583009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		} else if (!ret)
584009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			continue;
585009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
586009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (pfd.revents & POLLIN)
587009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			break;
588009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	} while (!exit_backend);
589009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
590009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (exit_backend)
591009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		goto out;
592009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
5936b976bfcda733ad9a05ce28526f670a51096a771Jens Axboe	sk = accept(listen_sk, (struct sockaddr *) &addr, &len);
59450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (sk < 0) {
595690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: accept: %s\n", strerror(errno));
59650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
59750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
59850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
599bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr));
60046c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
60137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = sk;
60237db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
60370e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe	exitval = handle_connection(sk, 1);
60450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
60537db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = -1;
60650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	close(sk);
6075c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
608009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (!exit_backend)
6095c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe		goto again;
6105c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
611009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout:
612132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return exitval;
61350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
61450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
61513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboeint fio_server_text_output(const char *buf, size_t len)
61637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
617337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe	if (server_fd != -1)
618af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len, 0);
619337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe
62013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return log_local_buf(buf, len);
621142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe}
622142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
623a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src)
624a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
625a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->max_val	= cpu_to_le64(src->max_val);
626a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->min_val	= cpu_to_le64(src->min_val);
627a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->samples	= cpu_to_le64(src->samples);
628802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
629802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	/*
630802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 * Encode to IEEE 754 for network transfer
631802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 */
632802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->mean.u.i	= __cpu_to_le64(fio_double_to_uint64(src->mean.u.f));
633802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->S.u.i	= __cpu_to_le64(fio_double_to_uint64(src->S.u.f));
634a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
635a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
636a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
637a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
638a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i;
639a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
640a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
641a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_run[i]		= cpu_to_le64(src->max_run[i]);
642a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_run[i]		= cpu_to_le64(src->min_run[i]);
643a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_bw[i]		= cpu_to_le64(src->max_bw[i]);
644a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_bw[i]		= cpu_to_le64(src->min_bw[i]);
645a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_kb[i]		= cpu_to_le64(src->io_kb[i]);
646a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->agg[i]		= cpu_to_le64(src->agg[i]);
647a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
648a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
649a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->kb_base	= cpu_to_le32(src->kb_base);
650a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= cpu_to_le32(src->groupid);
651a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
652a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
653a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
654a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats
655a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload.
656a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
657a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
658a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
659a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct cmd_ts_pdu p;
660a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i, j;
661a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
66260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending end stats\n");
66360efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
664317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe	memset(&p, 0, sizeof(p));
665317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe
666a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.name, ts->name);
667a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.verror, ts->verror);
668a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.description, ts->description);
669a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
670ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.error	= cpu_to_le32(ts->error);
671a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.groupid	= cpu_to_le32(ts->groupid);
672ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.pid	= cpu_to_le32(ts->pid);
673a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.members	= cpu_to_le32(ts->members);
674a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
675a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
676a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]);
677a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]);
678a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]);
679a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]);
680a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
681a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
682a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.usr_time		= cpu_to_le64(ts->usr_time);
683a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.sys_time		= cpu_to_le64(ts->sys_time);
684a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.ctx		= cpu_to_le64(ts->ctx);
685a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.minf		= cpu_to_le64(ts->minf);
686a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.majf		= cpu_to_le64(ts->majf);
687a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.clat_percentiles	= cpu_to_le64(ts->clat_percentiles);
688802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
689802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
690cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *src = &ts->percentile_list[i];
691cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		fio_fp64_t *dst = &p.ts.percentile_list[i];
692802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
693cfc03e4639fc29bf879f565300fe0238dd8b5ba9Jens Axboe		dst->u.i = __cpu_to_le64(fio_double_to_uint64(src->u.f));
694802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	}
695a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
696a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
697a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_map[i]	= cpu_to_le32(ts->io_u_map[i]);
698a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_submit[i]	= cpu_to_le32(ts->io_u_submit[i]);
699a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_complete[i]	= cpu_to_le32(ts->io_u_complete[i]);
700a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
701a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
702a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
703a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_u[i]	= cpu_to_le32(ts->io_u_lat_u[i]);
704a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_m[i]	= cpu_to_le32(ts->io_u_lat_m[i]);
705a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
706a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
707a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++)
708a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
709a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]);
710a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
711a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 3; i++) {
712a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.total_io_u[i]	= cpu_to_le64(ts->total_io_u[i]);
71393eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe		p.ts.short_io_u[i]	= cpu_to_le64(ts->short_io_u[i]);
714a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
715a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
71693eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe	p.ts.total_submit	= cpu_to_le64(ts->total_submit);
717a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_complete	= cpu_to_le64(ts->total_complete);
718a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
719a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
720a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_bytes[i]	= cpu_to_le64(ts->io_bytes[i]);
721a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.runtime[i]		= cpu_to_le64(ts->runtime[i]);
722a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
723a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
724a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_run_time	= cpu_to_le64(ts->total_run_time);
725a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.continue_on_error	= cpu_to_le16(ts->continue_on_error);
726a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_err_count	= cpu_to_le64(ts->total_err_count);
727ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.first_error	= cpu_to_le32(ts->first_error);
728ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.kb_base		= cpu_to_le32(ts->kb_base);
729a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
730a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&p.rs, rs);
731a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
732af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0);
733a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
734a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
735a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs)
736a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
737a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct group_run_stats gs;
738a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
73960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending group run stats\n");
74060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
741a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&gs, rs);
742af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0);
743cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe}
744cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
745d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src)
746d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
747d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
748d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
749d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
750d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ios[i]	= cpu_to_le32(src->ios[i]);
751d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->merges[i]	= cpu_to_le32(src->merges[i]);
752d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
753d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
754d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
755d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
756d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->io_ticks		= cpu_to_le32(src->io_ticks);
757d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
758d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->slavecount		= cpu_to_le32(src->slavecount);
759d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->max_util.u.i	= __cpu_to_le64(fio_double_to_uint64(src->max_util.u.f));
760d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
761d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
762d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboestatic void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src)
763d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
764d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	int i;
765d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
766d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	strcpy((char *) dst->name, (char *) src->name);
767d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
768d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	for (i = 0; i < 2; i++) {
769d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ios[i]	= cpu_to_le32(src->ios[i]);
770d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->merges[i]	= cpu_to_le32(src->merges[i]);
771d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
772d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
773d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
774d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
775d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->io_ticks		= cpu_to_le32(src->io_ticks);
776d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
777d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dst->msec		= cpu_to_le64(src->msec);
778d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
779d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
780d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboevoid fio_server_send_du(void)
781d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{
782d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct disk_util *du;
783d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct flist_head *entry;
784d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	struct cmd_du_pdu pdu;
785d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
786d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	dprint(FD_NET, "server: sending disk_util %d\n", !flist_empty(&disk_list));
787d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
7880766d92e06a119eea489e74d80d5840813559752Jens Axboe	memset(&pdu, 0, sizeof(pdu));
7890766d92e06a119eea489e74d80d5840813559752Jens Axboe
790d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	flist_for_each(entry, &disk_list) {
791d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		du = flist_entry(entry, struct disk_util, list);
792d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
793d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_dus(&pdu.dus, &du->dus);
794d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		convert_agg(&pdu.agg, &du->agg);
795d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
796d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe		fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), 0);
797d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe	}
798d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe}
799d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe
800142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...)
801142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{
802142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	char buffer[1024];
803142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_list args;
80482fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	size_t len;
805142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
80660efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server log\n");
80760efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
808142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_start(args, format);
80982fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	len = vsnprintf(buffer, sizeof(buffer), format, args);
810142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_end(args);
811142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
81282fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	return fio_server_text_output(buffer, len);
81337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe}
814e46d809110bd4ad2980ca64931b683673444454bJens Axboe
81587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_ip(void)
81681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
817811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	struct sockaddr *addr;
81867bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	socklen_t socklen;
81987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, opt;
82081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
821811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6)
822811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET6, SOCK_STREAM, 0);
823811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	else
824811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sk = socket(AF_INET, SOCK_STREAM, 0);
825811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
82681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (sk < 0) {
82781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
82881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
82981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
83081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
83181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	opt = 1;
83281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
83381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
834b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
83581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
83681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
83781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT
8386eb2479194603184f393057ea10326643edc7169Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
83981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
840b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
84181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
84281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
84381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif
84481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
845811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (use_ipv6) {
846811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in6;
847811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in6);
848811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in6.sin6_family = AF_INET6;
849811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else {
850811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		addr = (struct sockaddr *) &saddr_in;
851811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		socklen = sizeof(saddr_in);
852811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		saddr_in.sin_family = AF_INET;
853811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	}
85481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
855811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (bind(sk, addr, socklen) < 0) {
85681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
857b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
85881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
85981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
86081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
86187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
86287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
86387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
86487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_sock(void)
86587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
86687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un addr;
86767bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe	socklen_t len;
86887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode_t mode;
86987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
87087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
87187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = socket(AF_UNIX, SOCK_STREAM, 0);
87287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0) {
87387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: socket: %s\n", strerror(errno));
87487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
87587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
87687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
87787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode = umask(000);
87887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
87987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	memset(&addr, 0, sizeof(addr));
88087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	addr.sun_family = AF_UNIX;
88187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	strcpy(addr.sun_path, bind_sock);
88287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	unlink(bind_sock);
88387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
88487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	len = sizeof(addr.sun_family) + strlen(bind_sock) + 1;
88587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
88687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (bind(sk, (struct sockaddr *) &addr, len) < 0) {
88787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: bind: %s\n", strerror(errno));
888b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
88987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
89087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
89187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
89287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	umask(mode);
89387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
89487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
89587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
89687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_connection(void)
89787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
898bebe639808147d587bbe776566d390b9ff98773fJens Axboe	char bind_str[128];
89987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
90087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
90187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
90287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
90387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!bind_sock)
90487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_ip();
90587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	else
90687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_sock();
90787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
90887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
90987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return sk;
91087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
911811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	if (!bind_sock) {
912811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		char *p, port[16];
913811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		const void *src;
914811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		int af;
915811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
916811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (use_ipv6) {
917811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET6;
918811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in6.sin6_addr;
919811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		} else {
920811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			af = AF_INET;
921811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			src = &saddr_in.sin_addr;
922811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		}
923811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
924811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		p = (char *) inet_ntop(af, src, bind_str, sizeof(bind_str));
925811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
926811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		sprintf(port, ",%u", fio_net_port);
927811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		if (p)
928811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcat(p, port);
929811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe		else
930811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			strcpy(bind_str, port);
931811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	} else
932bebe639808147d587bbe776566d390b9ff98773fJens Axboe		strcpy(bind_str, bind_sock);
933bebe639808147d587bbe776566d390b9ff98773fJens Axboe
934bebe639808147d587bbe776566d390b9ff98773fJens Axboe	log_info("fio: server listening on %s\n", bind_str);
935bebe639808147d587bbe776566d390b9ff98773fJens Axboe
93689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (listen(sk, 0) < 0) {
93781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
93881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
93981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
94081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
94187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
94287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
94387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
944660a2bfb0858f94633f9e567b81968981541f079Jens Axboe/*
945660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Parse a host/ip/port string. Reads from 'str'.
946660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
947660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * Outputs:
948660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *
949660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv4:
950660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp is the destination.
951660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For IPv6:
952660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the host, *port is the port, inp6 is the dest, and *ipv6 is 1.
953660a2bfb0858f94633f9e567b81968981541f079Jens Axboe * For local domain sockets:
954660a2bfb0858f94633f9e567b81968981541f079Jens Axboe *	*ptr is the filename, *is_sock is 1.
955660a2bfb0858f94633f9e567b81968981541f079Jens Axboe */
956bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_server_parse_string(const char *str, char **ptr, int *is_sock,
957811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    int *port, struct in_addr *inp,
958811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe			    struct in6_addr *inp6, int *ipv6)
959bebe639808147d587bbe776566d390b9ff98773fJens Axboe{
96076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	const char *host = str;
96176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	char *portp;
96276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	int ret, lport = 0;
96376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
964bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*ptr = NULL;
965bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*is_sock = 0;
9666d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	*port = fio_net_port;
967811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	*ipv6 = 0;
968bebe639808147d587bbe776566d390b9ff98773fJens Axboe
969bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!strncmp(str, "sock:", 5)) {
970bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*ptr = strdup(str + 5);
971bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*is_sock = 1;
97276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
97376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
97476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
97576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
97676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
97776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * Is it ip:<ip or host>:port
97876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
97976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strncmp(host, "ip:", 3))
98076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 3;
98176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip4:", 4))
98276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
98376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else if (!strncmp(host, "ip6:", 4)) {
98476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host += 4;
98576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*ipv6 = 1;
98676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	} else if (host[0] == ':') {
98776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* String is :port */
98876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		host++;
98976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		lport = atoi(host);
99076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!lport || lport > 65535) {
99176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			log_err("fio: bad server port %u\n", port);
99276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			return 1;
99376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
99476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		/* no hostname given, we are done */
99576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
99676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
99776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
99876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe
99976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	/*
100076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 * If no port seen yet, check if there's a last ':' at the end
100176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	 */
100276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!lport) {
100376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		portp = strchr(host, ',');
100476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (portp) {
100576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			*portp = '\0';
100676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			portp++;
100776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			lport = atoi(portp);
1008bebe639808147d587bbe776566d390b9ff98773fJens Axboe			if (!lport || lport > 65535) {
1009bebe639808147d587bbe776566d390b9ff98773fJens Axboe				log_err("fio: bad server port %u\n", port);
1010bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
1011bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
1012bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
101376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	}
1014bebe639808147d587bbe776566d390b9ff98773fJens Axboe
101576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (lport)
101676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		*port = lport;
1017bebe639808147d587bbe776566d390b9ff98773fJens Axboe
101876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (!strlen(host))
101976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		return 0;
1020bebe639808147d587bbe776566d390b9ff98773fJens Axboe
102176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	*ptr = strdup(host);
1022811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
102376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (*ipv6)
102476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		ret = inet_pton(AF_INET6, host, inp6);
102576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	else
102676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		ret = inet_pton(AF_INET, host, inp);
1027bebe639808147d587bbe776566d390b9ff98773fJens Axboe
102876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe	if (ret != 1) {
102976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		struct hostent *hent;
1030811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe
103176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		hent = gethostbyname(host);
103276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!hent) {
103376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			log_err("fio: failed to resolve <%s>\n", host);
103476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			free(*ptr);
103576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			*ptr = NULL;
103676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			return 1;
103776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
1038bebe639808147d587bbe776566d390b9ff98773fJens Axboe
103976867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (*ipv6) {
104076867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			if (hent->h_addrtype != AF_INET6) {
104176867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe				log_info("fio: falling back to IPv4\n");
104276867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe				*ipv6 = 0;
104376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			} else
104476867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe				memcpy(inp6, hent->h_addr_list[0], 16);
104576867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		}
104676867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe		if (!*ipv6) {
104776867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			if (hent->h_addrtype != AF_INET) {
104876867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe				log_err("fio: lookup type mismatch\n");
1049bebe639808147d587bbe776566d390b9ff98773fJens Axboe				free(*ptr);
1050bebe639808147d587bbe776566d390b9ff98773fJens Axboe				*ptr = NULL;
1051bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
1052bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
105376867621c76ce561c315cd9c8d6b055eddd75d88Jens Axboe			memcpy(inp, hent->h_addr_list[0], 4);
1054bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
1055bebe639808147d587bbe776566d390b9ff98773fJens Axboe	}
1056bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1057bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (*port == 0)
1058bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*port = fio_net_port;
1059bebe639808147d587bbe776566d390b9ff98773fJens Axboe
1060bebe639808147d587bbe776566d390b9ff98773fJens Axboe	return 0;
1061bebe639808147d587bbe776566d390b9ff98773fJens Axboe}
1062bebe639808147d587bbe776566d390b9ff98773fJens Axboe
106387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe/*
106487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Server arg should be one of:
106587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
106687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * sock:/path/to/socket
106787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *   ip:1.2.3.4
106887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *      1.2.3.4
106987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
107087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Where sock uses unix domain sockets, and ip binds the server to
107187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * a specific interface. If no arguments are given to the server, it
107287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * uses IP and binds to 0.0.0.0.
107387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
107487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe */
107587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_handle_server_arg(void)
107687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
10776d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	int port = fio_net_port;
1078a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe	int is_sock, ret = 0;
1079bebe639808147d587bbe776566d390b9ff98773fJens Axboe
108087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
108187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
108287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!fio_server_arg)
1083a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe		goto out;
108487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
10854e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock,
1086811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&port, &saddr_in.sin_addr,
1087811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe					&saddr_in6.sin6_addr, &use_ipv6);
10884e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
10894e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	if (!is_sock && bind_sock) {
10904e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		free(bind_sock);
10914e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		bind_sock = NULL;
10924e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	}
10934e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
1094a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboeout:
10956d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	fio_net_port = port;
10966d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	saddr_in.sin_port = htons(port);
1097811826be429fd6fc5154d9b04ced1cd22bd66758Jens Axboe	saddr_in6.sin6_port = htons(port);
10984e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	return ret;
109987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
110087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
110187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_server(void)
110287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
110387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, ret;
110487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
110587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
110687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
110787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_handle_server_arg())
110887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
110987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
111087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = fio_init_server_connection();
111187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
111287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
111381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
111481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	ret = accept_loop(sk);
111587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
111681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	close(sk);
111787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
111887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_server_arg) {
111987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		free(fio_server_arg);
112087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fio_server_arg = NULL;
112187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
1122bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (bind_sock)
1123bebe639808147d587bbe776566d390b9ff98773fJens Axboe		free(bind_sock);
112487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
112581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
112681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
112781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
11287b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboevoid fio_server_got_signal(int signal)
11299abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{
11307b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	if (signal == SIGPIPE)
11317b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		server_fd = -1;
11327b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	else {
11337b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		log_info("\nfio: terminating on signal %d\n", signal);
11347b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		exit_backend = 1;
11357b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	}
11369abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe}
11379abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe
113813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int check_existing_pidfile(const char *pidfile)
113913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe{
114013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	struct stat sb;
114113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	char buf[16];
114213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid_t pid;
114313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	FILE *f;
114413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
114513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (stat(pidfile, &sb))
114613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
114713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
114813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	f = fopen(pidfile, "r");
114913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (!f)
115013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
115113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1152bfc3b17986fb80aeb5a6ea962bb38fc1509d60a8Jens Axboe	if (fread(buf, sb.st_size, 1, f) <= 0) {
115313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		fclose(f);
115413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
115513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
115613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(f);
115713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
115813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid = atoi(buf);
115913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (kill(pid, SIGCONT) < 0)
1160ea5aa1be68de71f9f02eb3d6f4db726adcafb40aJens Axboe		return errno != ESRCH;
116113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
116213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 1;
116313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe}
116413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
116513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int write_pid(pid_t pid, const char *pidfile)
1166402668f3e05259bfc135fc097136428feda01006Jens Axboe{
1167402668f3e05259bfc135fc097136428feda01006Jens Axboe	FILE *fpid;
1168402668f3e05259bfc135fc097136428feda01006Jens Axboe
1169402668f3e05259bfc135fc097136428feda01006Jens Axboe	fpid = fopen(pidfile, "w");
1170402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!fpid) {
1171402668f3e05259bfc135fc097136428feda01006Jens Axboe		log_err("fio: failed opening pid file %s\n", pidfile);
117213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
1173402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1174402668f3e05259bfc135fc097136428feda01006Jens Axboe
1175402668f3e05259bfc135fc097136428feda01006Jens Axboe	fprintf(fpid, "%u\n", (unsigned int) pid);
117613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(fpid);
117713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 0;
1178402668f3e05259bfc135fc097136428feda01006Jens Axboe}
1179402668f3e05259bfc135fc097136428feda01006Jens Axboe
1180402668f3e05259bfc135fc097136428feda01006Jens Axboe/*
1181402668f3e05259bfc135fc097136428feda01006Jens Axboe * If pidfile is specified, background us.
1182402668f3e05259bfc135fc097136428feda01006Jens Axboe */
1183402668f3e05259bfc135fc097136428feda01006Jens Axboeint fio_start_server(char *pidfile)
1184e46d809110bd4ad2980ca64931b683673444454bJens Axboe{
1185e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid_t pid;
1186402668f3e05259bfc135fc097136428feda01006Jens Axboe	int ret;
1187e46d809110bd4ad2980ca64931b683673444454bJens Axboe
118893bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#if defined(WIN32)
1189905c78b90f92bab91555313f7b4bd83d18246139Jens Axboe	WSADATA wsd;
1190905c78b90f92bab91555313f7b4bd83d18246139Jens Axboe	WSAStartup(MAKEWORD(2,2), &wsd);
119193bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran#endif
119293bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran
1193402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!pidfile)
1194e46d809110bd4ad2980ca64931b683673444454bJens Axboe		return fio_server();
1195e46d809110bd4ad2980ca64931b683673444454bJens Axboe
119613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (check_existing_pidfile(pidfile)) {
119713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: pidfile %s exists and server appears alive\n",
119813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe								pidfile);
119913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return -1;
120013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
120113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1202e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid = fork();
1203e46d809110bd4ad2980ca64931b683673444454bJens Axboe	if (pid < 0) {
120413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: failed server fork: %s", strerror(errno));
1205402668f3e05259bfc135fc097136428feda01006Jens Axboe		free(pidfile);
1206c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
1207402668f3e05259bfc135fc097136428feda01006Jens Axboe	} else if (pid) {
120813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		int ret = write_pid(pid, pidfile);
120913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
121013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		exit(ret);
1211402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1212e46d809110bd4ad2980ca64931b683673444454bJens Axboe
1213e46d809110bd4ad2980ca64931b683673444454bJens Axboe	setsid();
121413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
121513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	log_syslog = 1;
1216e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDIN_FILENO);
1217e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDOUT_FILENO);
1218e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDERR_FILENO);
1219e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_out = NULL;
1220e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_err = NULL;
1221402668f3e05259bfc135fc097136428feda01006Jens Axboe
1222402668f3e05259bfc135fc097136428feda01006Jens Axboe	ret = fio_server();
1223402668f3e05259bfc135fc097136428feda01006Jens Axboe
1224402668f3e05259bfc135fc097136428feda01006Jens Axboe	closelog();
1225402668f3e05259bfc135fc097136428feda01006Jens Axboe	unlink(pidfile);
1226402668f3e05259bfc135fc097136428feda01006Jens Axboe	free(pidfile);
1227402668f3e05259bfc135fc097136428feda01006Jens Axboe	return ret;
1228e46d809110bd4ad2980ca64931b683673444454bJens Axboe}
122987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1230bebe639808147d587bbe776566d390b9ff98773fJens Axboevoid fio_server_set_arg(const char *arg)
123187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
123287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_server_arg = strdup(arg);
123387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
1234