server.c revision c77a99e74e88a8ea1a8c0904aef3f7c81e07273f
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>
1150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/mman.h>
1250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netinet/in.h>
1350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <arpa/inet.h>
1450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netdb.h>
1550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
1650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h"
17132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h"
18fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h"
1950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
20132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765;
2150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
22009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0;
23009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
24132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic char *job_buf;
25132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic unsigned int job_cur_len;
26132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic unsigned int job_max_len;
27132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
2846c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1;
2937db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
30132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len)
31132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
32794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU);
33794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
34132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
35132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = send(sk, p, len, 0);
36132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
37132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
38132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
39132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
40132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
41132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
42132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
43132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
44132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
45132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
46132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
47132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
48132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
49132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
50132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
51132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
52132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 1;
53132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
54132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
55132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len)
56132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
57132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
58132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = recv(sk, p, len, MSG_WAITALL);
59132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
60132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
61132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
62132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
63132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
64132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
65132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
66132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return -1;
76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd)
79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
80fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
81132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
82fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16);
83fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16);
84132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
85fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	crc = crc16(cmd, FIO_NET_CMD_CRC_SZ);
86fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != cmd->cmd_crc16) {
87132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on command (got %x, wanted %x)\n",
88fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				cmd->cmd_crc16, crc);
89132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->version	= le16_to_cpu(cmd->version);
93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->opcode	= le16_to_cpu(cmd->opcode);
94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->flags	= le32_to_cpu(cmd->flags);
95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->serial	= le64_to_cpu(cmd->serial);
96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->pdu_len	= le32_to_cpu(cmd->pdu_len);
97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->version) {
99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_SERVER_VER1:
100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: bad server cmd version %d\n", cmd->version);
103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd->pdu_len > FIO_SERVER_MAX_PDU) {
107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: command payload too large: %u\n", cmd->pdu_len);
108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
111132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
113132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
11437db14feece08eb6e43de87c404180650ed5aa6fJens Axboestruct fio_net_cmd *fio_net_cmd_read(int sk)
115132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd cmd, *ret = NULL;
117fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
118132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fio_recv_data(sk, &cmd, sizeof(cmd)))
120132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return NULL;
121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
122132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* We have a command, verify it and swap if need be */
123132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (verify_convert_cmd(&cmd))
124132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return NULL;
125132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
126132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* Command checks out, alloc real command and fill in */
127132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	ret = malloc(sizeof(cmd) + cmd.pdu_len);
128132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	memcpy(ret, &cmd, sizeof(cmd));
129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
130132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!ret->pdu_len)
131132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return ret;
132132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* There's payload, get it */
134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fio_recv_data(sk, (void *) ret + sizeof(*ret), ret->pdu_len)) {
135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(ret);
136132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return NULL;
137132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
138132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
139132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* Verify payload crc */
140fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	crc = crc16(ret->payload, ret->pdu_len);
141fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != ret->pdu_crc16) {
142132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on payload (got %x, wanted %x)\n",
143fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				ret->pdu_crc16, crc);
144132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(ret);
145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return NULL;
146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd)
152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	uint32_t pdu_len;
154132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
155fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = cpu_to_le16(crc16(cmd, FIO_NET_CMD_CRC_SZ));
156132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
157132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	pdu_len = le32_to_cpu(cmd->pdu_len);
158132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (pdu_len)
159fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe		cmd->pdu_crc16 = cpu_to_le16(crc16(cmd->payload, pdu_len));
160132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
161132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
162794d69ca97738736844ee6a6da37f1ef686578cbJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const char *buf, off_t size)
163794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{
164794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	struct fio_net_cmd *cmd;
165794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	size_t this_len;
166794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	int ret;
167794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
168794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	do {
169794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		this_len = size;
170794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len > FIO_SERVER_MAX_PDU)
171794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe			this_len = FIO_SERVER_MAX_PDU;
172794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
173794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		cmd = malloc(sizeof(*cmd) + this_len);
174794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
175794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_init_net_cmd(cmd, opcode, buf, this_len);
176794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
177794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len < size)
178794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe			cmd->flags |= FIO_NET_CMD_F_MORE;
179794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
180794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_net_cmd_crc(cmd);
181794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
182794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
183794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		free(cmd);
184794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		size -= this_len;
185794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		buf += this_len;
186794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	} while (!ret && size);
187794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
188794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	return ret;
189794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe}
190794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
191132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int send_simple_command(int sk, uint16_t opcode, uint64_t serial)
192132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
193132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd cmd = {
194132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		.version	= cpu_to_le16(FIO_SERVER_VER1),
195132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		.opcode		= cpu_to_le16(opcode),
196bdab4441a476b8597001026445707daa1109aec2Jens Axboe		.serial		= cpu_to_le64(serial),
197132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	};
198132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
199132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fio_net_cmd_crc(&cmd);
200132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
201132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return fio_send_data(sk, &cmd, sizeof(cmd));
202132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
203132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
204132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe/*
205132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * Send an ack for this command
206132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe */
207132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int ack_command(int sk, struct fio_net_cmd *cmd)
208132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
209fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#if 0
210132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return send_simple_command(sk, FIO_NET_CMD_ACK, cmd->serial);
211fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#else
212fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	return 0;
213fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#endif
214132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
215132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
216132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#if 0
217132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int nak_command(int sk, struct fio_net_cmd *cmd)
218132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
219132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return send_simple_command(sk, FIO_NET_CMD_NAK, cmd->serial);
220132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
221132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#endif
222132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
223437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboestatic int send_quit_command(void)
224437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{
22546c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: sending quit\n");
226437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe	return send_simple_command(server_fd, FIO_NET_CMD_QUIT, 0);
227437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe}
228437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe
229794d69ca97738736844ee6a6da37f1ef686578cbJens Axboestatic int handle_cur_job(struct fio_net_cmd *cmd)
230132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
231132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	unsigned int left = job_max_len - job_cur_len;
232132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
234132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (left < cmd->pdu_len) {
235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		job_buf = realloc(job_buf, job_max_len + 2 * cmd->pdu_len);
236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		job_max_len += 2 * cmd->pdu_len;
237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
239132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	memcpy(job_buf + job_cur_len, cmd->payload, cmd->pdu_len);
240132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	job_cur_len += cmd->pdu_len;
241132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
242794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	/*
243794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	 * More data coming for this job
244794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	 */
245794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	if (cmd->flags & FIO_NET_CMD_F_MORE)
246794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		return 0;
247132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
248794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	parse_jobs_ini(job_buf, 1, 0);
249794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	ret = exec_run();
250794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	send_quit_command();
251794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	reset_fio_state();
252794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	free(job_buf);
253794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	job_buf = NULL;
254794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	job_cur_len = job_max_len = 0;
255132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
256132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
257132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
258132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd)
259132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
260132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret;
261132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
26246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: got opcode %d\n", cmd->opcode);
26346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
264132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->opcode) {
265132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_QUIT:
266132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		exit_backend = 1;
267132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
268132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_ACK:
269132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
270132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_NAK:
271132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
272132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_JOB:
273794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = handle_cur_job(cmd);
274132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
275132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
276132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: unknown opcode: %d\n", cmd->opcode);
277132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = 1;
278132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
279132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
280132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
281132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
282132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
283132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_connection(int sk)
284132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
285132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd *cmd = NULL;
286132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
288132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* read forever */
289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	while (!exit_backend) {
29037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe		cmd = fio_net_cmd_read(sk);
291132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (!cmd) {
292132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			ret = 1;
293132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
294132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		}
295132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
296132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = ack_command(sk, cmd);
297132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
298132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
299132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
300132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = handle_command(cmd);
301132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
302132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
303132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
304132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
305c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe		cmd = NULL;
306132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
307132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
308132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd)
309132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
310132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
311132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
312132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
313132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
31450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
31550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
31650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	struct sockaddr addr;
31750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	unsigned int len = sizeof(addr);
318009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
319132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret, sk, flags, exitval = 0;
32050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
321009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags = fcntl(listen_sk, F_GETFL);
322009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags |= O_NONBLOCK;
323009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	fcntl(listen_sk, F_SETFL, flags);
32450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain:
325009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.fd = listen_sk;
326009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.events = POLLIN;
327009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	do {
328009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		ret = poll(&pfd, 1, 100);
329009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (ret < 0) {
330009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			if (errno == EINTR)
331009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe				break;
332fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe			log_err("fio: poll: %s\n", strerror(errno));
333009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			goto out;
334009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		} else if (!ret)
335009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			continue;
336009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
337009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (pfd.revents & POLLIN)
338009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			break;
339009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	} while (!exit_backend);
340009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
341009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (exit_backend)
342009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		goto out;
343009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
34450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	sk = accept(listen_sk, &addr, &len);
34550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (sk < 0) {
346690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: accept: %s\n", strerror(errno));
34750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
34850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
34950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
35046c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server got a connection\n");
35146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
35237db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = sk;
35337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
354132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	exitval = handle_connection(sk);
35550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
35637db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = -1;
35750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	close(sk);
3585c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
359009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (!exit_backend)
3605c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe		goto again;
3615c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
362009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout:
363132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return exitval;
36450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
36550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
36650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeint fio_server(void)
36750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
36850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	struct sockaddr_in saddr_in;
36950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	struct sockaddr addr;
37050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	unsigned int len;
371afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	int sk, opt, ret;
37250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
37346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "starting server\n");
37446c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
37550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	sk = socket(AF_INET, SOCK_STREAM, 0);
37650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (sk < 0) {
377690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
37850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
37950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
38050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
38150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	opt = 1;
38250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
383690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
38450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
38550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
38650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#ifdef SO_REUSEPORT
38750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
388690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
38950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return 1;
39050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
39150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#endif
39250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
39350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	saddr_in.sin_family = AF_INET;
39450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
395132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	saddr_in.sin_port = htons(fio_net_port);
39650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
39750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) {
398690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
39950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
40050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
40150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
40250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (listen(sk, 1) < 0) {
403690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
40450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
40550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
40650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
40750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	len = sizeof(addr);
40850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (getsockname(sk, &addr, &len) < 0) {
409690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: getsockname: %s\n", strerror(errno));
41050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
41150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
41250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
413afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	ret = accept_loop(sk);
414afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	close(sk);
415afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	return ret;
41650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
41737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
418142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_text_output(const char *buf, unsigned int len)
41937db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
420337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe	if (server_fd != -1)
421337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe		return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len);
422337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe
423337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe	return 0;
424142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe}
425142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
426142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...)
427142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{
428142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	char buffer[1024];
429142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_list args;
43082fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	size_t len;
431142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
432142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_start(args, format);
43382fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	len = vsnprintf(buffer, sizeof(buffer), format, args);
434142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_end(args);
435142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
43682fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	return fio_server_text_output(buffer, len);
43737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe}
438