server.c revision 690e09aeff6111f0654899840280196cf8c96224
150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <stdio.h>
250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <stdlib.h>
350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <unistd.h>
450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <limits.h>
550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <string.h>
650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <getopt.h>
750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <errno.h>
850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <fcntl.h>
950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/poll.h>
1050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/stat.h>
1150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/types.h>
1250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/wait.h>
1350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/time.h>
1450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <sys/mman.h>
1550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <signal.h>
1650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netinet/in.h>
1750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <arpa/inet.h>
1850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include <netdb.h>
1950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
2050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#include "fio.h"
2150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
2250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int net_port = 8765;
2350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
24009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeint exit_backend = 0;
25009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
2650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboestatic int accept_loop(int listen_sk)
2750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
2850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	struct sockaddr addr;
2950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	unsigned int len = sizeof(addr);
30009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	struct pollfd pfd;
31009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	int ret, sk, flags;
3250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
33009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags = fcntl(listen_sk, F_GETFL);
34009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	flags |= O_NONBLOCK;
35009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	fcntl(listen_sk, F_SETFL, flags);
3650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeagain:
37009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.fd = listen_sk;
38009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	pfd.events = POLLIN;
39009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	do {
40009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		ret = poll(&pfd, 1, 100);
41009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (ret < 0) {
42009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			if (errno == EINTR)
43009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe				break;
44009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			perror("poll");
45009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			goto out;
46009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		} else if (!ret)
47009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			continue;
48009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
49009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		if (pfd.revents & POLLIN)
50009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe			break;
51009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	} while (!exit_backend);
52009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
53009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (exit_backend)
54009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe		goto out;
55009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe
5650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	sk = accept(listen_sk, &addr, &len);
5750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (sk < 0) {
58690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: accept: %s\n", strerror(errno));
5950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
6050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
6150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
6250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	/* read forever */
63009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	while (!exit_backend) {
6450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		char buf[131072];
6550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
6650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		ret = recv(sk, buf, 4096, 0);
6750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		if (ret > 0) {
685c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe			if (!strncmp("FIO_QUIT", buf, 8)) {
69009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe				exit_backend = 1;
705c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe				break;
715c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe			}
7250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe			parse_jobs_ini(buf, 1, 0);
7350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe			exec_run();
7450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe			reset_fio_state();
7550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe			break;
7650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		} else if (!ret)
7750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe			break;
7850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		if (errno == EAGAIN || errno == EINTR)
7950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe			continue;
8050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		break;
8150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
8250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
8350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	close(sk);
845c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
85009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboe	if (!exit_backend)
865c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe		goto again;
875c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe
88009b1be41b32bf7e32b441c6a22e3ae628ec9b89Jens Axboeout:
895c341e9a5734742ae1137388345d4f47efdd4f05Jens Axboe	return 0;
9050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
9150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
9250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboeint fio_server(void)
9350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe{
9450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	struct sockaddr_in saddr_in;
9550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	struct sockaddr addr;
9650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	unsigned int len;
97afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	int sk, opt, ret;
9850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
9950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	sk = socket(AF_INET, SOCK_STREAM, 0);
10050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (sk < 0) {
101690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
10250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
10350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
10450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
10550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	opt = 1;
10650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
107690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
10850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
10950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
11050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#ifdef SO_REUSEPORT
11150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
112690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: setsockopt: %s\n", strerror(errno));
11350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return 1;
11450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
11550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe#endif
11650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
11750d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	saddr_in.sin_family = AF_INET;
11850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
11950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	saddr_in.sin_port = htons(net_port);
12050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
12150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) {
122690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
12350d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
12450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
12550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
12650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (listen(sk, 1) < 0) {
127690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: listen: %s\n", strerror(errno));
12850d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
12950d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
13050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
13150d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	len = sizeof(addr);
13250d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	if (getsockname(sk, &addr, &len) < 0) {
133690e09aeff6111f0654899840280196cf8c96224Jens Axboe		log_err("fio: getsockname: %s\n", strerror(errno));
13450d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe		return -1;
13550d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe	}
13650d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe
137afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	ret = accept_loop(sk);
138afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	close(sk);
139afcf77584a39461d81ff8b5c3c86fb7583172020Jens Axboe	return ret;
14050d16976ac0cd44c1f5aba9217148ff05e141436Jens Axboe}
141