server.c revision e46d809110bd4ad2980ca64931b683673444454b
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>
15e46d809110bd4ad2980ca64931b683673444454bJens Axboe#include <syslog.h>
1650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
1750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h"
18132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#include "server.h"
19fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#include "crc/crc16.h"
2050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
21132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_net_port = 8765;
2250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
23009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0;
24009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
25132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic char *job_buf;
26132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic unsigned int job_cur_len;
27132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic unsigned int job_max_len;
28132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
2946c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboestatic int server_fd = -1;
3037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
31132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_send_data(int sk, const void *p, unsigned int len)
32132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
33794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU);
34794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
35132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
36132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = send(sk, p, len, 0);
37132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
38132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
39132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
40132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
41132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
42132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
43132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
44132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
45132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
46132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
47132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
48132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
49132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
50132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
51132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
52132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
53132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 1;
54132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
55132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
56132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboeint fio_recv_data(int sk, void *p, unsigned int len)
57132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
58132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	do {
59132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		int ret = recv(sk, p, len, MSG_WAITALL);
60132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
61132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret > 0) {
62132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			len -= ret;
63132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			if (!len)
64132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe				break;
65132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			p += ret;
66132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
67132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		} else if (!ret)
68132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
69132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		else if (errno == EAGAIN || errno == EINTR)
70132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			continue;
71132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	} while (!exit_backend);
72132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
73132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!len)
74132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
75132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
76132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return -1;
77132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
78132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
79132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int verify_convert_cmd(struct fio_net_cmd *cmd)
80132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
81fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
82132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
83fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16);
84fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16);
85132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
86fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	crc = crc16(cmd, FIO_NET_CMD_CRC_SZ);
87fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != cmd->cmd_crc16) {
88132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on command (got %x, wanted %x)\n",
89fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				cmd->cmd_crc16, crc);
90132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
91132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
92132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
93132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->version	= le16_to_cpu(cmd->version);
94132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->opcode	= le16_to_cpu(cmd->opcode);
95132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->flags	= le32_to_cpu(cmd->flags);
96132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->serial	= le64_to_cpu(cmd->serial);
97132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	cmd->pdu_len	= le32_to_cpu(cmd->pdu_len);
98132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
99132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->version) {
100132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_SERVER_VER1:
101132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
102132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
103132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: bad server cmd version %d\n", cmd->version);
104132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
105132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
106132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
107132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd->pdu_len > FIO_SERVER_MAX_PDU) {
108132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: command payload too large: %u\n", cmd->pdu_len);
109132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
110132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
111132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
112132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return 0;
113132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
114132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
11537db14feece08eb6e43de87c404180650ed5aa6fJens Axboestruct fio_net_cmd *fio_net_cmd_read(int sk)
116132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
117132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd cmd, *ret = NULL;
118fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	uint16_t crc;
119132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
120132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fio_recv_data(sk, &cmd, sizeof(cmd)))
121132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return NULL;
122132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
123132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* We have a command, verify it and swap if need be */
124132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (verify_convert_cmd(&cmd))
125132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return NULL;
126132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
127132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* Command checks out, alloc real command and fill in */
128132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	ret = malloc(sizeof(cmd) + cmd.pdu_len);
129132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	memcpy(ret, &cmd, sizeof(cmd));
130132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
131132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (!ret->pdu_len)
132132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return ret;
133132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
134132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* There's payload, get it */
135132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (fio_recv_data(sk, (void *) ret + sizeof(*ret), ret->pdu_len)) {
136132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(ret);
137132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return NULL;
138132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
139132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
140132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* Verify payload crc */
141fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	crc = crc16(ret->payload, ret->pdu_len);
142fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	if (crc != ret->pdu_crc16) {
143132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: server bad crc on payload (got %x, wanted %x)\n",
144fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe				ret->pdu_crc16, crc);
145132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(ret);
146132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return NULL;
147132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
148132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
149132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
150132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
151132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
152132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboevoid fio_net_cmd_crc(struct fio_net_cmd *cmd)
153132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
154132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	uint32_t pdu_len;
155132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
156fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	cmd->cmd_crc16 = cpu_to_le16(crc16(cmd, FIO_NET_CMD_CRC_SZ));
157132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
158132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	pdu_len = le32_to_cpu(cmd->pdu_len);
159132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (pdu_len)
160fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe		cmd->pdu_crc16 = cpu_to_le16(crc16(cmd->payload, pdu_len));
161132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
162132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
163794d69ca97738736844ee6a6da37f1ef686578cbJens Axboeint fio_net_send_cmd(int fd, uint16_t opcode, const char *buf, off_t size)
164794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe{
165794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	struct fio_net_cmd *cmd;
166794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	size_t this_len;
167794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	int ret;
168794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
169794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	do {
170794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		this_len = size;
171794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len > FIO_SERVER_MAX_PDU)
172794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe			this_len = FIO_SERVER_MAX_PDU;
173794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
174794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		cmd = malloc(sizeof(*cmd) + this_len);
175794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
176794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_init_net_cmd(cmd, opcode, buf, this_len);
177794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
178794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		if (this_len < size)
179794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe			cmd->flags |= FIO_NET_CMD_F_MORE;
180794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
181794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		fio_net_cmd_crc(cmd);
182794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
183794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
184794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		free(cmd);
185794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		size -= this_len;
186794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		buf += this_len;
187794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	} while (!ret && size);
188794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
189794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	return ret;
190794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe}
191794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe
192132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int send_simple_command(int sk, uint16_t opcode, uint64_t serial)
193132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
194132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd cmd = {
195132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		.version	= cpu_to_le16(FIO_SERVER_VER1),
196132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		.opcode		= cpu_to_le16(opcode),
197bdab4441a476b8597001026445707daa1109aec2Jens Axboe		.serial		= cpu_to_le64(serial),
198132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	};
199132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
200132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	fio_net_cmd_crc(&cmd);
201132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
202132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return fio_send_data(sk, &cmd, sizeof(cmd));
203132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
204132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
205132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe/*
206132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe * Send an ack for this command
207132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe */
208132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int ack_command(int sk, struct fio_net_cmd *cmd)
209132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
210fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#if 0
211132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return send_simple_command(sk, FIO_NET_CMD_ACK, cmd->serial);
212fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#else
213fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe	return 0;
214fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe#endif
215132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
216132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
217132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#if 0
218132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int nak_command(int sk, struct fio_net_cmd *cmd)
219132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
220132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return send_simple_command(sk, FIO_NET_CMD_NAK, cmd->serial);
221132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
222132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe#endif
223132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
224437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboestatic int send_quit_command(void)
225437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe{
22646c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: sending quit\n");
227437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe	return send_simple_command(server_fd, FIO_NET_CMD_QUIT, 0);
228437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe}
229437377e14010f4443bd0fd1b40c4e75885520d7dJens Axboe
230794d69ca97738736844ee6a6da37f1ef686578cbJens Axboestatic int handle_cur_job(struct fio_net_cmd *cmd)
231132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
232132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	unsigned int left = job_max_len - job_cur_len;
233132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
234132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
235132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (left < cmd->pdu_len) {
236132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		job_buf = realloc(job_buf, job_max_len + 2 * cmd->pdu_len);
237132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		job_max_len += 2 * cmd->pdu_len;
238132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
239132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
240132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	memcpy(job_buf + job_cur_len, cmd->payload, cmd->pdu_len);
241132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	job_cur_len += cmd->pdu_len;
242132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
243794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	/*
244794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	 * More data coming for this job
245794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	 */
246794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	if (cmd->flags & FIO_NET_CMD_F_MORE)
247794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		return 0;
248132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
249794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	parse_jobs_ini(job_buf, 1, 0);
250794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	ret = exec_run();
251794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	send_quit_command();
252794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	reset_fio_state();
253794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	free(job_buf);
254794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	job_buf = NULL;
255794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe	job_cur_len = job_max_len = 0;
256132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
257132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
258132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
259132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_command(struct fio_net_cmd *cmd)
260132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
261132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret;
262132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
26346c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server: got opcode %d\n", cmd->opcode);
26446c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
265132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	switch (cmd->opcode) {
266132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_QUIT:
267132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		exit_backend = 1;
268132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
269132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_ACK:
270132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 0;
271132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_NAK:
272132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		return 1;
273132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	case FIO_NET_CMD_JOB:
274794d69ca97738736844ee6a6da37f1ef686578cbJens Axboe		ret = handle_cur_job(cmd);
275132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		break;
276132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	default:
277132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		log_err("fio: unknown opcode: %d\n", cmd->opcode);
278132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = 1;
279132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
280132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
281132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
282132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
283132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
284132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboestatic int handle_connection(int sk)
285132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe{
286132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	struct fio_net_cmd *cmd = NULL;
287132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret = 0;
288132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
289132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	/* read forever */
290132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	while (!exit_backend) {
29137db14feece08eb6e43de87c404180650ed5aa6fJens Axboe		cmd = fio_net_cmd_read(sk);
292132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (!cmd) {
293132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			ret = 1;
294132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
295132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		}
296132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
297132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = ack_command(sk, cmd);
298132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
299132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
300132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
301132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		ret = handle_command(cmd);
302132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		if (ret)
303132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe			break;
304132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
305132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
306c77a99e74e88a8ea1a8c0904aef3f7c81e07273fJens Axboe		cmd = NULL;
307132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	}
308132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
309132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	if (cmd)
310132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe		free(cmd);
311132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
312132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return ret;
313132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe}
314132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe
31550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
31650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
31750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	struct sockaddr addr;
31850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	unsigned int len = sizeof(addr);
319009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
320132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	int ret, sk, flags, exitval = 0;
32150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
322009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags = fcntl(listen_sk, F_GETFL);
323009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags |= O_NONBLOCK;
324009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	fcntl(listen_sk, F_SETFL, flags);
32550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain:
326009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.fd = listen_sk;
327009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.events = POLLIN;
328009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	do {
329009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		ret = poll(&pfd, 1, 100);
330009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (ret < 0) {
331009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			if (errno == EINTR)
332009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe				break;
333fcee5ff6f30d0f05582a378a310ed1f68491766fJens Axboe			log_err("fio: poll: %s\n", strerror(errno));
334009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			goto out;
335009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		} else if (!ret)
336009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			continue;
337009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
338009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (pfd.revents & POLLIN)
339009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			break;
340009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	} while (!exit_backend);
341009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
342009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (exit_backend)
343009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		goto out;
344009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
34550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	sk = accept(listen_sk, &addr, &len);
34650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (sk < 0) {
347690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: accept: %s\n", strerror(errno));
34850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
34950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
35050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
35146c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "server got a connection\n");
35246c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
35337db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = sk;
35437db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
355132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	exitval = handle_connection(sk);
35650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
35737db14feece08eb6e43de87c404180650ed5aa6fJens Axboe	server_fd = -1;
35850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	close(sk);
3595c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
360009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (!exit_backend)
3615c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe		goto again;
3625c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
363009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout:
364132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	return exitval;
36550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
36650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
367e46d809110bd4ad2980ca64931b683673444454bJens Axboestatic int fio_server(void)
36850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
36950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	struct sockaddr_in saddr_in;
37050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	struct sockaddr addr;
37150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	unsigned int len;
372afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	int sk, opt, ret;
37350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
37446c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe	dprint(FD_NET, "starting server\n");
37546c48f1f9b8ce94132c13638e4c83c13e1d392daJens Axboe
37650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	sk = socket(AF_INET, SOCK_STREAM, 0);
37750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (sk < 0) {
378690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
37950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
38050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
38150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
38250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	opt = 1;
38350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
384690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
38550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
38650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
38750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#ifdef SO_REUSEPORT
38850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
389690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
39050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return 1;
39150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
39250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#endif
39350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
39450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	saddr_in.sin_family = AF_INET;
39550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
396132159a5a062cabfe963b3d57e82a80741bf5506Jens Axboe	saddr_in.sin_port = htons(fio_net_port);
39750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
39850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) {
399690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
40050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
40150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
40250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
40350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (listen(sk, 1) < 0) {
404690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
40550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
40650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
40750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
40850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	len = sizeof(addr);
40950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (getsockname(sk, &addr, &len) < 0) {
410690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: getsockname: %s\n", strerror(errno));
41150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
41250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
41350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
414afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	ret = accept_loop(sk);
415afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	close(sk);
416afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	return ret;
41750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
41837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe
419142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_text_output(const char *buf, unsigned int len)
42037db14feece08eb6e43de87c404180650ed5aa6fJens Axboe{
421337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe	if (server_fd != -1)
422337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe		return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len);
423337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe
424337d75a81c40aef6d693fc0d18e78b0c2444a1beJens Axboe	return 0;
425142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe}
426142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
427142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboeint fio_server_log(const char *format, ...)
428142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe{
429142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	char buffer[1024];
430142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_list args;
43182fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	size_t len;
432142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
433142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_start(args, format);
43482fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	len = vsnprintf(buffer, sizeof(buffer), format, args);
435142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe	va_end(args);
436142575e6579462656a6d0f7c50ec8c35b8a08802Jens Axboe
43782fa6b21d98da1341a54f415e43940213b39f18bJens Axboe	return fio_server_text_output(buffer, len);
43837db14feece08eb6e43de87c404180650ed5aa6fJens Axboe}
439e46d809110bd4ad2980ca64931b683673444454bJens Axboe
440e46d809110bd4ad2980ca64931b683673444454bJens Axboeint fio_start_server(int daemonize)
441e46d809110bd4ad2980ca64931b683673444454bJens Axboe{
442e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid_t pid;
443e46d809110bd4ad2980ca64931b683673444454bJens Axboe
444e46d809110bd4ad2980ca64931b683673444454bJens Axboe	if (!daemonize)
445e46d809110bd4ad2980ca64931b683673444454bJens Axboe		return fio_server();
446e46d809110bd4ad2980ca64931b683673444454bJens Axboe
447e46d809110bd4ad2980ca64931b683673444454bJens Axboe	openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
448e46d809110bd4ad2980ca64931b683673444454bJens Axboe	pid = fork();
449e46d809110bd4ad2980ca64931b683673444454bJens Axboe	if (pid < 0) {
450e46d809110bd4ad2980ca64931b683673444454bJens Axboe		syslog(LOG_ERR, "failed server fork");
451e46d809110bd4ad2980ca64931b683673444454bJens Axboe		return 1;
452e46d809110bd4ad2980ca64931b683673444454bJens Axboe	} else if (pid)
453e46d809110bd4ad2980ca64931b683673444454bJens Axboe		exit(0);
454e46d809110bd4ad2980ca64931b683673444454bJens Axboe
455e46d809110bd4ad2980ca64931b683673444454bJens Axboe	setsid();
456e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDIN_FILENO);
457e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDOUT_FILENO);
458e46d809110bd4ad2980ca64931b683673444454bJens Axboe	close(STDERR_FILENO);
459e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_out = NULL;
460e46d809110bd4ad2980ca64931b683673444454bJens Axboe	f_err = NULL;
461e46d809110bd4ad2980ca64931b683673444454bJens Axboe	log_syslog = 1;
462e46d809110bd4ad2980ca64931b683673444454bJens Axboe	return fio_server();
463e46d809110bd4ad2980ca64931b683673444454bJens Axboe}
464