server.c revision 7b8216842eb888ff626f616c2770a2548b0b0bf9
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"
23802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe#include "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;
3537db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
3689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic const char *fio_server_ops[FIO_NET_CMD_NR] = {
3789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"",
3889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"QUIT",
3989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"EXIT",
4089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOB",
4189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"JOBLINE",
4289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TEXT",
4389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"TS",
4489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"GS",
4589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"SEND_ETA",
4689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"ETA",
4789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"PROBE",
4889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"START",
4989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	"STOP"
5089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe};
5189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
5289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeconst char *fio_server_op(unsigned int op)
5389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
5489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	static char buf[32];
5589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
5689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (op < FIO_NET_CMD_NR)
5789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_server_ops[op];
5889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
5989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	sprintf(buf, "UNKNOWN/%d", op);
6089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return buf;
6189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
6289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
63132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len)
64132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
65794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU);
66794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = send(sk, p, len, 0);
69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
807b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
817b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
82132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
83132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
84132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
85132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
86132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
87132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 1;
88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len)
91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = recv(sk, p, len, MSG_WAITALL);
94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
1057b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		else
1067b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe			break;
107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
111132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return -1;
113132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
114132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
115132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd)
116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
117fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
118132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
119fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16);
120fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16);
121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
122fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	crc = crc16(cmd, FIO_NET_CMD_CRC_SZ);
123fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != cmd->cmd_crc16) {
124132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on command (got %x, wanted %x)\n",
125fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				cmd->cmd_crc16, crc);
126132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
127132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
128132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->version	= le16_to_cpu(cmd->version);
130132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->opcode	= le16_to_cpu(cmd->opcode);
131132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->flags	= le32_to_cpu(cmd->flags);
132af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	cmd->tag	= le64_to_cpu(cmd->tag);
133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->pdu_len	= le32_to_cpu(cmd->pdu_len);
134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->version) {
136fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	case FIO_SERVER_VER:
137132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
138132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
139132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: bad server cmd version %d\n", cmd->version);
140132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
141132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
143132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd->pdu_len > FIO_SERVER_MAX_PDU) {
144132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: command payload too large: %u\n", cmd->pdu_len);
145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
151a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
152a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Read (and defragment, if necessary) incoming commands
153a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
154e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboestruct fio_net_cmd *fio_net_recv_cmd(int sk)
155132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
156a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct fio_net_cmd cmd, *cmdret = NULL;
157a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	size_t cmd_size = 0, pdu_offset = 0;
158fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
159a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret, first = 1;
160a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	void *pdu = NULL;
161132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
162a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	do {
163a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, &cmd, sizeof(cmd));
164a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
165a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
166132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
167a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* We have a command, verify it and swap if need be */
168a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = verify_convert_cmd(&cmd);
169a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
170a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
171132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
1720b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (first) {
1730b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			/* if this is text, add room for \0 at the end */
1740b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			cmd_size = sizeof(cmd) + cmd.pdu_len + 1;
1750b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			assert(!cmdret);
1760b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		} else
177a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			cmd_size += cmd.pdu_len;
178132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
179a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = realloc(cmdret, cmd_size);
180132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
181a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (first)
182a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			memcpy(cmdret, &cmd, sizeof(cmd));
183a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		else
184a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			assert(cmdret->opcode == cmd.opcode);
185a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
186a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (!cmd.pdu_len)
187a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
188a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
189a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* There's payload, get it */
190a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu = (void *) cmdret->payload + pdu_offset;
191a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		ret = fio_recv_data(sk, pdu, cmd.pdu_len);
192a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (ret)
193a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
194a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
195a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		/* Verify payload crc */
196a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		crc = crc16(pdu, cmd.pdu_len);
197a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		if (crc != cmd.pdu_crc16) {
198a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("fio: server bad crc on payload ");
199a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc);
200a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			ret = 1;
201a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			break;
202a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		}
203a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
204a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		pdu_offset += cmd.pdu_len;
205817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe		if (!first)
206817f06bbc52aea4011ab975d8fa3e3f1065c6065Jens Axboe			cmdret->pdu_len += cmd.pdu_len;
207a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		first = 0;
208a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	} while (cmd.flags & FIO_NET_CMD_F_MORE);
209132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
210a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	if (ret) {
211a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		free(cmdret);
212a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret = NULL;
2130b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	} else if (cmdret) {
2140b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* zero-terminate text input */
2150b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT ||
2160b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		    cmdret->opcode == FIO_NET_CMD_JOB)) {
2170b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			char *buf = (char *) cmdret->payload;
2180b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe
2190b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe			buf[cmdret->pdu_len ] = '\0';
2200b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		}
2210b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		/* frag flag is internal */
222a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		cmdret->flags &= ~FIO_NET_CMD_F_MORE;
2230b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	}
224a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
225a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	return cmdret;
226132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
227132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
228132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd)
229132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
230132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	uint32_t pdu_len;
231132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
232ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	cmd->cmd_crc16 = __cpu_to_le16(crc16(cmd, FIO_NET_CMD_CRC_SZ));
233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
234132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	pdu_len = le32_to_cpu(cmd->pdu_len);
235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (pdu_len)
236ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe		cmd->pdu_crc16 = __cpu_to_le16(crc16(cmd->payload, pdu_len));
237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
239af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
240af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		     uint64_t tag)
241794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{
2427f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	struct fio_net_cmd *cmd = NULL;
2437f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	size_t this_len, cur_len = 0;
244794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	int ret;
245794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
246794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	do {
247794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		this_len = size;
248794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len > FIO_SERVER_MAX_PDU)
249794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe			this_len = FIO_SERVER_MAX_PDU;
250794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
2517f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		if (!cmd || cur_len < sizeof(*cmd) + this_len) {
2527f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			if (cmd)
2537f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe				free(cmd);
2547f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
2557f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cur_len = sizeof(*cmd) + this_len;
2567f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe			cmd = malloc(cur_len);
2577f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		}
258794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
259af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		fio_init_net_cmd(cmd, opcode, buf, this_len, tag);
260794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
261794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len < size)
262ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe			cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE);
263794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
264794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_net_cmd_crc(cmd);
265794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
266794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
267794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		size -= this_len;
268794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		buf += this_len;
269794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	} while (!ret && size);
270794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
2717f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	if (cmd)
2727f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe		free(cmd);
2737f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe
274794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	return ret;
275794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe}
276794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
27789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboestatic int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag)
278132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
279178cde9ff403da53428c5962b8600e47b4580d80Jens Axboe	struct fio_net_cmd cmd;
280132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
281af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_init_net_cmd(&cmd, opcode, NULL, 0, tag);
282132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fio_net_cmd_crc(&cmd);
283132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
284132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return fio_send_data(sk, &cmd, sizeof(cmd));
285132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
286132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
28789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe/*
28889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * If 'list' is non-NULL, then allocate and store the sent command for
28989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe * later verification.
29089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe */
29189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboeint fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag,
29289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			    struct flist_head *list)
29389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe{
29489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	struct fio_net_int_cmd *cmd;
29589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	int ret;
29689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
29789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (!list)
29889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return fio_net_send_simple_stack_cmd(sk, opcode, tag);
29989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
30089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	cmd = malloc(sizeof(*cmd));
30189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
30289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_init_net_cmd(&cmd->cmd, opcode, NULL, 0, (uint64_t) cmd);
30389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_net_cmd_crc(&cmd->cmd);
30489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
30589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	INIT_FLIST_HEAD(&cmd->list);
30689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	gettimeofday(&cmd->tv, NULL);
30789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	cmd->saved_tag = tag;
30889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
30989c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	ret = fio_send_data(sk, &cmd->cmd, sizeof(cmd->cmd));
31089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (ret) {
31189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		free(cmd);
31289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		return ret;
31389c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	}
31489c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
31589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	flist_add_tail(&cmd->list, list);
31689c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return 0;
31789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe}
31889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
3199abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboestatic int fio_server_send_quit_cmd(void)
320437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{
32146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: sending quit\n");
32289c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0, NULL);
323437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe}
324437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe
3250b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboestatic int handle_job_cmd(struct fio_net_cmd *cmd)
326132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
3270b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe	char *buf = (char *) cmd->payload;
328a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int ret;
329132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
330e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	if (parse_jobs_ini(buf, 1, 0)) {
331e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe		fio_server_send_quit_cmd();
33281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
333e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
33481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
33589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0, NULL);
33681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
33781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	ret = exec_run();
3389abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe	fio_server_send_quit_cmd();
33981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	reset_fio_state();
34081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
34181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
34281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
34381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboestatic int handle_jobline_cmd(struct fio_net_cmd *cmd)
34481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
345fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	void *pdu = cmd->payload;
346fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_single_line_pdu *cslp;
347fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	struct cmd_line_pdu *clp;
348fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	unsigned long offset;
349fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	char **argv;
35081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	int ret, i;
35181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
352fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp = pdu;
353fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	clp->lines = le16_to_cpu(clp->lines);
354fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	argv = malloc(clp->lines * sizeof(char *));
355fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	offset = sizeof(*clp);
35681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
357fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	dprint(FD_NET, "server: %d command line args\n", clp->lines);
35839e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe
359fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	for (i = 0; i < clp->lines; i++) {
360fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		cslp = pdu + offset;
361fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		argv[i] = (char *) cslp->text;
362fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
363fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		offset += sizeof(*cslp) + le16_to_cpu(cslp->len);
36439e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe		dprint(FD_NET, "server: %d: %s\n", i, argv[i]);
36539e8e01691c9d5765795417ee49a40d5ae08cb8bJens Axboe	}
36681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
367fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	if (parse_cmd_line(clp->lines, argv)) {
368e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe		fio_server_send_quit_cmd();
369fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe		free(argv);
37081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
371e6d1c6687bf7dcd738657bcac70982c1e790329eJens Axboe	}
37281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
373fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe	free(argv);
374fa2ea806de0d6410320abd97599bc52f5a3e72ccJens Axboe
37589c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0, NULL);
37681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
377794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	ret = exec_run();
3789abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe	fio_server_send_quit_cmd();
379794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	reset_fio_state();
380132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
381132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
382132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
383c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboestatic int handle_probe_cmd(struct fio_net_cmd *cmd)
384c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe{
385c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	struct cmd_probe_pdu probe;
386c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
38789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: sending probe reply\n");
38889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe
389c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	memset(&probe, 0, sizeof(probe));
390c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	gethostname((char *) probe.hostname, sizeof(probe.hostname));
3916eb2479194603184f393057ea10326643edc7169Jens Axboe#ifdef FIO_BIG_ENDIAN
3926eb2479194603184f393057ea10326643edc7169Jens Axboe	probe.bigendian = 1;
3936eb2479194603184f393057ea10326643edc7169Jens Axboe#endif
39481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_major = FIO_MAJOR;
39581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_minor = FIO_MINOR;
39681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	probe.fio_patch = FIO_PATCH;
397c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
398cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.os	= FIO_OS;
399cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe	probe.arch	= FIO_ARCH;
400cca84643cc10cd72b0b453ff92ccb8643ba51493Jens Axboe
40189c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), cmd->tag);
402af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe}
403af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
404af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboestatic int handle_send_eta_cmd(struct fio_net_cmd *cmd)
405af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe{
406af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	struct jobs_eta *je;
407af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	size_t size;
408af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	int i;
409af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
410af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	size = sizeof(*je) + thread_number * sizeof(char);
4117f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	je = malloc(size);
4127f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	memset(je, 0, size);
413af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
414af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	if (!calc_thread_status(je, 1)) {
415af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		free(je);
416af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return 0;
417af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
418af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
419af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	dprint(FD_NET, "server sending status\n");
420af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
421af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_running		= cpu_to_le32(je->nr_running);
422af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_ramp		= cpu_to_le32(je->nr_ramp);
423af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->nr_pending		= cpu_to_le32(je->nr_pending);
424af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->files_open		= cpu_to_le32(je->files_open);
425af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->m_rate		= cpu_to_le32(je->m_rate);
426af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->t_rate		= cpu_to_le32(je->t_rate);
427af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->m_iops		= cpu_to_le32(je->m_iops);
428af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->t_iops		= cpu_to_le32(je->t_iops);
429af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
430af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	for (i = 0; i < 2; i++) {
431af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->rate[i]	= cpu_to_le32(je->rate[i]);
432af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		je->iops[i]	= cpu_to_le32(je->iops[i]);
433af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	}
434af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
435af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->elapsed_sec		= cpu_to_le32(je->nr_running);
436af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	je->eta_sec		= cpu_to_le64(je->eta_sec);
437af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe
4387f868316a7244cad23735e44e6ef66e5779c9660Jens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, cmd->tag);
439af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	free(je);
440af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	return 0;
441c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe}
442c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe
443132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd)
444132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
445132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret;
446132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
44789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%lx\n",
44889c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe			fio_server_op(cmd->opcode), cmd->pdu_len, cmd->tag);
44946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
450132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->opcode) {
451132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_QUIT:
452cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe		fio_terminate_threads(TERMINATE_ALL);
453c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
454d7959186aa6f8ca6ee5bdcd773d77280fc806617Jens Axboe	case FIO_NET_CMD_EXIT:
455132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		exit_backend = 1;
456c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
457132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_JOB:
4580b8f30a5691b9e600a06ded035996e79c2100d77Jens Axboe		ret = handle_job_cmd(cmd);
459132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
46081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	case FIO_NET_CMD_JOBLINE:
46181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		ret = handle_jobline_cmd(cmd);
46281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		break;
463c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe	case FIO_NET_CMD_PROBE:
464c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		ret = handle_probe_cmd(cmd);
465c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		break;
466af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	case FIO_NET_CMD_SEND_ETA:
467af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		ret = handle_send_eta_cmd(cmd);
468af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		break;
469132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
47089c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe		log_err("fio: unknown opcode: %s\n",fio_server_op(cmd->opcode));
471132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = 1;
472132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
473132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
474132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
475132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
476132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
47770e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboestatic int handle_connection(int sk, int block)
478132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
479132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd *cmd = NULL;
480132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
481132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
482132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* read forever */
483132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	while (!exit_backend) {
484e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		struct pollfd pfd = {
485e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.fd	= sk,
486e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			.events	= POLLIN,
487e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		};
488e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
489e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		ret = 0;
490e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		do {
491e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			ret = poll(&pfd, 1, 100);
492e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (ret < 0) {
493e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				if (errno == EINTR)
494e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe					break;
495e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				log_err("fio: poll: %s\n", strerror(errno));
496e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
49719c65179fad3e0a32a450401ba7d312169627fddJens Axboe			} else if (!ret) {
49819c65179fad3e0a32a450401ba7d312169627fddJens Axboe				if (!block)
49919c65179fad3e0a32a450401ba7d312169627fddJens Axboe					return 0;
500e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				continue;
50119c65179fad3e0a32a450401ba7d312169627fddJens Axboe			}
502e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
503e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & POLLIN)
504e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
505e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			if (pfd.revents & (POLLERR|POLLHUP)) {
506e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				ret = 1;
507e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe				break;
508e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			}
50919c65179fad3e0a32a450401ba7d312169627fddJens Axboe		} while (!exit_backend);
510e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
511e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		if (ret < 0)
512e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe			break;
513e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe
514e951bdc47d094d43d6f41de95c6af191b8346459Jens Axboe		cmd = fio_net_recv_cmd(sk);
515132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (!cmd) {
516c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe			ret = -1;
517132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
518132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		}
519132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
520132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = handle_command(cmd);
521132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
522132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
523132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
524132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
525c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe		cmd = NULL;
526132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
527132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
528132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd)
529132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
530132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
531132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
532132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
533132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
534cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboevoid fio_server_idle_loop(void)
535cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe{
536cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe	if (server_fd != -1)
53770e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe		handle_connection(server_fd, 0);
538cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe}
539cc0df00ad5076d4adbc439899f24d9b0db26075dJens Axboe
54050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
54150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
542bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	struct sockaddr_in addr;
5435ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe	fio_socklen_t len = sizeof(addr);
544009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
545132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret, sk, flags, exitval = 0;
54650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
54760efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server enter accept loop\n");
54860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
549009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags = fcntl(listen_sk, F_GETFL);
550009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags |= O_NONBLOCK;
551009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	fcntl(listen_sk, F_SETFL, flags);
55250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain:
553009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.fd = listen_sk;
554009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.events = POLLIN;
555009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	do {
556009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		ret = poll(&pfd, 1, 100);
557009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (ret < 0) {
558009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			if (errno == EINTR)
559009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe				break;
560fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe			log_err("fio: poll: %s\n", strerror(errno));
561009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			goto out;
562009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		} else if (!ret)
563009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			continue;
564009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
565009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (pfd.revents & POLLIN)
566009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			break;
567009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	} while (!exit_backend);
568009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
569009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (exit_backend)
570009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		goto out;
571009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
5726b976bfcda733ad9a05ce28526f670a51096a771Jens Axboe	sk = accept(listen_sk, (struct sockaddr *) &addr, &len);
57350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (sk < 0) {
574690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: accept: %s\n", strerror(errno));
57550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
57650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
57750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
578bb447a27c8cbab03a54fa6ceec1a244aabec57d2Jens Axboe	dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr));
57946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
58037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = sk;
58137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
58270e0c3166fdb8048b1e7f84be2371fc60af04f87Jens Axboe	exitval = handle_connection(sk, 1);
58350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
58437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = -1;
58550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	close(sk);
5865c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
587009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (!exit_backend)
5885c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe		goto again;
5895c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
590009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout:
591132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return exitval;
59250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
59350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
59413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboeint fio_server_text_output(const char *buf, size_t len)
59537db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
596337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe	if (server_fd != -1)
597af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe		return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len, 0);
598337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe
59913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return log_local_buf(buf, len);
600142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe}
601142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
602a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_io_stat(struct io_stat *dst, struct io_stat *src)
603a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
604a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->max_val	= cpu_to_le64(src->max_val);
605a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->min_val	= cpu_to_le64(src->min_val);
606a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->samples	= cpu_to_le64(src->samples);
607802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
608802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	/*
609802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 * Encode to IEEE 754 for network transfer
610802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	 */
611802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->mean.u.i	= __cpu_to_le64(fio_double_to_uint64(src->mean.u.f));
612802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	dst->S.u.i	= __cpu_to_le64(fio_double_to_uint64(src->S.u.f));
613a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
614a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
615a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboestatic void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
616a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
617a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i;
618a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
619a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
620a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_run[i]		= cpu_to_le64(src->max_run[i]);
621a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_run[i]		= cpu_to_le64(src->min_run[i]);
622a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->max_bw[i]		= cpu_to_le64(src->max_bw[i]);
623a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->min_bw[i]		= cpu_to_le64(src->min_bw[i]);
624a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->io_kb[i]		= cpu_to_le64(src->io_kb[i]);
625a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		dst->agg[i]		= cpu_to_le64(src->agg[i]);
626a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
627a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
628a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->kb_base	= cpu_to_le32(src->kb_base);
629a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	dst->groupid	= cpu_to_le32(src->groupid);
630a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
631a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
632a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe/*
633a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * Send a CMD_TS, which packs struct thread_stat and group_run_stats
634a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe * into a single payload.
635a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe */
636a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
637a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
638a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct cmd_ts_pdu p;
639a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	int i, j;
640a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
64160efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending end stats\n");
64260efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
643317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe	memset(&p, 0, sizeof(p));
644317b3c8b1bd5cdb1f2bd02c94d536fa853321bc6Jens Axboe
645a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.name, ts->name);
646a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.verror, ts->verror);
647a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	strcpy(p.ts.description, ts->description);
648a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
649ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.error	= cpu_to_le32(ts->error);
650a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.groupid	= cpu_to_le32(ts->groupid);
651ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.pid	= cpu_to_le32(ts->pid);
652a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.members	= cpu_to_le32(ts->members);
653a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
654a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
655a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]);
656a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]);
657a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]);
658a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]);
659a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
660a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
661a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.usr_time		= cpu_to_le64(ts->usr_time);
662a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.sys_time		= cpu_to_le64(ts->sys_time);
663a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.ctx		= cpu_to_le64(ts->ctx);
664a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.minf		= cpu_to_le64(ts->minf);
665a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.majf		= cpu_to_le64(ts->majf);
666a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.clat_percentiles	= cpu_to_le64(ts->clat_percentiles);
667802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
668802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
669802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe		fio_fp64_t *fp = &p.ts.percentile_list[i];
670802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe
671802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe		fp->u.i = __cpu_to_le64(fio_double_to_uint64(fp->u.f));
672802ad4a83e92a30b5fdccf117d59fbb69068c054Jens Axboe	}
673a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
674a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
675a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_map[i]	= cpu_to_le32(ts->io_u_map[i]);
676a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_submit[i]	= cpu_to_le32(ts->io_u_submit[i]);
677a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_complete[i]	= cpu_to_le32(ts->io_u_complete[i]);
678a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
679a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
680a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
681a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_u[i]	= cpu_to_le32(ts->io_u_lat_u[i]);
682a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_u_lat_m[i]	= cpu_to_le32(ts->io_u_lat_m[i]);
683a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
684a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
685a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++)
686a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
687a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe			p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]);
688a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
689a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 3; i++) {
690a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.total_io_u[i]	= cpu_to_le64(ts->total_io_u[i]);
69193eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe		p.ts.short_io_u[i]	= cpu_to_le64(ts->short_io_u[i]);
692a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
693a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
69493eee04aef9ed39070ce2e69bd1f661a95b1d50aJens Axboe	p.ts.total_submit	= cpu_to_le64(ts->total_submit);
695a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_complete	= cpu_to_le64(ts->total_complete);
696a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
697a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	for (i = 0; i < 2; i++) {
698a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.io_bytes[i]	= cpu_to_le64(ts->io_bytes[i]);
699a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe		p.ts.runtime[i]		= cpu_to_le64(ts->runtime[i]);
700a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	}
701a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
702a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_run_time	= cpu_to_le64(ts->total_run_time);
703a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.continue_on_error	= cpu_to_le16(ts->continue_on_error);
704a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	p.ts.total_err_count	= cpu_to_le64(ts->total_err_count);
705ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.first_error	= cpu_to_le32(ts->first_error);
706ddcc0b69aa4ed04c8681f447a1a6274bb8837a14Jens Axboe	p.ts.kb_base		= cpu_to_le32(ts->kb_base);
707a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
708a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&p.rs, rs);
709a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
710af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0);
711a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe}
712a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
713a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboevoid fio_server_send_gs(struct group_run_stats *rs)
714a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe{
715a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	struct group_run_stats gs;
716a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe
71760efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server sending group run stats\n");
71860efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
719a64e88dad0c0e4a510ae8ab54cde1a20b99c59d1Jens Axboe	convert_gs(&gs, rs);
720af9c9fb34e420fc4d9cf317aa0f3cf6795a5a07fJens Axboe	fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0);
721cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe}
722cf451d1ede3bbbd2fed3619eb43def054d5b5a5aJens Axboe
723142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...)
724142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{
725142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	char buffer[1024];
726142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_list args;
72782fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	size_t len;
728142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
72960efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe	dprint(FD_NET, "server log\n");
73060efd14e3b5b5a2adb9f7c9ecfb9bfba38f76ce9Jens Axboe
731142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_start(args, format);
73282fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	len = vsnprintf(buffer, sizeof(buffer), format, args);
733142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_end(args);
734142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
73582fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	return fio_server_text_output(buffer, len);
73637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe}
737e46d809110bd4ad2980ca64931b683673444454bJens Axboe
73887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_ip(void)
73981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe{
74087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, opt;
74181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
74281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	sk = socket(AF_INET, SOCK_STREAM, 0);
74381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (sk < 0) {
74481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
74581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
74681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
74781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
74881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	opt = 1;
74981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
75081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
751b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
75281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
75381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
75481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#ifdef SO_REUSEPORT
7556eb2479194603184f393057ea10326643edc7169Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
75681179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
757b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
75881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
75981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
76081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe#endif
76181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
76281179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	saddr_in.sin_family = AF_INET;
76381179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
76481179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) {
76581179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
766b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
76781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
76881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
76981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
77087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
77187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
77287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
77387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_sock(void)
77487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
77587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	struct sockaddr_un addr;
77687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_socklen_t len;
77787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode_t mode;
77887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
77987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
78087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = socket(AF_UNIX, SOCK_STREAM, 0);
78187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0) {
78287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: socket: %s\n", strerror(errno));
78387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
78487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
78587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
78687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	mode = umask(000);
78787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
78887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	memset(&addr, 0, sizeof(addr));
78987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	addr.sun_family = AF_UNIX;
79087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	strcpy(addr.sun_path, bind_sock);
79187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	unlink(bind_sock);
79287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
79387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	len = sizeof(addr.sun_family) + strlen(bind_sock) + 1;
79487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
79587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (bind(sk, (struct sockaddr *) &addr, len) < 0) {
79687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		log_err("fio: bind: %s\n", strerror(errno));
797b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(sk);
79887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
79987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
80087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
80187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	umask(mode);
80287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
80387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
80487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
80587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_init_server_connection(void)
80687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
807bebe639808147d587bbe776566d390b9ff98773fJens Axboe	char bind_str[128];
80887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk;
80987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
81087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
81187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
81287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!bind_sock)
81387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_ip();
81487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	else
81587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		sk = fio_init_server_sock();
81687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
81787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
81887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return sk;
81987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
820bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!bind_sock)
821bebe639808147d587bbe776566d390b9ff98773fJens Axboe		sprintf(bind_str, "%s:%u", inet_ntoa(saddr_in.sin_addr), fio_net_port);
822bebe639808147d587bbe776566d390b9ff98773fJens Axboe	else
823bebe639808147d587bbe776566d390b9ff98773fJens Axboe		strcpy(bind_str, bind_sock);
824bebe639808147d587bbe776566d390b9ff98773fJens Axboe
825bebe639808147d587bbe776566d390b9ff98773fJens Axboe	log_info("fio: server listening on %s\n", bind_str);
826bebe639808147d587bbe776566d390b9ff98773fJens Axboe
82789c1707cb512e562b55b56c268f7fad612be6f04Jens Axboe	if (listen(sk, 0) < 0) {
82881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
82981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe		return -1;
83081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	}
83181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
83287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	return sk;
83387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
83487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
835bebe639808147d587bbe776566d390b9ff98773fJens Axboeint fio_server_parse_string(const char *str, char **ptr, int *is_sock,
836bebe639808147d587bbe776566d390b9ff98773fJens Axboe			    int *port, struct in_addr *inp)
837bebe639808147d587bbe776566d390b9ff98773fJens Axboe{
838bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*ptr = NULL;
839bebe639808147d587bbe776566d390b9ff98773fJens Axboe	*is_sock = 0;
8406d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	*port = fio_net_port;
841bebe639808147d587bbe776566d390b9ff98773fJens Axboe
842bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (!strncmp(str, "sock:", 5)) {
843bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*ptr = strdup(str + 5);
844bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*is_sock = 1;
845bebe639808147d587bbe776566d390b9ff98773fJens Axboe	} else {
846bebe639808147d587bbe776566d390b9ff98773fJens Axboe		const char *host = str;
847bebe639808147d587bbe776566d390b9ff98773fJens Axboe		char *portp;
848bebe639808147d587bbe776566d390b9ff98773fJens Axboe		int lport = 0;
849bebe639808147d587bbe776566d390b9ff98773fJens Axboe
850bebe639808147d587bbe776566d390b9ff98773fJens Axboe		/*
851bebe639808147d587bbe776566d390b9ff98773fJens Axboe		 * Is it ip:<ip or host>:port
852bebe639808147d587bbe776566d390b9ff98773fJens Axboe		 */
853bebe639808147d587bbe776566d390b9ff98773fJens Axboe		if (!strncmp(host, "ip:", 3))
854bebe639808147d587bbe776566d390b9ff98773fJens Axboe			host += 3;
855bebe639808147d587bbe776566d390b9ff98773fJens Axboe		else if (host[0] == ':') {
856bebe639808147d587bbe776566d390b9ff98773fJens Axboe			/* String is :port */
857bebe639808147d587bbe776566d390b9ff98773fJens Axboe			host++;
858bebe639808147d587bbe776566d390b9ff98773fJens Axboe			lport = atoi(host);
859bebe639808147d587bbe776566d390b9ff98773fJens Axboe			if (!lport || lport > 65535) {
860bebe639808147d587bbe776566d390b9ff98773fJens Axboe				log_err("fio: bad server port %u\n", port);
861bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
862bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
863bebe639808147d587bbe776566d390b9ff98773fJens Axboe			/* no hostname given, we are done */
864bebe639808147d587bbe776566d390b9ff98773fJens Axboe			*port = lport;
865bebe639808147d587bbe776566d390b9ff98773fJens Axboe			return 0;
866bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
867bebe639808147d587bbe776566d390b9ff98773fJens Axboe
868bebe639808147d587bbe776566d390b9ff98773fJens Axboe		/*
869bebe639808147d587bbe776566d390b9ff98773fJens Axboe		 * If no port seen yet, check if there's a last ':' at the end
870bebe639808147d587bbe776566d390b9ff98773fJens Axboe		 */
871bebe639808147d587bbe776566d390b9ff98773fJens Axboe		if (!lport) {
872bebe639808147d587bbe776566d390b9ff98773fJens Axboe			portp = strchr(host, ':');
873bebe639808147d587bbe776566d390b9ff98773fJens Axboe			if (portp) {
874bebe639808147d587bbe776566d390b9ff98773fJens Axboe				*portp = '\0';
875bebe639808147d587bbe776566d390b9ff98773fJens Axboe				portp++;
876bebe639808147d587bbe776566d390b9ff98773fJens Axboe				lport = atoi(portp);
877bebe639808147d587bbe776566d390b9ff98773fJens Axboe				if (!lport || lport > 65535) {
878bebe639808147d587bbe776566d390b9ff98773fJens Axboe					log_err("fio: bad server port %u\n", port);
879bebe639808147d587bbe776566d390b9ff98773fJens Axboe					return 1;
880bebe639808147d587bbe776566d390b9ff98773fJens Axboe				}
881bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
882bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
883bebe639808147d587bbe776566d390b9ff98773fJens Axboe
884bebe639808147d587bbe776566d390b9ff98773fJens Axboe		if (lport)
885bebe639808147d587bbe776566d390b9ff98773fJens Axboe			*port = lport;
886bebe639808147d587bbe776566d390b9ff98773fJens Axboe
887bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*ptr = strdup(host);
888bebe639808147d587bbe776566d390b9ff98773fJens Axboe
889bebe639808147d587bbe776566d390b9ff98773fJens Axboe		if (inet_aton(host, inp) != 1) {
890bebe639808147d587bbe776566d390b9ff98773fJens Axboe			struct hostent *hent;
891bebe639808147d587bbe776566d390b9ff98773fJens Axboe
892bebe639808147d587bbe776566d390b9ff98773fJens Axboe			hent = gethostbyname(host);
893bebe639808147d587bbe776566d390b9ff98773fJens Axboe			if (!hent) {
894bebe639808147d587bbe776566d390b9ff98773fJens Axboe				free(*ptr);
895bebe639808147d587bbe776566d390b9ff98773fJens Axboe				*ptr = NULL;
896bebe639808147d587bbe776566d390b9ff98773fJens Axboe				return 1;
897bebe639808147d587bbe776566d390b9ff98773fJens Axboe			}
898bebe639808147d587bbe776566d390b9ff98773fJens Axboe
899bebe639808147d587bbe776566d390b9ff98773fJens Axboe			memcpy(inp, hent->h_addr, 4);
900bebe639808147d587bbe776566d390b9ff98773fJens Axboe		}
901bebe639808147d587bbe776566d390b9ff98773fJens Axboe	}
902bebe639808147d587bbe776566d390b9ff98773fJens Axboe
903bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (*port == 0)
904bebe639808147d587bbe776566d390b9ff98773fJens Axboe		*port = fio_net_port;
905bebe639808147d587bbe776566d390b9ff98773fJens Axboe
906bebe639808147d587bbe776566d390b9ff98773fJens Axboe	return 0;
907bebe639808147d587bbe776566d390b9ff98773fJens Axboe}
908bebe639808147d587bbe776566d390b9ff98773fJens Axboe
90987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe/*
91087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Server arg should be one of:
91187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
91287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * sock:/path/to/socket
91387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *   ip:1.2.3.4
91487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *      1.2.3.4
91587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
91687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * Where sock uses unix domain sockets, and ip binds the server to
91787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * a specific interface. If no arguments are given to the server, it
91887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe * uses IP and binds to 0.0.0.0.
91987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe *
92087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe */
92187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_handle_server_arg(void)
92287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
9236d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	int port = fio_net_port;
924a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe	int is_sock, ret = 0;
925bebe639808147d587bbe776566d390b9ff98773fJens Axboe
92687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
92787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
92887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (!fio_server_arg)
929a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboe		goto out;
93087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
9314e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock,
9326d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe					&port, &saddr_in.sin_addr);
9334e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
9344e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	if (!is_sock && bind_sock) {
9354e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		free(bind_sock);
9364e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe		bind_sock = NULL;
9374e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	}
9384e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe
939a7de0a1163e63cb6fa0a6bad773c415d06d154acJens Axboeout:
9406d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	fio_net_port = port;
9416d2cf39497670a0246c9b7bb1cc6ef77629e08f7Jens Axboe	saddr_in.sin_port = htons(port);
9424e5b8fb8e2d989789e18b31f9aed969c8fa43cdbJens Axboe	return ret;
94387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
94487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
94587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboestatic int fio_server(void)
94687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
94787aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	int sk, ret;
94887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
94987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	dprint(FD_NET, "starting server\n");
95087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
95187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_handle_server_arg())
95287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
95387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
95487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	sk = fio_init_server_connection();
95587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (sk < 0)
95687aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		return -1;
95781179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
95881179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	ret = accept_loop(sk);
95987aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
96081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	close(sk);
96187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
96287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	if (fio_server_arg) {
96387aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		free(fio_server_arg);
96487aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe		fio_server_arg = NULL;
96587aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	}
966bebe639808147d587bbe776566d390b9ff98773fJens Axboe	if (bind_sock)
967bebe639808147d587bbe776566d390b9ff98773fJens Axboe		free(bind_sock);
96887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
96981179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe	return ret;
97081179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe}
97181179eec4a84ff25c190a8a6a685b0b3b4dd2a37Jens Axboe
9727b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboevoid fio_server_got_signal(int signal)
9739abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe{
9747b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	if (signal == SIGPIPE)
9757b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		server_fd = -1;
9767b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	else {
9777b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		log_info("\nfio: terminating on signal %d\n", signal);
9787b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe		exit_backend = 1;
9797b8216842eb888ff626f616c2770a2548b0b0bf9Jens Axboe	}
9809abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe}
9819abea48bee7340fdf0aee00fa734a3071d47ed86Jens Axboe
98213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int check_existing_pidfile(const char *pidfile)
98313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe{
98413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	struct stat sb;
98513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	char buf[16];
98613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid_t pid;
98713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	FILE *f;
98813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
98913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (stat(pidfile, &sb))
99013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
99113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
99213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	f = fopen(pidfile, "r");
99313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (!f)
99413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 0;
99513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
996bfc3b17986fb80aeb5a6ea962bb38fc1509d60a8Jens Axboe	if (fread(buf, sb.st_size, 1, f) <= 0) {
99713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		fclose(f);
99813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
99913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
100013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(f);
100113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
100213755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	pid = atoi(buf);
100313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (kill(pid, SIGCONT) < 0)
1004ea5aa1be68de71f9f02eb3d6f4db726adcafb40aJens Axboe		return errno != ESRCH;
100513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
100613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 1;
100713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe}
100813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
100913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboestatic int write_pid(pid_t pid, const char *pidfile)
1010402668f3e05259bfc135fc097136428feda01006Jens Axboe{
1011402668f3e05259bfc135fc097136428feda01006Jens Axboe	FILE *fpid;
1012402668f3e05259bfc135fc097136428feda01006Jens Axboe
1013402668f3e05259bfc135fc097136428feda01006Jens Axboe	fpid = fopen(pidfile, "w");
1014402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!fpid) {
1015402668f3e05259bfc135fc097136428feda01006Jens Axboe		log_err("fio: failed opening pid file %s\n", pidfile);
101613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return 1;
1017402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1018402668f3e05259bfc135fc097136428feda01006Jens Axboe
1019402668f3e05259bfc135fc097136428feda01006Jens Axboe	fprintf(fpid, "%u\n", (unsigned int) pid);
102013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	fclose(fpid);
102113755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	return 0;
1022402668f3e05259bfc135fc097136428feda01006Jens Axboe}
1023402668f3e05259bfc135fc097136428feda01006Jens Axboe
1024402668f3e05259bfc135fc097136428feda01006Jens Axboe/*
1025402668f3e05259bfc135fc097136428feda01006Jens Axboe * If pidfile is specified, background us.
1026402668f3e05259bfc135fc097136428feda01006Jens Axboe */
1027402668f3e05259bfc135fc097136428feda01006Jens Axboeint fio_start_server(char *pidfile)
1028e46d809110bd4ad2980ca64931b683673444454bJens Axboe{
1029e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid_t pid;
1030402668f3e05259bfc135fc097136428feda01006Jens Axboe	int ret;
1031e46d809110bd4ad2980ca64931b683673444454bJens Axboe
1032402668f3e05259bfc135fc097136428feda01006Jens Axboe	if (!pidfile)
1033e46d809110bd4ad2980ca64931b683673444454bJens Axboe		return fio_server();
1034e46d809110bd4ad2980ca64931b683673444454bJens Axboe
103513755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	if (check_existing_pidfile(pidfile)) {
103613755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: pidfile %s exists and server appears alive\n",
103713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe								pidfile);
103813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		return -1;
103913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	}
104013755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
1041e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid = fork();
1042e46d809110bd4ad2980ca64931b683673444454bJens Axboe	if (pid < 0) {
104313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		log_err("fio: failed server fork: %s", strerror(errno));
1044402668f3e05259bfc135fc097136428feda01006Jens Axboe		free(pidfile);
1045c28e8e8c68f7e908085f4585299e6e4d74d01837Jens Axboe		return -1;
1046402668f3e05259bfc135fc097136428feda01006Jens Axboe	} else if (pid) {
104713755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		int ret = write_pid(pid, pidfile);
104813755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe
104913755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe		exit(ret);
1050402668f3e05259bfc135fc097136428feda01006Jens Axboe	}
1051e46d809110bd4ad2980ca64931b683673444454bJens Axboe
1052e46d809110bd4ad2980ca64931b683673444454bJens Axboe	setsid();
105313755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
105413755d946d034eb7395a818db7ace2c9cb60b4cbJens Axboe	log_syslog = 1;
1055e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDIN_FILENO);
1056e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDOUT_FILENO);
1057e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDERR_FILENO);
1058e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_out = NULL;
1059e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_err = NULL;
1060402668f3e05259bfc135fc097136428feda01006Jens Axboe
1061402668f3e05259bfc135fc097136428feda01006Jens Axboe	ret = fio_server();
1062402668f3e05259bfc135fc097136428feda01006Jens Axboe
1063402668f3e05259bfc135fc097136428feda01006Jens Axboe	closelog();
1064402668f3e05259bfc135fc097136428feda01006Jens Axboe	unlink(pidfile);
1065402668f3e05259bfc135fc097136428feda01006Jens Axboe	free(pidfile);
1066402668f3e05259bfc135fc097136428feda01006Jens Axboe	return ret;
1067e46d809110bd4ad2980ca64931b683673444454bJens Axboe}
106887aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe
1069bebe639808147d587bbe776566d390b9ff98773fJens Axboevoid fio_server_set_arg(const char *arg)
107087aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe{
107187aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe	fio_server_arg = strdup(arg);
107287aa8f1901e26bc377f3035a485d35c417d0255aJens Axboe}
1073