daemon.c: squelch error message from EINTR
[git.git] / daemon.c
1 #include "cache.h"
2 #include "pkt-line.h"
3 #include <signal.h>
4 #include <sys/wait.h>
5 #include <sys/socket.h>
6 #include <netdb.h>
7 #include <netinet/in.h>
8
9 static const char daemon_usage[] = "git-daemon [--inetd | --port=n]";
10
11 static int upload(char *dir, int dirlen)
12 {
13         if (chdir(dir) < 0)
14                 return -1;
15         chdir(".git");
16
17         /*
18          * Security on the cheap.
19          *
20          * We want a readable HEAD, usable "objects" directory, and 
21          * a "git-daemon-export-ok" flag that says that the other side
22          * is ok with us doing this.
23          */
24         if (access("git-daemon-export-ok", F_OK) ||
25             access("objects/00", X_OK) ||
26             access("HEAD", R_OK))
27                 return -1;
28
29         /*
30          * We'll ignore SIGTERM from now on, we have a
31          * good client.
32          */
33         signal(SIGTERM, SIG_IGN);
34
35         /* git-upload-pack only ever reads stuff, so this is safe */
36         execlp("git-upload-pack", "git-upload-pack", ".", NULL);
37         return -1;
38 }
39
40 static int execute(void)
41 {
42         static char line[1000];
43         int len;
44
45         len = packet_read_line(0, line, sizeof(line));
46
47         if (len && line[len-1] == '\n')
48                 line[--len] = 0;
49
50         if (!strncmp("git-upload-pack /", line, 17))
51                 return upload(line + 16, len - 16);
52
53         fprintf(stderr, "got bad connection '%s'\n", line);
54         return -1;
55 }
56
57
58 /*
59  * We count spawned/reaped separately, just to avoid any
60  * races when updating them from signals. The SIGCHLD handler
61  * will only update children_reaped, and the fork logic will
62  * only update children_spawned.
63  *
64  * MAX_CHILDREN should be a power-of-two to make the modulus
65  * operation cheap. It should also be at least twice
66  * the maximum number of connections we will ever allow.
67  */
68 #define MAX_CHILDREN 128
69
70 static int max_connections = 25;
71
72 /* These are updated by the signal handler */
73 static volatile unsigned int children_reaped = 0;
74 static pid_t dead_child[MAX_CHILDREN];
75
76 /* These are updated by the main loop */
77 static unsigned int children_spawned = 0;
78 static unsigned int children_deleted = 0;
79
80 static struct child {
81         pid_t pid;
82         socklen_t addrlen;
83         struct sockaddr_storage address;
84 } live_child[MAX_CHILDREN];
85
86 static void add_child(int idx, pid_t pid, struct sockaddr *addr, socklen_t addrlen)
87 {
88         live_child[idx].pid = pid;
89         live_child[idx].addrlen = addrlen;
90         memcpy(&live_child[idx].address, addr, addrlen);
91 }
92
93 /*
94  * Walk from "deleted" to "spawned", and remove child "pid".
95  *
96  * We move everything up by one, since the new "deleted" will
97  * be one higher.
98  */
99 static void remove_child(pid_t pid, unsigned deleted, unsigned spawned)
100 {
101         struct child n;
102
103         deleted %= MAX_CHILDREN;
104         spawned %= MAX_CHILDREN;
105         if (live_child[deleted].pid == pid) {
106                 live_child[deleted].pid = -1;
107                 return;
108         }
109         n = live_child[deleted];
110         for (;;) {
111                 struct child m;
112                 deleted = (deleted + 1) % MAX_CHILDREN;
113                 if (deleted == spawned)
114                         die("could not find dead child %d\n", pid);
115                 m = live_child[deleted];
116                 live_child[deleted] = n;
117                 if (m.pid == pid)
118                         return;
119                 n = m;
120         }
121 }
122
123 /*
124  * This gets called if the number of connections grows
125  * past "max_connections".
126  *
127  * We _should_ start off by searching for connections
128  * from the same IP, and if there is some address wth
129  * multiple connections, we should kill that first.
130  *
131  * As it is, we just "randomly" kill 25% of the connections,
132  * and our pseudo-random generator sucks too. I have no
133  * shame.
134  *
135  * Really, this is just a place-holder for a _real_ algorithm.
136  */
137 static void kill_some_children(int signo, unsigned start, unsigned stop)
138 {
139         start %= MAX_CHILDREN;
140         stop %= MAX_CHILDREN;
141         while (start != stop) {
142                 if (!(start & 3))
143                         kill(live_child[start].pid, signo);
144                 start = (start + 1) % MAX_CHILDREN;
145         }
146 }
147
148 static void check_max_connections(void)
149 {
150         for (;;) {
151                 int active;
152                 unsigned spawned, reaped, deleted;
153
154                 spawned = children_spawned;
155                 reaped = children_reaped;
156                 deleted = children_deleted;
157
158                 while (deleted < reaped) {
159                         pid_t pid = dead_child[deleted % MAX_CHILDREN];
160                         remove_child(pid, deleted, spawned);
161                         deleted++;
162                 }
163                 children_deleted = deleted;
164
165                 active = spawned - deleted;
166                 if (active <= max_connections)
167                         break;
168
169                 /* Kill some unstarted connections with SIGTERM */
170                 kill_some_children(SIGTERM, deleted, spawned);
171                 if (active <= max_connections << 1)
172                         break;
173
174                 /* If the SIGTERM thing isn't helping use SIGKILL */
175                 kill_some_children(SIGKILL, deleted, spawned);
176                 sleep(1);
177         }
178 }
179
180 static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
181 {
182         pid_t pid = fork();
183
184         if (pid) {
185                 unsigned idx;
186
187                 close(incoming);
188                 if (pid < 0)
189                         return;
190
191                 idx = children_spawned % MAX_CHILDREN;
192                 children_spawned++;
193                 add_child(idx, pid, addr, addrlen);
194
195                 check_max_connections();
196                 return;
197         }
198
199         dup2(incoming, 0);
200         dup2(incoming, 1);
201         close(incoming);
202         exit(execute());
203 }
204
205 static void child_handler(int signo)
206 {
207         for (;;) {
208                 pid_t pid = waitpid(-1, NULL, WNOHANG);
209
210                 if (pid > 0) {
211                         unsigned reaped = children_reaped;
212                         dead_child[reaped % MAX_CHILDREN] = pid;
213                         children_reaped = reaped + 1;
214                         continue;
215                 }
216                 break;
217         }
218 }
219
220 static int serve(int port)
221 {
222         struct addrinfo hints, *ai0, *ai;
223         int gai;
224         int socknum = 0, *socklist = NULL;
225         int maxfd = -1;
226         fd_set fds_init, fds;
227         char pbuf[NI_MAXSERV];
228
229         signal(SIGCHLD, child_handler);
230
231         sprintf(pbuf, "%d", port);
232         memset(&hints, 0, sizeof(hints));
233         hints.ai_family = AF_UNSPEC;
234         hints.ai_socktype = SOCK_STREAM;
235         hints.ai_protocol = IPPROTO_TCP;
236         hints.ai_flags = AI_PASSIVE;
237
238         gai = getaddrinfo(NULL, pbuf, &hints, &ai0);
239         if (gai)
240                 die("getaddrinfo() failed: %s\n", gai_strerror(gai));
241
242         FD_ZERO(&fds_init);
243
244         for (ai = ai0; ai; ai = ai->ai_next) {
245                 int sockfd;
246                 int *newlist;
247
248                 sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
249                 if (sockfd < 0)
250                         continue;
251                 if (sockfd >= FD_SETSIZE) {
252                         error("too large socket descriptor.");
253                         close(sockfd);
254                         continue;
255                 }
256
257 #ifdef IPV6_V6ONLY
258                 if (ai->ai_family == AF_INET6) {
259                         int on = 1;
260                         setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
261                                    &on, sizeof(on));
262                         /* Note: error is not fatal */
263                 }
264 #endif
265
266                 if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
267                         close(sockfd);
268                         continue;       /* not fatal */
269                 }
270                 if (listen(sockfd, 5) < 0) {
271                         close(sockfd);
272                         continue;       /* not fatal */
273                 }
274
275                 newlist = realloc(socklist, sizeof(int) * (socknum + 1));
276                 if (!newlist)
277                         die("memory allocation failed: %s", strerror(errno));
278
279                 socklist = newlist;
280                 socklist[socknum++] = sockfd;
281
282                 FD_SET(sockfd, &fds_init);
283                 if (maxfd < sockfd)
284                         maxfd = sockfd;
285         }
286
287         freeaddrinfo(ai0);
288
289         if (socknum == 0)
290                 die("unable to allocate any listen sockets on port %u", port);
291
292         for (;;) {
293                 int i;
294                 fds = fds_init;
295                 
296                 if (select(maxfd + 1, &fds, NULL, NULL, NULL) < 0) {
297                         if (errno != EINTR) {
298                                 error("select failed, resuming: %s",
299                                       strerror(errno));
300                                 sleep(1);
301                         }
302                         continue;
303                 }
304
305                 for (i = 0; i < socknum; i++) {
306                         int sockfd = socklist[i];
307
308                         if (FD_ISSET(sockfd, &fds)) {
309                                 struct sockaddr_storage ss;
310                                 socklen_t sslen = sizeof(ss);
311                                 int incoming = accept(sockfd, (struct sockaddr *)&ss, &sslen);
312                                 if (incoming < 0) {
313                                         switch (errno) {
314                                         case EAGAIN:
315                                         case EINTR:
316                                         case ECONNABORTED:
317                                                 continue;
318                                         default:
319                                                 die("accept returned %s", strerror(errno));
320                                         }
321                                 }
322                                 handle(incoming, (struct sockaddr *)&ss, sslen);
323                         }
324                 }
325         }
326 }
327
328 int main(int argc, char **argv)
329 {
330         int port = DEFAULT_GIT_PORT;
331         int inetd_mode = 0;
332         int i;
333
334         for (i = 1; i < argc; i++) {
335                 char *arg = argv[i];
336
337                 if (!strncmp(arg, "--port=", 7)) {
338                         char *end;
339                         unsigned long n;
340                         n = strtoul(arg+7, &end, 0);
341                         if (arg[7] && !*end) {
342                                 port = n;
343                                 continue;
344                         }
345                 }
346
347                 if (!strcmp(arg, "--inetd")) {
348                         inetd_mode = 1;
349                         continue;
350                 }
351
352                 usage(daemon_usage);
353         }
354
355         if (inetd_mode)
356                 return execute();
357
358         return serve(port);
359 }