]> git.ipfire.org Git - people/ms/systemd.git/blame - socket.c
socket: optionally call accept() for incoming connections and spawn one service insta...
[people/ms/systemd.git] / socket.c
CommitLineData
5cb5a6ff
LP
1/*-*- Mode: C; c-basic-offset: 8 -*-*/
2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
83c60c9f
LP
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <unistd.h>
25#include <errno.h>
26#include <fcntl.h>
f94ea366 27#include <sys/epoll.h>
034c6ed7 28#include <signal.h>
4f2d528d 29#include <arpa/inet.h>
83c60c9f 30
87f0e418 31#include "unit.h"
5cb5a6ff 32#include "socket.h"
83c60c9f 33#include "log.h"
23a177ef
LP
34#include "load-dropin.h"
35#include "load-fragment.h"
9e2f7c11 36#include "strv.h"
4f2d528d 37#include "unit-name.h"
83c60c9f 38
acbb0225 39static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
87f0e418
LP
40 [SOCKET_DEAD] = UNIT_INACTIVE,
41 [SOCKET_START_PRE] = UNIT_ACTIVATING,
42 [SOCKET_START_POST] = UNIT_ACTIVATING,
43 [SOCKET_LISTENING] = UNIT_ACTIVE,
44 [SOCKET_RUNNING] = UNIT_ACTIVE,
45 [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
46 [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
47 [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
48 [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
80876c20
LP
49 [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING,
50 [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING,
87f0e418 51 [SOCKET_MAINTAINANCE] = UNIT_INACTIVE,
83c60c9f 52};
5cb5a6ff 53
acbb0225
LP
54static const char* const state_string_table[_SOCKET_STATE_MAX] = {
55 [SOCKET_DEAD] = "dead",
56 [SOCKET_START_PRE] = "start-pre",
57 [SOCKET_START_POST] = "start-post",
58 [SOCKET_LISTENING] = "listening",
59 [SOCKET_RUNNING] = "running",
60 [SOCKET_STOP_PRE] = "stop-pre",
61 [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
62 [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
63 [SOCKET_STOP_POST] = "stop-post",
80876c20
LP
64 [SOCKET_FINAL_SIGTERM] = "final-sigterm",
65 [SOCKET_FINAL_SIGKILL] = "final-sigkill",
acbb0225
LP
66 [SOCKET_MAINTAINANCE] = "maintainance"
67};
68
5e94833f
LP
69static void socket_unwatch_control_pid(Socket *s) {
70 assert(s);
71
72 if (s->control_pid <= 0)
73 return;
74
75 unit_unwatch_pid(UNIT(s), s->control_pid);
76 s->control_pid = 0;
77}
78
87f0e418
LP
79static void socket_done(Unit *u) {
80 Socket *s = SOCKET(u);
034c6ed7
LP
81 SocketPort *p;
82
83 assert(s);
84
85 while ((p = s->ports)) {
86 LIST_REMOVE(SocketPort, port, s->ports, p);
87
88 if (p->fd >= 0)
89 close_nointr(p->fd);
90 free(p->path);
91 free(p);
92 }
93
94 exec_context_done(&s->exec_context);
e537352b 95 exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
034c6ed7
LP
96 s->control_command = NULL;
97
5e94833f 98 socket_unwatch_control_pid(s);
034c6ed7
LP
99
100 s->service = NULL;
101
acbb0225 102 free(s->bind_to_device);
e537352b 103 s->bind_to_device = NULL;
acbb0225
LP
104
105 unit_unwatch_timer(u, &s->timer_watch);
5cb5a6ff
LP
106}
107
e537352b 108static void socket_init(Unit *u) {
87f0e418 109 Socket *s = SOCKET(u);
44d8db9e 110
e537352b
LP
111 assert(u);
112 assert(u->meta.load_state == UNIT_STUB);
44d8db9e
LP
113
114 s->state = 0;
acbb0225 115 s->timer_watch.type = WATCH_INVALID;
44d8db9e
LP
116 s->bind_ipv6_only = false;
117 s->backlog = SOMAXCONN;
118 s->timeout_usec = DEFAULT_TIMEOUT_USEC;
b5a0699f
LP
119 s->directory_mode = 0755;
120 s->socket_mode = 0666;
50159e6a
LP
121 s->kill_mode = 0;
122 s->failure = false;
123 s->control_pid = 0;
e537352b 124 s->service = NULL;
4f2d528d
LP
125 s->accept = false;
126 s->n_accepted = 0;
44d8db9e 127 exec_context_init(&s->exec_context);
e537352b 128}
44d8db9e 129
4f2d528d
LP
130static bool have_non_accept_socket(Socket *s) {
131 SocketPort *p;
132
133 assert(s);
134
135 if (!s->accept)
136 return true;
137
138 LIST_FOREACH(port, p, s->ports)
139 if (!socket_address_can_accept(&p->address))
140 return true;
141
142 return false;
143}
144
145static int socket_verify(Socket *s) {
146 assert(s);
147
148 if (UNIT(s)->meta.load_state != UNIT_LOADED)
149 return 0;
150
151 if (!s->ports) {
152 log_error("%s lacks Listen setting. Refusing.", UNIT(s)->meta.id);
153 return -EINVAL;
154 }
155
156 return 0;
157}
158
e537352b
LP
159static int socket_load(Unit *u) {
160 Socket *s = SOCKET(u);
161 int r;
44d8db9e 162
e537352b
LP
163 assert(u);
164 assert(u->meta.load_state == UNIT_STUB);
44d8db9e 165
e537352b 166 if ((r = unit_load_fragment_and_dropin(u)) < 0)
23a177ef 167 return r;
44d8db9e 168
23a177ef 169 /* This is a new unit? Then let's add in some extras */
e537352b 170 if (u->meta.load_state == UNIT_LOADED) {
44d8db9e 171
4f2d528d
LP
172 if (have_non_accept_socket(s)) {
173 if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service)))
174 return r;
23a177ef 175
4f2d528d
LP
176 if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service))) < 0)
177 return r;
178 }
44d8db9e 179
23a177ef
LP
180 if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
181 return r;
182
183 if ((r = unit_add_default_cgroup(u)) < 0)
184 return r;
185 }
186
4f2d528d 187 return socket_verify(s);
44d8db9e
LP
188}
189
542563ba
LP
190static const char* listen_lookup(int type) {
191
192 if (type == SOCK_STREAM)
193 return "ListenStream";
194 else if (type == SOCK_DGRAM)
195 return "ListenDatagram";
196 else if (type == SOCK_SEQPACKET)
197 return "ListenSequentialPacket";
198
034c6ed7 199 assert_not_reached("Unknown socket type");
542563ba
LP
200 return NULL;
201}
202
87f0e418 203static void socket_dump(Unit *u, FILE *f, const char *prefix) {
5cb5a6ff 204
e537352b 205 static const char* const command_table[_SOCKET_EXEC_COMMAND_MAX] = {
5cb5a6ff
LP
206 [SOCKET_EXEC_START_PRE] = "StartPre",
207 [SOCKET_EXEC_START_POST] = "StartPost",
208 [SOCKET_EXEC_STOP_PRE] = "StopPre",
209 [SOCKET_EXEC_STOP_POST] = "StopPost"
210 };
211
212 SocketExecCommand c;
87f0e418 213 Socket *s = SOCKET(u);
542563ba 214 SocketPort *p;
82ba9f08
LP
215 const char *prefix2;
216 char *p2;
5cb5a6ff
LP
217
218 assert(s);
fa068367 219 assert(f);
5cb5a6ff 220
82ba9f08
LP
221 p2 = strappend(prefix, "\t");
222 prefix2 = p2 ? p2 : prefix;
c43d20a0 223
5cb5a6ff
LP
224 fprintf(f,
225 "%sSocket State: %s\n"
542563ba 226 "%sBindIPv6Only: %s\n"
b5a0699f 227 "%sBacklog: %u\n"
50159e6a 228 "%sKillMode: %s\n"
b5a0699f
LP
229 "%sSocketMode: %04o\n"
230 "%sDirectoryMode: %04o\n",
acbb0225 231 prefix, state_string_table[s->state],
542563ba 232 prefix, yes_no(s->bind_ipv6_only),
b5a0699f 233 prefix, s->backlog,
50159e6a 234 prefix, kill_mode_to_string(s->kill_mode),
b5a0699f
LP
235 prefix, s->socket_mode,
236 prefix, s->directory_mode);
542563ba 237
70123e68
LP
238 if (s->control_pid > 0)
239 fprintf(f,
240 "%sControl PID: %llu\n",
241 prefix, (unsigned long long) s->control_pid);
242
acbb0225
LP
243 if (s->bind_to_device)
244 fprintf(f,
245 "%sBindToDevice: %s\n",
246 prefix, s->bind_to_device);
247
4f2d528d
LP
248 if (s->accept)
249 fprintf(f,
250 "%sAccepted: %u\n",
251 prefix, s->n_accepted);
252
034c6ed7 253 LIST_FOREACH(port, p, s->ports) {
5cb5a6ff 254
542563ba
LP
255 if (p->type == SOCKET_SOCKET) {
256 const char *t;
257 int r;
258 char *k;
259
260 if ((r = socket_address_print(&p->address, &k)) < 0)
261 t = strerror(-r);
262 else
263 t = k;
264
265 fprintf(f, "%s%s: %s\n", prefix, listen_lookup(p->address.type), k);
266 free(k);
267 } else
268 fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
269 }
5cb5a6ff
LP
270
271 exec_context_dump(&s->exec_context, f, prefix);
272
e537352b 273 for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
c43d20a0
LP
274 if (!s->exec_command[c])
275 continue;
5cb5a6ff 276
c43d20a0
LP
277 fprintf(f, "%s→ %s:\n",
278 prefix, command_table[c]);
279
280 exec_command_dump_list(s->exec_command[c], f, prefix2);
5cb5a6ff 281 }
c43d20a0 282
82ba9f08 283 free(p2);
5cb5a6ff
LP
284}
285
4f2d528d
LP
286static int instance_from_socket(int fd, unsigned nr, char **instance) {
287 socklen_t l;
288 char *r;
289 union {
290 struct sockaddr sa;
291 struct sockaddr_un un;
292 struct sockaddr_in in;
293 struct sockaddr_in6 in6;
294 struct sockaddr_storage storage;
295 } local, remote;
296
297 assert(fd >= 0);
298 assert(instance);
299
300 l = sizeof(local);
301 if (getsockname(fd, &local.sa, &l) < 0)
302 return -errno;
303
304 l = sizeof(remote);
305 if (getpeername(fd, &remote.sa, &l) < 0)
306 return -errno;
307
308 switch (local.sa.sa_family) {
309
310 case AF_INET: {
311 uint32_t
312 a = ntohl(local.in.sin_addr.s_addr),
313 b = ntohl(remote.in.sin_addr.s_addr);
314
315 if (asprintf(&r,
316 "%u-%u.%u.%u.%u-%u-%u.%u.%u.%u-%u",
317 nr,
318 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
319 ntohs(local.in.sin_port),
320 b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
321 ntohs(remote.in.sin_port)) < 0)
322 return -ENOMEM;
323
324 break;
325 }
326
327 case AF_INET6: {
328 char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
329
330 if (asprintf(&r,
331 "%u-%s-%u-%s-%u",
332 nr,
333 inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
334 ntohs(local.in6.sin6_port),
335 inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
336 ntohs(remote.in6.sin6_port)) < 0)
337 return -ENOMEM;
338
339 break;
340 }
341
342 case AF_UNIX: {
343 struct ucred ucred;
344
345 l = sizeof(ucred);
346 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
347 return -errno;
348
349 if (asprintf(&r,
350 "%u-%llu-%llu",
351 nr,
352 (unsigned long long) ucred.pid,
353 (unsigned long long) ucred.uid) < 0)
354 return -ENOMEM;
355
356 break;
357 }
358
359 default:
360 assert_not_reached("Unhandled socket type.");
361 }
362
363 *instance = r;
364 return 0;
365}
366
034c6ed7 367static void socket_close_fds(Socket *s) {
83c60c9f
LP
368 SocketPort *p;
369
370 assert(s);
371
034c6ed7 372 LIST_FOREACH(port, p, s->ports) {
83c60c9f
LP
373 if (p->fd < 0)
374 continue;
375
acbb0225 376 unit_unwatch_fd(UNIT(s), &p->fd_watch);
9152c765
LP
377 assert_se(close_nointr(p->fd) >= 0);
378
83c60c9f
LP
379 p->fd = -1;
380 }
381}
382
034c6ed7 383static int socket_open_fds(Socket *s) {
83c60c9f
LP
384 SocketPort *p;
385 int r;
386
387 assert(s);
388
034c6ed7 389 LIST_FOREACH(port, p, s->ports) {
83c60c9f 390
034c6ed7
LP
391 if (p->fd >= 0)
392 continue;
83c60c9f
LP
393
394 if (p->type == SOCKET_SOCKET) {
395
b5a0699f
LP
396 if ((r = socket_address_listen(
397 &p->address,
398 s->backlog,
399 s->bind_ipv6_only,
400 s->bind_to_device,
401 s->directory_mode,
402 s->socket_mode,
403 &p->fd)) < 0)
83c60c9f
LP
404 goto rollback;
405
406 } else {
407 struct stat st;
408 assert(p->type == SOCKET_FIFO);
409
8cb45bf8
LP
410 mkdir_parents(p->path, s->directory_mode);
411
412 if (mkfifo(p->path, s->socket_mode) < 0 && errno != EEXIST) {
83c60c9f
LP
413 r = -errno;
414 goto rollback;
415 }
416
417 if ((p->fd = open(p->path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
418 r = -errno;
419 goto rollback;
420 }
421
422 if (fstat(p->fd, &st) < 0) {
423 r = -errno;
424 goto rollback;
425 }
426
427 /* FIXME verify user, access mode */
428
429 if (!S_ISFIFO(st.st_mode)) {
430 r = -EEXIST;
431 goto rollback;
432 }
433 }
034c6ed7
LP
434 }
435
436 return 0;
437
438rollback:
439 socket_close_fds(s);
440 return r;
441}
442
443static void socket_unwatch_fds(Socket *s) {
444 SocketPort *p;
9152c765 445
034c6ed7
LP
446 assert(s);
447
448 LIST_FOREACH(port, p, s->ports) {
449 if (p->fd < 0)
450 continue;
451
acbb0225 452 unit_unwatch_fd(UNIT(s), &p->fd_watch);
83c60c9f 453 }
034c6ed7
LP
454}
455
456static int socket_watch_fds(Socket *s) {
457 SocketPort *p;
458 int r;
459
460 assert(s);
83c60c9f 461
034c6ed7
LP
462 LIST_FOREACH(port, p, s->ports) {
463 if (p->fd < 0)
464 continue;
465
4f2d528d
LP
466 p->fd_watch.data.socket_accept =
467 s->accept &&
468 socket_address_can_accept(&p->address);
469
f94ea366 470 if ((r = unit_watch_fd(UNIT(s), p->fd, EPOLLIN, &p->fd_watch)) < 0)
034c6ed7
LP
471 goto fail;
472 }
83c60c9f 473
542563ba 474 return 0;
83c60c9f 475
034c6ed7
LP
476fail:
477 socket_unwatch_fds(s);
478 return r;
479}
480
481static void socket_set_state(Socket *s, SocketState state) {
482 SocketState old_state;
483 assert(s);
484
485 old_state = s->state;
486 s->state = state;
487
488 if (state != SOCKET_START_PRE &&
489 state != SOCKET_START_POST &&
490 state != SOCKET_STOP_PRE &&
491 state != SOCKET_STOP_PRE_SIGTERM &&
492 state != SOCKET_STOP_PRE_SIGKILL &&
493 state != SOCKET_STOP_POST &&
80876c20
LP
494 state != SOCKET_FINAL_SIGTERM &&
495 state != SOCKET_FINAL_SIGKILL) {
acbb0225 496 unit_unwatch_timer(UNIT(s), &s->timer_watch);
5e94833f 497 socket_unwatch_control_pid(s);
034c6ed7 498 s->control_command = NULL;
e537352b 499 }
034c6ed7
LP
500
501 if (state != SOCKET_START_POST &&
502 state != SOCKET_LISTENING &&
503 state != SOCKET_RUNNING &&
504 state != SOCKET_STOP_PRE &&
505 state != SOCKET_STOP_PRE_SIGTERM &&
506 state != SOCKET_STOP_PRE_SIGKILL)
507 socket_close_fds(s);
508
509 if (state != SOCKET_LISTENING)
510 socket_unwatch_fds(s);
511
e537352b 512 if (state != old_state)
9e2f7c11 513 log_debug("%s changed %s → %s", s->meta.id, state_string_table[old_state], state_string_table[state]);
acbb0225
LP
514
515 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]);
034c6ed7
LP
516}
517
e537352b 518static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
034c6ed7
LP
519 pid_t pid;
520 int r;
9e2f7c11 521 char **argv;
034c6ed7
LP
522
523 assert(s);
524 assert(c);
525 assert(_pid);
526
e537352b
LP
527 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
528 goto fail;
034c6ed7 529
9e2f7c11
LP
530 if (!(argv = unit_full_printf_strv(UNIT(s), c->argv))) {
531 r = -ENOMEM;
532 goto fail;
533 }
534
535 r = exec_spawn(c,
536 argv,
537 &s->exec_context,
538 NULL, 0,
539 true,
540 true,
541 UNIT(s)->meta.manager->confirm_spawn,
542 UNIT(s)->meta.cgroup_bondings,
543 &pid);
544
545 strv_free(argv);
546 if (r < 0)
034c6ed7
LP
547 goto fail;
548
87f0e418 549 if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
034c6ed7
LP
550 /* FIXME: we need to do something here */
551 goto fail;
83c60c9f 552
034c6ed7
LP
553 *_pid = pid;
554
555 return 0;
556
557fail:
e537352b 558 unit_unwatch_timer(UNIT(s), &s->timer_watch);
83c60c9f
LP
559
560 return r;
542563ba
LP
561}
562
034c6ed7
LP
563static void socket_enter_dead(Socket *s, bool success) {
564 assert(s);
565
566 if (!success)
567 s->failure = true;
568
569 socket_set_state(s, s->failure ? SOCKET_MAINTAINANCE : SOCKET_DEAD);
570}
571
80876c20
LP
572static void socket_enter_signal(Socket *s, SocketState state, bool success);
573
034c6ed7
LP
574static void socket_enter_stop_post(Socket *s, bool success) {
575 int r;
576 assert(s);
577
578 if (!success)
579 s->failure = true;
580
5e94833f
LP
581 socket_unwatch_control_pid(s);
582
80876c20 583 if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) {
e537352b 584 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
585 goto fail;
586
80876c20
LP
587 socket_set_state(s, SOCKET_STOP_POST);
588 } else
589 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, true);
034c6ed7
LP
590
591 return;
592
593fail:
9e2f7c11 594 log_warning("%s failed to run stop-post executable: %s", s->meta.id, strerror(-r));
80876c20 595 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, false);
034c6ed7
LP
596}
597
598static void socket_enter_signal(Socket *s, SocketState state, bool success) {
599 int r;
80876c20 600 bool sent = false;
034c6ed7
LP
601
602 assert(s);
603
604 if (!success)
605 s->failure = true;
606
80876c20
LP
607 if (s->kill_mode != KILL_NONE) {
608 int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? SIGTERM : SIGKILL;
034c6ed7 609
50159e6a
LP
610 if (s->kill_mode == KILL_CONTROL_GROUP) {
611
612 if ((r = cgroup_bonding_kill_list(UNIT(s)->meta.cgroup_bondings, sig)) < 0) {
613 if (r != -EAGAIN && r != -ESRCH)
614 goto fail;
615 } else
616 sent = true;
034c6ed7 617 }
50159e6a 618
80876c20 619 if (!sent && s->control_pid > 0)
50159e6a
LP
620 if (kill(s->kill_mode == KILL_PROCESS ? s->control_pid : -s->control_pid, sig) < 0 && errno != ESRCH) {
621 r = -errno;
622 goto fail;
623 }
d6ea93e3 624 }
034c6ed7 625
80876c20
LP
626 if (sent) {
627 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
628 goto fail;
d6ea93e3 629
80876c20
LP
630 socket_set_state(s, state);
631 } else if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
632 socket_enter_stop_post(s, true);
633 else
034c6ed7
LP
634 socket_enter_dead(s, true);
635
636 return;
637
638fail:
9e2f7c11 639 log_warning("%s failed to kill processes: %s", s->meta.id, strerror(-r));
034c6ed7
LP
640
641 if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
642 socket_enter_stop_post(s, false);
643 else
644 socket_enter_dead(s, false);
645}
646
647static void socket_enter_stop_pre(Socket *s, bool success) {
648 int r;
649 assert(s);
650
651 if (!success)
652 s->failure = true;
653
5e94833f
LP
654 socket_unwatch_control_pid(s);
655
80876c20 656 if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) {
e537352b 657 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
658 goto fail;
659
80876c20
LP
660 socket_set_state(s, SOCKET_STOP_PRE);
661 } else
034c6ed7
LP
662 socket_enter_stop_post(s, true);
663
664 return;
665
666fail:
9e2f7c11 667 log_warning("%s failed to run stop-pre executable: %s", s->meta.id, strerror(-r));
034c6ed7
LP
668 socket_enter_stop_post(s, false);
669}
670
e9af15c3
LP
671static void socket_enter_listening(Socket *s) {
672 int r;
673 assert(s);
674
675 if ((r = socket_watch_fds(s)) < 0) {
9e2f7c11 676 log_warning("%s failed to watch sockets: %s", s->meta.id, strerror(-r));
e9af15c3
LP
677 goto fail;
678 }
679
680 socket_set_state(s, SOCKET_LISTENING);
681 return;
682
683fail:
684 socket_enter_stop_pre(s, false);
685}
686
034c6ed7
LP
687static void socket_enter_start_post(Socket *s) {
688 int r;
689 assert(s);
690
e9af15c3 691 if ((r = socket_open_fds(s)) < 0) {
9e2f7c11 692 log_warning("%s failed to listen on sockets: %s", s->meta.id, strerror(-r));
034c6ed7
LP
693 goto fail;
694 }
695
5e94833f
LP
696 socket_unwatch_control_pid(s);
697
80876c20 698 if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
e537352b 699 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) {
9e2f7c11 700 log_warning("%s failed to run start-post executable: %s", s->meta.id, strerror(-r));
034c6ed7
LP
701 goto fail;
702 }
703
80876c20
LP
704 socket_set_state(s, SOCKET_START_POST);
705 } else
e9af15c3 706 socket_enter_listening(s);
034c6ed7
LP
707
708 return;
709
710fail:
711 socket_enter_stop_pre(s, false);
712}
713
714static void socket_enter_start_pre(Socket *s) {
715 int r;
716 assert(s);
717
5e94833f
LP
718 socket_unwatch_control_pid(s);
719
80876c20 720 if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) {
e537352b 721 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
722 goto fail;
723
80876c20
LP
724 socket_set_state(s, SOCKET_START_PRE);
725 } else
034c6ed7
LP
726 socket_enter_start_post(s);
727
728 return;
729
730fail:
9e2f7c11 731 log_warning("%s failed to run start-pre exectuable: %s", s->meta.id, strerror(-r));
034c6ed7
LP
732 socket_enter_dead(s, false);
733}
734
4f2d528d 735static void socket_enter_running(Socket *s, int cfd) {
034c6ed7
LP
736 int r;
737
738 assert(s);
739
4f2d528d
LP
740 if (cfd < 0) {
741 if ((r = manager_add_job(UNIT(s)->meta.manager, JOB_START, UNIT(s->service), JOB_REPLACE, true, NULL)) < 0)
742 goto fail;
743
744 socket_set_state(s, SOCKET_RUNNING);
745 } else {
746 Unit *u;
747 char *prefix, *instance, *name;
748
749 if ((r = instance_from_socket(cfd, s->n_accepted++, &instance)))
750 goto fail;
751
752 if (!(prefix = unit_name_to_prefix(UNIT(s)->meta.id))) {
753 free(instance);
754 r = -ENOMEM;
755 goto fail;
756 }
757
758 name = unit_name_build(prefix, instance, ".service");
759 free(prefix);
760 free(instance);
761
762 if (!name)
763 r = -ENOMEM;
764
765 r = manager_load_unit(UNIT(s)->meta.manager, name, NULL, &u);
766 free(name);
767
768 if (r < 0)
769 goto fail;
770
771 if ((r = service_set_socket_fd(SERVICE(u), cfd) < 0))
772 goto fail;
773
774 cfd = -1;
775
776 if ((r = manager_add_job(u->meta.manager, JOB_START, u, JOB_REPLACE, true, NULL)) < 0)
777 goto fail;
778 }
034c6ed7 779
034c6ed7
LP
780 return;
781
782fail:
9e2f7c11 783 log_warning("%s failed to queue socket startup job: %s", s->meta.id, strerror(-r));
80876c20 784 socket_enter_stop_pre(s, false);
4f2d528d
LP
785
786 if (cfd >= 0)
787 close_nointr_nofail(cfd);
034c6ed7
LP
788}
789
790static void socket_run_next(Socket *s, bool success) {
791 int r;
792
793 assert(s);
794 assert(s->control_command);
795 assert(s->control_command->command_next);
796
797 if (!success)
798 s->failure = true;
799
5e94833f
LP
800 socket_unwatch_control_pid(s);
801
034c6ed7
LP
802 s->control_command = s->control_command->command_next;
803
e537352b 804 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
805 goto fail;
806
807 return;
808
809fail:
9e2f7c11 810 log_warning("%s failed to run spawn next executable: %s", s->meta.id, strerror(-r));
80876c20
LP
811
812 if (s->state == SOCKET_START_POST)
813 socket_enter_stop_pre(s, false);
034c6ed7
LP
814 else if (s->state == SOCKET_STOP_POST)
815 socket_enter_dead(s, false);
816 else
80876c20 817 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, false);
034c6ed7
LP
818}
819
87f0e418
LP
820static int socket_start(Unit *u) {
821 Socket *s = SOCKET(u);
83c60c9f
LP
822
823 assert(s);
824
034c6ed7
LP
825 /* We cannot fulfill this request right now, try again later
826 * please! */
827 if (s->state == SOCKET_STOP_PRE ||
828 s->state == SOCKET_STOP_PRE_SIGKILL ||
829 s->state == SOCKET_STOP_PRE_SIGTERM ||
830 s->state == SOCKET_STOP_POST ||
80876c20
LP
831 s->state == SOCKET_FINAL_SIGTERM ||
832 s->state == SOCKET_FINAL_SIGKILL)
034c6ed7
LP
833 return -EAGAIN;
834
83c60c9f
LP
835 if (s->state == SOCKET_START_PRE ||
836 s->state == SOCKET_START_POST)
034c6ed7 837 return 0;
83c60c9f 838
034c6ed7 839 /* Cannot run this without the service being around */
4f2d528d
LP
840 if (s->service) {
841 if (s->service->meta.load_state != UNIT_LOADED)
842 return -ENOENT;
843
844 /* If the service is alredy actvie we cannot start the
845 * socket */
846 if (s->service->state != SERVICE_DEAD &&
847 s->service->state != SERVICE_MAINTAINANCE &&
848 s->service->state != SERVICE_AUTO_RESTART)
849 return -EBUSY;
850 }
e537352b 851
034c6ed7 852 assert(s->state == SOCKET_DEAD || s->state == SOCKET_MAINTAINANCE);
83c60c9f 853
034c6ed7
LP
854 s->failure = false;
855 socket_enter_start_pre(s);
856 return 0;
857}
83c60c9f 858
87f0e418
LP
859static int socket_stop(Unit *u) {
860 Socket *s = SOCKET(u);
034c6ed7
LP
861
862 assert(s);
863
864 /* We cannot fulfill this request right now, try again later
865 * please! */
866 if (s->state == SOCKET_START_PRE ||
867 s->state == SOCKET_START_POST)
868 return -EAGAIN;
83c60c9f 869
e537352b
LP
870 /* Already on it */
871 if (s->state == SOCKET_STOP_PRE ||
872 s->state == SOCKET_STOP_PRE_SIGTERM ||
873 s->state == SOCKET_STOP_PRE_SIGKILL ||
874 s->state == SOCKET_STOP_POST ||
80876c20
LP
875 s->state == SOCKET_FINAL_SIGTERM ||
876 s->state == SOCKET_FINAL_SIGTERM)
e537352b
LP
877 return 0;
878
034c6ed7 879 assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
83c60c9f 880
034c6ed7 881 socket_enter_stop_pre(s, true);
542563ba
LP
882 return 0;
883}
884
87f0e418
LP
885static UnitActiveState socket_active_state(Unit *u) {
886 assert(u);
5cb5a6ff 887
acbb0225 888 return state_translation_table[SOCKET(u)->state];
5cb5a6ff
LP
889}
890
10a94420
LP
891static const char *socket_sub_state_to_string(Unit *u) {
892 assert(u);
893
894 return state_string_table[SOCKET(u)->state];
895}
896
acbb0225 897static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
87f0e418 898 Socket *s = SOCKET(u);
4f2d528d 899 int cfd = -1;
9152c765 900
034c6ed7 901 assert(s);
9152c765 902
9e2f7c11 903 log_debug("Incoming traffic on %s", u->meta.id);
9152c765 904
4f2d528d
LP
905 if (events != EPOLLIN) {
906 log_error("Got invalid poll event on socket.");
034c6ed7 907 socket_enter_stop_pre(s, false);
4f2d528d
LP
908 return;
909 }
910
911 if (w->data.socket_accept) {
912 for (;;) {
913
914 if ((cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK)) < 0) {
915
916 if (errno == EINTR)
917 continue;
918
919 log_error("Failed to accept socket: %m");
920 socket_enter_stop_pre(s, false);
921 return;
922 }
923
924 break;
925 }
926 }
9152c765 927
4f2d528d 928 socket_enter_running(s, cfd);
9152c765
LP
929}
930
87f0e418
LP
931static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
932 Socket *s = SOCKET(u);
034c6ed7 933 bool success;
5cb5a6ff
LP
934
935 assert(s);
034c6ed7 936 assert(pid >= 0);
5cb5a6ff 937
bd982a8b 938 success = code == CLD_EXITED && status == 0;
034c6ed7 939 s->failure = s->failure || !success;
542563ba 940
034c6ed7
LP
941 assert(s->control_pid == pid);
942 assert(s->control_command);
943
944 exec_status_fill(&s->control_command->exec_status, pid, code, status);
945 s->control_pid = 0;
946
9e2f7c11 947 log_debug("%s control process exited, code=%s status=%i", u->meta.id, sigchld_code_to_string(code), status);
034c6ed7 948
80876c20 949 if (s->control_command->command_next && success) {
9e2f7c11 950 log_debug("%s running next command for state %s", u->meta.id, state_string_table[s->state]);
034c6ed7 951 socket_run_next(s, success);
acbb0225 952 } else {
034c6ed7
LP
953 /* No further commands for this step, so let's figure
954 * out what to do next */
5cb5a6ff 955
9e2f7c11 956 log_debug("%s got final SIGCHLD for state %s", u->meta.id, state_string_table[s->state]);
acbb0225 957
034c6ed7
LP
958 switch (s->state) {
959
960 case SOCKET_START_PRE:
961 if (success)
acbb0225 962 socket_enter_start_post(s);
034c6ed7 963 else
80876c20 964 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, false);
034c6ed7
LP
965 break;
966
967 case SOCKET_START_POST:
968 if (success)
e9af15c3 969 socket_enter_listening(s);
034c6ed7
LP
970 else
971 socket_enter_stop_pre(s, false);
972 break;
973
974 case SOCKET_STOP_PRE:
975 case SOCKET_STOP_PRE_SIGTERM:
976 case SOCKET_STOP_PRE_SIGKILL:
977 socket_enter_stop_post(s, success);
978 break;
979
980 case SOCKET_STOP_POST:
80876c20
LP
981 case SOCKET_FINAL_SIGTERM:
982 case SOCKET_FINAL_SIGKILL:
034c6ed7
LP
983 socket_enter_dead(s, success);
984 break;
985
986 default:
987 assert_not_reached("Uh, control process died at wrong time.");
988 }
989 }
990}
5cb5a6ff 991
acbb0225 992static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
87f0e418 993 Socket *s = SOCKET(u);
5cb5a6ff 994
034c6ed7
LP
995 assert(s);
996 assert(elapsed == 1);
acbb0225 997 assert(w == &s->timer_watch);
034c6ed7
LP
998
999 switch (s->state) {
1000
1001 case SOCKET_START_PRE:
9e2f7c11 1002 log_warning("%s starting timed out. Terminating.", u->meta.id);
80876c20
LP
1003 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, false);
1004
034c6ed7 1005 case SOCKET_START_POST:
9e2f7c11 1006 log_warning("%s starting timed out. Stopping.", u->meta.id);
034c6ed7
LP
1007 socket_enter_stop_pre(s, false);
1008 break;
1009
1010 case SOCKET_STOP_PRE:
9e2f7c11 1011 log_warning("%s stopping timed out. Terminating.", u->meta.id);
034c6ed7
LP
1012 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, false);
1013 break;
1014
1015 case SOCKET_STOP_PRE_SIGTERM:
9e2f7c11 1016 log_warning("%s stopping timed out. Killing.", u->meta.id);
034c6ed7
LP
1017 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
1018 break;
1019
1020 case SOCKET_STOP_PRE_SIGKILL:
9e2f7c11 1021 log_warning("%s still around after SIGKILL. Ignoring.", u->meta.id);
034c6ed7
LP
1022 socket_enter_stop_post(s, false);
1023 break;
1024
1025 case SOCKET_STOP_POST:
9e2f7c11 1026 log_warning("%s stopping timed out (2). Terminating.", u->meta.id);
80876c20 1027 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, false);
034c6ed7
LP
1028 break;
1029
80876c20 1030 case SOCKET_FINAL_SIGTERM:
9e2f7c11 1031 log_warning("%s stopping timed out (2). Killing.", u->meta.id);
80876c20 1032 socket_enter_signal(s, SOCKET_FINAL_SIGKILL, false);
034c6ed7
LP
1033 break;
1034
80876c20 1035 case SOCKET_FINAL_SIGKILL:
9e2f7c11 1036 log_warning("%s still around after SIGKILL (2). Entering maintainance mode.", u->meta.id);
034c6ed7
LP
1037 socket_enter_dead(s, false);
1038 break;
1039
1040 default:
1041 assert_not_reached("Timeout at wrong time.");
1042 }
5cb5a6ff
LP
1043}
1044
44d8db9e
LP
1045int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
1046 int *rfds;
1047 unsigned rn_fds, k;
1048 SocketPort *p;
1049
1050 assert(s);
1051 assert(fds);
1052 assert(n_fds);
1053
1054 /* Called from the service code for requesting our fds */
1055
1056 rn_fds = 0;
1057 LIST_FOREACH(port, p, s->ports)
1058 if (p->fd >= 0)
1059 rn_fds++;
1060
1061 if (!(rfds = new(int, rn_fds)) < 0)
1062 return -ENOMEM;
1063
1064 k = 0;
1065 LIST_FOREACH(port, p, s->ports)
1066 if (p->fd >= 0)
1067 rfds[k++] = p->fd;
1068
1069 assert(k == rn_fds);
1070
1071 *fds = rfds;
1072 *n_fds = rn_fds;
1073
1074 return 0;
1075}
1076
ceee3d82
LP
1077void socket_notify_service_dead(Socket *s) {
1078 assert(s);
1079
1080 /* The service is dead. Dang. */
1081
1082 if (s->state == SOCKET_RUNNING) {
9e2f7c11 1083 log_debug("%s got notified about service death.", s->meta.id);
ceee3d82
LP
1084 socket_enter_listening(s);
1085 }
1086}
1087
87f0e418 1088const UnitVTable socket_vtable = {
5cb5a6ff
LP
1089 .suffix = ".socket",
1090
034c6ed7 1091 .init = socket_init,
e537352b 1092 .load = socket_load,
034c6ed7
LP
1093 .done = socket_done,
1094
5cb5a6ff
LP
1095 .dump = socket_dump,
1096
542563ba
LP
1097 .start = socket_start,
1098 .stop = socket_stop,
5cb5a6ff
LP
1099
1100 .active_state = socket_active_state,
10a94420 1101 .sub_state_to_string = socket_sub_state_to_string,
5cb5a6ff 1102
9152c765 1103 .fd_event = socket_fd_event,
034c6ed7
LP
1104 .sigchld_event = socket_sigchld_event,
1105 .timer_event = socket_timer_event
5cb5a6ff 1106};