chiark / gitweb /
when shortcutting states do not skip state transitions
[elogind.git] / socket.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
2
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <sys/poll.h>
9 #include <signal.h>
10
11 #include "unit.h"
12 #include "socket.h"
13 #include "log.h"
14
15 static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
16         [SOCKET_DEAD] = UNIT_INACTIVE,
17         [SOCKET_START_PRE] = UNIT_ACTIVATING,
18         [SOCKET_START_POST] = UNIT_ACTIVATING,
19         [SOCKET_LISTENING] = UNIT_ACTIVE,
20         [SOCKET_RUNNING] = UNIT_ACTIVE,
21         [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
22         [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
23         [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
24         [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
25         [SOCKET_STOP_POST_SIGTERM] = UNIT_DEACTIVATING,
26         [SOCKET_STOP_POST_SIGKILL] = UNIT_DEACTIVATING,
27         [SOCKET_MAINTAINANCE] = UNIT_INACTIVE,
28 };
29
30 static const char* const state_string_table[_SOCKET_STATE_MAX] = {
31         [SOCKET_DEAD] = "dead",
32         [SOCKET_START_PRE] = "start-pre",
33         [SOCKET_START_POST] = "start-post",
34         [SOCKET_LISTENING] = "listening",
35         [SOCKET_RUNNING] = "running",
36         [SOCKET_STOP_PRE] = "stop-pre",
37         [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
38         [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
39         [SOCKET_STOP_POST] = "stop-post",
40         [SOCKET_STOP_POST_SIGTERM] = "stop-post-sigterm",
41         [SOCKET_STOP_POST_SIGKILL] = "stop-post-sigkill",
42         [SOCKET_MAINTAINANCE] = "maintainance"
43 };
44
45 static void socket_done(Unit *u) {
46         Socket *s = SOCKET(u);
47         SocketPort *p;
48
49         assert(s);
50
51         while ((p = s->ports)) {
52                 LIST_REMOVE(SocketPort, port, s->ports, p);
53
54                 if (p->fd >= 0)
55                         close_nointr(p->fd);
56                 free(p->path);
57                 free(p);
58         }
59
60         exec_context_done(&s->exec_context);
61         exec_command_free_array(s->exec_command, _SOCKET_EXEC_MAX);
62         s->control_command = NULL;
63
64         if (s->control_pid > 0) {
65                 unit_unwatch_pid(u, s->control_pid);
66                 s->control_pid = 0;
67         }
68
69         s->service = NULL;
70
71         free(s->bind_to_device);
72
73         unit_unwatch_timer(u, &s->timer_watch);
74 }
75
76 static int socket_init(Unit *u) {
77         Socket *s = SOCKET(u);
78         char *t;
79         int r;
80
81         /* First, reset everything to the defaults, in case this is a
82          * reload */
83
84         s->state = 0;
85         s->timer_watch.type = WATCH_INVALID;
86         s->bind_ipv6_only = false;
87         s->backlog = SOMAXCONN;
88         s->timeout_usec = DEFAULT_TIMEOUT_USEC;
89         exec_context_init(&s->exec_context);
90
91         if ((r = unit_load_fragment_and_dropin(u)) < 0)
92                 goto fail;
93
94         if (!(t = unit_name_change_suffix(unit_id(u), ".service"))) {
95                 r = -ENOMEM;
96                 goto fail;
97         }
98
99         r = manager_load_unit(u->meta.manager, t, (Unit**) &s->service);
100         free(t);
101
102         if (r < 0)
103                 goto fail;
104
105         if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service))) < 0)
106                 goto fail;
107
108         return 0;
109
110 fail:
111         socket_done(u);
112         return r;
113 }
114
115 static const char* listen_lookup(int type) {
116
117         if (type == SOCK_STREAM)
118                 return "ListenStream";
119         else if (type == SOCK_DGRAM)
120                 return "ListenDatagram";
121         else if (type == SOCK_SEQPACKET)
122                 return "ListenSequentialPacket";
123
124         assert_not_reached("Unknown socket type");
125         return NULL;
126 }
127
128 static void socket_dump(Unit *u, FILE *f, const char *prefix) {
129
130         static const char* const command_table[_SOCKET_EXEC_MAX] = {
131                 [SOCKET_EXEC_START_PRE] = "StartPre",
132                 [SOCKET_EXEC_START_POST] = "StartPost",
133                 [SOCKET_EXEC_STOP_PRE] = "StopPre",
134                 [SOCKET_EXEC_STOP_POST] = "StopPost"
135         };
136
137         SocketExecCommand c;
138         Socket *s = SOCKET(u);
139         SocketPort *p;
140         char *prefix2;
141
142         assert(s);
143         assert(f);
144
145         prefix2 = strappend(prefix, "\t");
146         if (!prefix2)
147                 prefix2 = "";
148
149         fprintf(f,
150                 "%sSocket State: %s\n"
151                 "%sBindIPv6Only: %s\n"
152                 "%sBacklog: %u\n",
153                 prefix, state_string_table[s->state],
154                 prefix, yes_no(s->bind_ipv6_only),
155                 prefix, s->backlog);
156
157         if (s->bind_to_device)
158                 fprintf(f,
159                         "%sBindToDevice: %s\n",
160                         prefix, s->bind_to_device);
161
162         LIST_FOREACH(port, p, s->ports) {
163
164                 if (p->type == SOCKET_SOCKET) {
165                         const char *t;
166                         int r;
167                         char *k;
168
169                         if ((r = socket_address_print(&p->address, &k)) < 0)
170                                 t = strerror(-r);
171                         else
172                                 t = k;
173
174                         fprintf(f, "%s%s: %s\n", prefix, listen_lookup(p->address.type), k);
175                         free(k);
176                 } else
177                         fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
178         }
179
180         exec_context_dump(&s->exec_context, f, prefix);
181
182         for (c = 0; c < _SOCKET_EXEC_MAX; c++) {
183                 if (!s->exec_command[c])
184                         continue;
185
186                 fprintf(f, "%s→ %s:\n",
187                         prefix, command_table[c]);
188
189                 exec_command_dump_list(s->exec_command[c], f, prefix2);
190         }
191
192         free(prefix2);
193 }
194
195 static void socket_close_fds(Socket *s) {
196         SocketPort *p;
197
198         assert(s);
199
200         LIST_FOREACH(port, p, s->ports) {
201                 if (p->fd < 0)
202                         continue;
203
204                 unit_unwatch_fd(UNIT(s), &p->fd_watch);
205                 assert_se(close_nointr(p->fd) >= 0);
206
207                 p->fd = -1;
208         }
209 }
210
211 static int socket_open_fds(Socket *s) {
212         SocketPort *p;
213         int r;
214
215         assert(s);
216
217         LIST_FOREACH(port, p, s->ports) {
218
219                 if (p->fd >= 0)
220                         continue;
221
222                 if (p->type == SOCKET_SOCKET) {
223
224                         if ((r = socket_address_listen(&p->address, s->backlog, s->bind_ipv6_only, s->bind_to_device, &p->fd)) < 0)
225                                 goto rollback;
226
227                 } else {
228                         struct stat st;
229                         assert(p->type == SOCKET_FIFO);
230
231                         if (mkfifo(p->path, 0666 & ~s->exec_context.umask) < 0 && errno != EEXIST) {
232                                 r = -errno;
233                                 goto rollback;
234                         }
235
236                         if ((p->fd = open(p->path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
237                                 r = -errno;
238                                 goto rollback;
239                         }
240
241                         if (fstat(p->fd, &st) < 0) {
242                                 r = -errno;
243                                 goto rollback;
244                         }
245
246                         /* FIXME verify user, access mode */
247
248                         if (!S_ISFIFO(st.st_mode)) {
249                                 r = -EEXIST;
250                                 goto rollback;
251                         }
252                 }
253         }
254
255         return 0;
256
257 rollback:
258         socket_close_fds(s);
259         return r;
260 }
261
262 static void socket_unwatch_fds(Socket *s) {
263         SocketPort *p;
264
265         assert(s);
266
267         LIST_FOREACH(port, p, s->ports) {
268                 if (p->fd < 0)
269                         continue;
270
271                 unit_unwatch_fd(UNIT(s), &p->fd_watch);
272         }
273 }
274
275 static int socket_watch_fds(Socket *s) {
276         SocketPort *p;
277         int r;
278
279         assert(s);
280
281         LIST_FOREACH(port, p, s->ports) {
282                 if (p->fd < 0)
283                         continue;
284
285                 if ((r = unit_watch_fd(UNIT(s), p->fd, POLLIN, &p->fd_watch)) < 0)
286                         goto fail;
287         }
288
289         return 0;
290
291 fail:
292         socket_unwatch_fds(s);
293         return r;
294 }
295
296 static void socket_set_state(Socket *s, SocketState state) {
297         SocketState old_state;
298         assert(s);
299
300         old_state = s->state;
301         s->state = state;
302
303         if (state != SOCKET_START_PRE &&
304             state != SOCKET_START_POST &&
305             state != SOCKET_STOP_PRE &&
306             state != SOCKET_STOP_PRE_SIGTERM &&
307             state != SOCKET_STOP_PRE_SIGKILL &&
308             state != SOCKET_STOP_POST &&
309             state != SOCKET_STOP_POST_SIGTERM &&
310             state != SOCKET_STOP_POST_SIGKILL)
311                 unit_unwatch_timer(UNIT(s), &s->timer_watch);
312
313         if (state != SOCKET_START_PRE &&
314             state != SOCKET_START_POST &&
315             state != SOCKET_STOP_PRE &&
316             state != SOCKET_STOP_PRE_SIGTERM &&
317             state != SOCKET_STOP_PRE_SIGKILL &&
318             state != SOCKET_STOP_POST &&
319             state != SOCKET_STOP_POST_SIGTERM &&
320             state != SOCKET_STOP_POST_SIGKILL)
321                 if (s->control_pid > 0) {
322                         unit_unwatch_pid(UNIT(s), s->control_pid);
323                         s->control_pid = 0;
324                 }
325
326         if (state != SOCKET_START_PRE &&
327             state != SOCKET_START_POST &&
328             state != SOCKET_STOP_PRE &&
329             state != SOCKET_STOP_POST)
330                 s->control_command = NULL;
331
332         if (state != SOCKET_START_POST &&
333             state != SOCKET_LISTENING &&
334             state != SOCKET_RUNNING &&
335             state != SOCKET_STOP_PRE &&
336             state != SOCKET_STOP_PRE_SIGTERM &&
337             state != SOCKET_STOP_PRE_SIGKILL)
338                 socket_close_fds(s);
339
340         if (state != SOCKET_LISTENING)
341                 socket_unwatch_fds(s);
342
343         log_debug("%s changed %s → %s", unit_id(UNIT(s)), state_string_table[old_state], state_string_table[state]);
344
345         unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]);
346 }
347
348 static int socket_spawn(Socket *s, ExecCommand *c, bool timeout, pid_t *_pid) {
349         pid_t pid;
350         int r;
351
352         assert(s);
353         assert(c);
354         assert(_pid);
355
356         if (timeout) {
357                 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
358                         goto fail;
359         } else
360                 unit_unwatch_timer(UNIT(s), &s->timer_watch);
361
362         if ((r = exec_spawn(c, &s->exec_context, NULL, 0, &pid)) < 0)
363                 goto fail;
364
365         if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
366                 /* FIXME: we need to do something here */
367                 goto fail;
368
369         *_pid = pid;
370
371         return 0;
372
373 fail:
374         if (timeout)
375                 unit_unwatch_timer(UNIT(s), &s->timer_watch);
376
377         return r;
378 }
379
380 static void socket_enter_dead(Socket *s, bool success) {
381         assert(s);
382
383         if (!success)
384                 s->failure = true;
385
386         socket_set_state(s, s->failure ? SOCKET_MAINTAINANCE : SOCKET_DEAD);
387 }
388
389 static void socket_enter_stop_post(Socket *s, bool success) {
390         int r;
391         assert(s);
392
393         if (!success)
394                 s->failure = true;
395
396         if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST]))
397                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
398                         goto fail;
399
400         socket_set_state(s, SOCKET_STOP_POST);
401
402         if (!s->control_command)
403                 socket_enter_dead(s, true);
404
405         return;
406
407 fail:
408         log_warning("%s failed to run stop-post executable: %s", unit_id(UNIT(s)), strerror(-r));
409         socket_enter_dead(s, false);
410 }
411
412 static void socket_enter_signal(Socket *s, SocketState state, bool success) {
413         int r;
414
415         assert(s);
416
417         if (!success)
418                 s->failure = true;
419
420         if (s->control_pid > 0) {
421                 int sig;
422
423                 sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_POST_SIGTERM) ? SIGTERM : SIGKILL;
424
425                 if (kill(s->control_pid, sig) < 0 && errno != ESRCH) {
426                         r = -errno;
427                         goto fail;
428                 }
429         }
430
431         socket_set_state(s, state);
432
433         if (s->control_pid <= 0)
434                 socket_enter_dead(s, true);
435
436         return;
437
438 fail:
439         log_warning("%s failed to kill processes: %s", unit_id(UNIT(s)), strerror(-r));
440
441         if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
442                 socket_enter_stop_post(s, false);
443         else
444                 socket_enter_dead(s, false);
445 }
446
447 static void socket_enter_stop_pre(Socket *s, bool success) {
448         int r;
449         assert(s);
450
451         if (!success)
452                 s->failure = true;
453
454         if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE]))
455                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
456                         goto fail;
457
458         socket_set_state(s, SOCKET_STOP_PRE);
459
460         if (!s->control_command)
461                 socket_enter_stop_post(s, true);
462
463         return;
464
465 fail:
466         log_warning("%s failed to run stop-pre executable: %s", unit_id(UNIT(s)), strerror(-r));
467         socket_enter_stop_post(s, false);
468 }
469
470 static void socket_enter_listening(Socket *s) {
471         int r;
472         assert(s);
473
474         if ((r = socket_watch_fds(s)) < 0) {
475                 log_warning("%s failed to watch sockets: %s", unit_id(UNIT(s)), strerror(-r));
476                 goto fail;
477         }
478
479         socket_set_state(s, SOCKET_LISTENING);
480         return;
481
482 fail:
483         socket_enter_stop_pre(s, false);
484 }
485
486 static void socket_enter_start_post(Socket *s) {
487         int r;
488         assert(s);
489
490         if ((r = socket_open_fds(s)) < 0) {
491                 log_warning("%s failed to listen on sockets: %s", unit_id(UNIT(s)), strerror(-r));
492                 goto fail;
493         }
494
495         if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST]))
496                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0) {
497                         log_warning("%s failed to run start-post executable: %s", unit_id(UNIT(s)), strerror(-r));
498                         goto fail;
499                 }
500
501         socket_set_state(s, SOCKET_START_POST);
502
503         if (!s->control_command)
504                 socket_enter_listening(s);
505
506         return;
507
508 fail:
509         socket_enter_stop_pre(s, false);
510 }
511
512 static void socket_enter_start_pre(Socket *s) {
513         int r;
514         assert(s);
515
516         if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE]))
517                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
518                         goto fail;
519
520         socket_set_state(s, SOCKET_START_PRE);
521
522         if (!s->control_command)
523                 socket_enter_start_post(s);
524
525         return;
526
527 fail:
528         log_warning("%s failed to run start-pre exectuable: %s", unit_id(UNIT(s)), strerror(-r));
529         socket_enter_dead(s, false);
530 }
531
532 static void socket_enter_running(Socket *s) {
533         int r;
534
535         assert(s);
536
537         if ((r = manager_add_job(UNIT(s)->meta.manager, JOB_START, UNIT(s->service), JOB_REPLACE, true, NULL)) < 0)
538                 goto fail;
539
540         socket_set_state(s, SOCKET_RUNNING);
541         return;
542
543 fail:
544         log_warning("%s failed to queue socket startup job: %s", unit_id(UNIT(s)), strerror(-r));
545         socket_enter_dead(s, false);
546 }
547
548 static void socket_run_next(Socket *s, bool success) {
549         int r;
550
551         assert(s);
552         assert(s->control_command);
553         assert(s->control_command->command_next);
554
555         if (!success)
556                 s->failure = true;
557
558         s->control_command = s->control_command->command_next;
559
560         if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
561                 goto fail;
562
563         return;
564
565 fail:
566         if (s->state == SOCKET_STOP_PRE)
567                 socket_enter_stop_post(s, false);
568         else if (s->state == SOCKET_STOP_POST)
569                 socket_enter_dead(s, false);
570         else
571                 socket_enter_stop_pre(s, false);
572 }
573
574 static int socket_start(Unit *u) {
575         Socket *s = SOCKET(u);
576
577         assert(s);
578
579         /* We cannot fulfill this request right now, try again later
580          * please! */
581         if (s->state == SOCKET_STOP_PRE ||
582             s->state == SOCKET_STOP_PRE_SIGKILL ||
583             s->state == SOCKET_STOP_PRE_SIGTERM ||
584             s->state == SOCKET_STOP_POST ||
585             s->state == SOCKET_STOP_POST_SIGTERM ||
586             s->state == SOCKET_STOP_POST_SIGKILL)
587                 return -EAGAIN;
588
589         if (s->state == SOCKET_START_PRE ||
590             s->state == SOCKET_START_POST)
591                 return 0;
592
593         /* Cannot run this without the service being around */
594         if (s->service->meta.load_state != UNIT_LOADED)
595                 return -ENOENT;
596
597         assert(s->state == SOCKET_DEAD || s->state == SOCKET_MAINTAINANCE);
598
599         s->failure = false;
600         socket_enter_start_pre(s);
601         return 0;
602 }
603
604 static int socket_stop(Unit *u) {
605         Socket *s = SOCKET(u);
606
607         assert(s);
608
609         /* We cannot fulfill this request right now, try again later
610          * please! */
611         if (s->state == SOCKET_START_PRE ||
612             s->state == SOCKET_START_POST)
613                 return -EAGAIN;
614
615         assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
616
617         socket_enter_stop_pre(s, true);
618         return 0;
619 }
620
621 static UnitActiveState socket_active_state(Unit *u) {
622         assert(u);
623
624         return state_translation_table[SOCKET(u)->state];
625 }
626
627 static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
628         Socket *s = SOCKET(u);
629
630         assert(s);
631
632         log_debug("Incoming traffic on %s", unit_id(u));
633
634         if (events != POLLIN)
635                 socket_enter_stop_pre(s, false);
636
637         socket_enter_running(s);
638 }
639
640 static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
641         Socket *s = SOCKET(u);
642         bool success;
643
644         assert(s);
645         assert(pid >= 0);
646
647         success = code == CLD_EXITED && status == 0;
648         s->failure = s->failure || !success;
649
650         assert(s->control_pid == pid);
651         assert(s->control_command);
652
653         exec_status_fill(&s->control_command->exec_status, pid, code, status);
654         s->control_pid = 0;
655
656         log_debug("%s control process exited, code=%s status=%i", unit_id(u), sigchld_code(code), status);
657
658         if (s->control_command->command_next &&
659             (success || (s->state == SOCKET_EXEC_STOP_PRE || s->state == SOCKET_EXEC_STOP_POST))) {
660                 log_debug("%s running next command for the state %s", unit_id(u), state_string_table[s->state]);
661                 socket_run_next(s, success);
662         } else {
663                 /* No further commands for this step, so let's figure
664                  * out what to do next */
665
666                 log_debug("%s got final SIGCHLD for state %s", unit_id(u), state_string_table[s->state]);
667
668                 switch (s->state) {
669
670                 case SOCKET_START_PRE:
671                         if (success)
672                                 socket_enter_start_post(s);
673                         else
674                                 socket_enter_stop_pre(s, false);
675                         break;
676
677                 case SOCKET_START_POST:
678                         if (success)
679                                 socket_enter_listening(s);
680                         else
681                                 socket_enter_stop_pre(s, false);
682                         break;
683
684                 case SOCKET_STOP_PRE:
685                 case SOCKET_STOP_PRE_SIGTERM:
686                 case SOCKET_STOP_PRE_SIGKILL:
687                         socket_enter_stop_post(s, success);
688                         break;
689
690                 case SOCKET_STOP_POST:
691                 case SOCKET_STOP_POST_SIGTERM:
692                 case SOCKET_STOP_POST_SIGKILL:
693                         socket_enter_dead(s, success);
694                         break;
695
696                 default:
697                         assert_not_reached("Uh, control process died at wrong time.");
698                 }
699         }
700 }
701
702 static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
703         Socket *s = SOCKET(u);
704
705         assert(s);
706         assert(elapsed == 1);
707
708         assert(w == &s->timer_watch);
709
710         switch (s->state) {
711
712         case SOCKET_START_PRE:
713         case SOCKET_START_POST:
714                 log_warning("%s operation timed out. Stopping.", unit_id(u));
715                 socket_enter_stop_pre(s, false);
716                 break;
717
718         case SOCKET_STOP_PRE:
719                 log_warning("%s stopping timed out. Terminating.", unit_id(u));
720                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, false);
721                 break;
722
723         case SOCKET_STOP_PRE_SIGTERM:
724                 log_warning("%s stopping timed out. Killing.", unit_id(u));
725                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
726                 break;
727
728         case SOCKET_STOP_PRE_SIGKILL:
729                 log_warning("%s still around after SIGKILL. Ignoring.", unit_id(u));
730                 socket_enter_stop_post(s, false);
731                 break;
732
733         case SOCKET_STOP_POST:
734                 log_warning("%s stopping timed out (2). Terminating.", unit_id(u));
735                 socket_enter_signal(s, SOCKET_STOP_POST_SIGTERM, false);
736                 break;
737
738         case SOCKET_STOP_POST_SIGTERM:
739                 log_warning("%s stopping timed out (2). Killing.", unit_id(u));
740                 socket_enter_signal(s, SOCKET_STOP_POST_SIGKILL, false);
741                 break;
742
743         case SOCKET_STOP_POST_SIGKILL:
744                 log_warning("%s still around after SIGKILL (2). Entering maintainance mode.", unit_id(u));
745                 socket_enter_dead(s, false);
746                 break;
747
748         default:
749                 assert_not_reached("Timeout at wrong time.");
750         }
751 }
752
753 int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
754         int *rfds;
755         unsigned rn_fds, k;
756         SocketPort *p;
757
758         assert(s);
759         assert(fds);
760         assert(n_fds);
761
762         /* Called from the service code for requesting our fds */
763
764         rn_fds = 0;
765         LIST_FOREACH(port, p, s->ports)
766                 if (p->fd >= 0)
767                         rn_fds++;
768
769         if (!(rfds = new(int, rn_fds)) < 0)
770                 return -ENOMEM;
771
772         k = 0;
773         LIST_FOREACH(port, p, s->ports)
774                 if (p->fd >= 0)
775                         rfds[k++] = p->fd;
776
777         assert(k == rn_fds);
778
779         *fds = rfds;
780         *n_fds = rn_fds;
781
782         return 0;
783 }
784
785 void socket_notify_service_dead(Socket *s) {
786         assert(s);
787
788         /* The service is dead. Dang. */
789
790         if (s->state == SOCKET_RUNNING) {
791                 log_debug("%s got notified about service death.", unit_id(UNIT(s)));
792                 socket_enter_listening(s);
793         }
794 }
795
796 const UnitVTable socket_vtable = {
797         .suffix = ".socket",
798
799         .init = socket_init,
800         .done = socket_done,
801
802         .dump = socket_dump,
803
804         .start = socket_start,
805         .stop = socket_stop,
806
807         .active_state = socket_active_state,
808
809         .fd_event = socket_fd_event,
810         .sigchld_event = socket_sigchld_event,
811         .timer_event = socket_timer_event
812 };