Properly log errors in server
[fio.git] / server.c
CommitLineData
50d16976
JA
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <limits.h>
5#include <string.h>
6#include <getopt.h>
7#include <errno.h>
8#include <fcntl.h>
9#include <sys/poll.h>
10#include <sys/stat.h>
11#include <sys/types.h>
12#include <sys/wait.h>
13#include <sys/time.h>
14#include <sys/mman.h>
15#include <signal.h>
16#include <netinet/in.h>
17#include <arpa/inet.h>
18#include <netdb.h>
19
20#include "fio.h"
21
22static int net_port = 8765;
23
009b1be4
JA
24int exit_backend = 0;
25
50d16976
JA
26static int accept_loop(int listen_sk)
27{
28 struct sockaddr addr;
29 unsigned int len = sizeof(addr);
009b1be4
JA
30 struct pollfd pfd;
31 int ret, sk, flags;
50d16976 32
009b1be4
JA
33 flags = fcntl(listen_sk, F_GETFL);
34 flags |= O_NONBLOCK;
35 fcntl(listen_sk, F_SETFL, flags);
50d16976 36again:
009b1be4
JA
37 pfd.fd = listen_sk;
38 pfd.events = POLLIN;
39 do {
40 ret = poll(&pfd, 1, 100);
41 if (ret < 0) {
42 if (errno == EINTR)
43 break;
44 perror("poll");
45 goto out;
46 } else if (!ret)
47 continue;
48
49 if (pfd.revents & POLLIN)
50 break;
51 } while (!exit_backend);
52
53 if (exit_backend)
54 goto out;
55
50d16976 56 sk = accept(listen_sk, &addr, &len);
50d16976 57 if (sk < 0) {
690e09ae 58 log_err("fio: accept: %s\n", strerror(errno));
50d16976
JA
59 return -1;
60 }
61
62 /* read forever */
009b1be4 63 while (!exit_backend) {
50d16976 64 char buf[131072];
50d16976
JA
65
66 ret = recv(sk, buf, 4096, 0);
67 if (ret > 0) {
5c341e9a 68 if (!strncmp("FIO_QUIT", buf, 8)) {
009b1be4 69 exit_backend = 1;
5c341e9a
JA
70 break;
71 }
50d16976
JA
72 parse_jobs_ini(buf, 1, 0);
73 exec_run();
74 reset_fio_state();
75 break;
76 } else if (!ret)
77 break;
78 if (errno == EAGAIN || errno == EINTR)
79 continue;
80 break;
81 }
82
83 close(sk);
5c341e9a 84
009b1be4 85 if (!exit_backend)
5c341e9a
JA
86 goto again;
87
009b1be4 88out:
5c341e9a 89 return 0;
50d16976
JA
90}
91
92int fio_server(void)
93{
94 struct sockaddr_in saddr_in;
95 struct sockaddr addr;
96 unsigned int len;
afcf7758 97 int sk, opt, ret;
50d16976
JA
98
99 sk = socket(AF_INET, SOCK_STREAM, 0);
100 if (sk < 0) {
690e09ae 101 log_err("fio: socket: %s\n", strerror(errno));
50d16976
JA
102 return -1;
103 }
104
105 opt = 1;
106 if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
690e09ae 107 log_err("fio: setsockopt: %s\n", strerror(errno));
50d16976
JA
108 return -1;
109 }
110#ifdef SO_REUSEPORT
111 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
690e09ae 112 log_err("fio: setsockopt: %s\n", strerror(errno));
50d16976
JA
113 return 1;
114 }
115#endif
116
117 saddr_in.sin_family = AF_INET;
118 saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
119 saddr_in.sin_port = htons(net_port);
120
121 if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) {
690e09ae 122 log_err("fio: bind: %s\n", strerror(errno));
50d16976
JA
123 return -1;
124 }
125
126 if (listen(sk, 1) < 0) {
690e09ae 127 log_err("fio: listen: %s\n", strerror(errno));
50d16976
JA
128 return -1;
129 }
130
131 len = sizeof(addr);
132 if (getsockname(sk, &addr, &len) < 0) {
690e09ae 133 log_err("fio: getsockname: %s\n", strerror(errno));
50d16976
JA
134 return -1;
135 }
136
afcf7758
JA
137 ret = accept_loop(sk);
138 close(sk);
139 return ret;
50d16976 140}