]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/socket.c
core: add global settings for enabling CPUAccounting=, MemoryAccounting=, BlockIOAcco...
[thirdparty/systemd.git] / src / core / socket.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5cb5a6ff 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
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
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
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
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>
718db961 30#include <netinet/tcp.h>
916abb21 31#include <mqueue.h>
b00ad20f 32#ifdef HAVE_XATTR
0eb59ccf 33#include <attr/xattr.h>
cf37cd2f 34#endif
83c60c9f 35
718db961 36#include "sd-event.h"
83c60c9f 37#include "log.h"
23a177ef
LP
38#include "load-dropin.h"
39#include "load-fragment.h"
9e2f7c11 40#include "strv.h"
49e942b2 41#include "mkdir.h"
9eb977db 42#include "path-util.h"
4f2d528d 43#include "unit-name.h"
41f9172f 44#include "unit-printf.h"
4fd5948e 45#include "missing.h"
a40eb732 46#include "special.h"
e51bc1a2 47#include "label.h"
9a57c629 48#include "exit-status.h"
f6a6225e 49#include "def.h"
5a045dad 50#include "smack-util.h"
718db961
LP
51#include "bus-util.h"
52#include "bus-error.h"
e821075a
LP
53#include "dbus-socket.h"
54#include "unit.h"
55#include "socket.h"
83c60c9f 56
acbb0225 57static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
87f0e418
LP
58 [SOCKET_DEAD] = UNIT_INACTIVE,
59 [SOCKET_START_PRE] = UNIT_ACTIVATING,
60 [SOCKET_START_POST] = UNIT_ACTIVATING,
61 [SOCKET_LISTENING] = UNIT_ACTIVE,
62 [SOCKET_RUNNING] = UNIT_ACTIVE,
63 [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
64 [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
65 [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
66 [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
80876c20
LP
67 [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING,
68 [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING,
fdf20a31 69 [SOCKET_FAILED] = UNIT_FAILED
83c60c9f 70};
5cb5a6ff 71
718db961
LP
72static int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
73static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
74
a16e1123
LP
75static void socket_init(Unit *u) {
76 Socket *s = SOCKET(u);
77
78 assert(u);
ac155bb8 79 assert(u->load_state == UNIT_STUB);
a16e1123 80
a16e1123 81 s->backlog = SOMAXCONN;
1f19a534 82 s->timeout_usec = u->manager->default_timeout_start_usec;
a16e1123 83 s->directory_mode = 0755;
9131f660 84 s->socket_mode = 0666;
a16e1123 85
6cf6bbc2
LP
86 s->max_connections = 64;
87
4fd5948e 88 s->priority = -1;
4fd5948e
LP
89 s->ip_tos = -1;
90 s->ip_ttl = -1;
4fd5948e 91 s->mark = -1;
4fd5948e 92
a16e1123 93 exec_context_init(&s->exec_context);
ac155bb8
MS
94 s->exec_context.std_output = u->manager->default_std_output;
95 s->exec_context.std_error = u->manager->default_std_error;
4819ff03 96 kill_context_init(&s->kill_context);
4ad49000 97 cgroup_context_init(&s->cgroup_context);
a16e1123 98
085afe36
LP
99 unit_cgroup_context_init_defaults(u, &s->cgroup_context);
100
a16e1123
LP
101 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
102}
acbb0225 103
5e94833f
LP
104static void socket_unwatch_control_pid(Socket *s) {
105 assert(s);
106
107 if (s->control_pid <= 0)
108 return;
109
110 unit_unwatch_pid(UNIT(s), s->control_pid);
111 s->control_pid = 0;
112}
113
74051b9b 114void socket_free_ports(Socket *s) {
034c6ed7
LP
115 SocketPort *p;
116
117 assert(s);
118
119 while ((p = s->ports)) {
71fda00f 120 LIST_REMOVE(port, s->ports, p);
034c6ed7 121
718db961
LP
122 sd_event_source_unref(p->event_source);
123
124 if (p->fd >= 0)
a16e1123 125 close_nointr_nofail(p->fd);
a16e1123 126
034c6ed7
LP
127 free(p->path);
128 free(p);
129 }
74051b9b
LP
130}
131
132static void socket_done(Unit *u) {
133 Socket *s = SOCKET(u);
134
135 assert(s);
136
137 socket_free_ports(s);
034c6ed7 138
613b411c
LP
139 cgroup_context_done(&s->cgroup_context);
140 exec_context_done(&s->exec_context);
141 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
e537352b 142 exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
034c6ed7
LP
143 s->control_command = NULL;
144
5e94833f 145 socket_unwatch_control_pid(s);
034c6ed7 146
57020a3a 147 unit_ref_unset(&s->service);
034c6ed7 148
cebf8b20
TT
149 free(s->tcp_congestion);
150 s->tcp_congestion = NULL;
151
acbb0225 152 free(s->bind_to_device);
e537352b 153 s->bind_to_device = NULL;
acbb0225 154
0eb59ccf
AK
155 free(s->smack);
156 free(s->smack_ip_in);
157 free(s->smack_ip_out);
158
718db961
LP
159 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
160}
161
162static int socket_arm_timer(Socket *s) {
163 int r;
164
165 assert(s);
166
167 if (s->timeout_usec <= 0) {
168 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
169 return 0;
170 }
171
172 if (s->timer_event_source) {
173 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
174 if (r < 0)
175 return r;
176
177 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
178 }
179
151b9b96 180 return sd_event_add_monotonic(UNIT(s)->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec, 0, socket_dispatch_timer, s);
5cb5a6ff
LP
181}
182
b15bdda8 183static int socket_instantiate_service(Socket *s) {
6c833cdf
MS
184 _cleanup_free_ char *prefix = NULL;
185 _cleanup_free_ char *name = NULL;
b15bdda8
LP
186 int r;
187 Unit *u;
188
189 assert(s);
190
191 /* This fills in s->service if it isn't filled in yet. For
192 * Accept=yes sockets we create the next connection service
193 * here. For Accept=no this is mostly a NOP since the service
194 * is figured out at load time anyway. */
195
57020a3a 196 if (UNIT_DEREF(s->service))
b15bdda8
LP
197 return 0;
198
199 assert(s->accept);
200
1124fe6f 201 if (!(prefix = unit_name_to_prefix(UNIT(s)->id)))
b15bdda8
LP
202 return -ENOMEM;
203
204 r = asprintf(&name, "%s@%u.service", prefix, s->n_accepted);
b15bdda8
LP
205
206 if (r < 0)
207 return -ENOMEM;
208
1124fe6f 209 r = manager_load_unit(UNIT(s)->manager, name, NULL, NULL, &u);
b15bdda8
LP
210
211 if (r < 0)
212 return r;
213
7b4bf06b 214#ifdef HAVE_SYSV_COMPAT
1b64d026 215 if (SERVICE(u)->is_sysv) {
7b4bf06b
LP
216 log_error("Using SysV services for socket activation is not supported. Refusing.");
217 return -ENOENT;
218 }
219#endif
220
ac155bb8 221 u->no_gc = true;
57020a3a
LP
222 unit_ref_set(&s->service, u);
223
224 return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
b15bdda8
LP
225}
226
4f2d528d
LP
227static bool have_non_accept_socket(Socket *s) {
228 SocketPort *p;
229
230 assert(s);
231
232 if (!s->accept)
233 return true;
234
dd5ad9d4
LP
235 LIST_FOREACH(port, p, s->ports) {
236
237 if (p->type != SOCKET_SOCKET)
238 return true;
239
4f2d528d
LP
240 if (!socket_address_can_accept(&p->address))
241 return true;
dd5ad9d4 242 }
4f2d528d
LP
243
244 return false;
245}
246
a57f7e2c 247static int socket_add_mount_links(Socket *s) {
6e2ef85b 248 SocketPort *p;
6e2ef85b
LP
249 int r;
250
251 assert(s);
6e2ef85b 252
a57f7e2c
LP
253 LIST_FOREACH(port, p, s->ports) {
254 const char *path = NULL;
6e2ef85b 255
a57f7e2c
LP
256 if (p->type == SOCKET_SOCKET)
257 path = socket_address_get_path(&p->address);
258 else if (p->type == SOCKET_FIFO || p->type == SOCKET_SPECIAL)
259 path = p->path;
6e2ef85b 260
a57f7e2c
LP
261 if (!path)
262 continue;
6e2ef85b 263
a57f7e2c 264 r = unit_require_mounts_for(UNIT(s), path);
b87705cd 265 if (r < 0)
6e2ef85b 266 return r;
b87705cd 267 }
6e2ef85b
LP
268
269 return 0;
270}
271
272static int socket_add_device_link(Socket *s) {
273 char *t;
6e2ef85b
LP
274
275 assert(s);
276
7d0c710d 277 if (!s->bind_to_device || streq(s->bind_to_device, "lo"))
6e2ef85b
LP
278 return 0;
279
e821075a
LP
280 t = strappenda("/sys/subsystem/net/devices/", s->bind_to_device);
281 return unit_add_node_link(UNIT(s), t, false);
6e2ef85b
LP
282}
283
a40eb732
LP
284static int socket_add_default_dependencies(Socket *s) {
285 int r;
286 assert(s);
287
e3d84721
LP
288 r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true);
289 if (r < 0)
290 return r;
2a77d31d 291
e3d84721
LP
292 if (UNIT(s)->manager->running_as == SYSTEMD_SYSTEM) {
293 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
294 if (r < 0)
a40eb732 295 return r;
2a77d31d 296 }
a40eb732 297
ead8e478 298 return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
a40eb732
LP
299}
300
44a6b1b6 301_pure_ static bool socket_has_exec(Socket *s) {
4cfc6dbe
LP
302 unsigned i;
303 assert(s);
304
305 for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
306 if (s->exec_command[i])
307 return true;
308
309 return false;
310}
311
e821075a
LP
312static int socket_add_extras(Socket *s) {
313 Unit *u = UNIT(s);
e537352b 314 int r;
44d8db9e 315
e821075a 316 assert(s);
57020a3a 317
e821075a 318 if (have_non_accept_socket(s)) {
23a177ef 319
e821075a
LP
320 if (!UNIT_DEREF(s->service)) {
321 Unit *x;
57020a3a 322
e821075a 323 r = unit_load_related_unit(u, ".service", &x);
57020a3a 324 if (r < 0)
4f2d528d 325 return r;
e821075a
LP
326
327 unit_ref_set(&s->service, x);
4f2d528d 328 }
44d8db9e 329
e821075a
LP
330 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true);
331 if (r < 0)
6e2ef85b 332 return r;
e821075a 333 }
6e2ef85b 334
e821075a
LP
335 r = socket_add_mount_links(s);
336 if (r < 0)
337 return r;
6e2ef85b 338
e821075a
LP
339 r = socket_add_device_link(s);
340 if (r < 0)
341 return r;
342
085afe36 343 r = unit_exec_context_patch_defaults(u, &s->exec_context);
e821075a
LP
344 if (r < 0)
345 return r;
346
347 if (socket_has_exec(s)) {
348 r = unit_add_exec_dependencies(u, &s->exec_context);
349 if (r < 0)
350 return r;
23a177ef 351
a016b922
LP
352 r = unit_add_default_slice(u);
353 if (r < 0)
354 return r;
e821075a 355 }
a016b922 356
e821075a
LP
357 if (u->default_dependencies) {
358 r = socket_add_default_dependencies(s);
359 if (r < 0)
360 return r;
361 }
362
363 return 0;
364}
365
366static int socket_verify(Socket *s) {
367 assert(s);
368
369 if (UNIT(s)->load_state != UNIT_LOADED)
370 return 0;
371
372 if (!s->ports) {
373 log_error_unit(UNIT(s)->id, "%s lacks Listen setting. Refusing.", UNIT(s)->id);
374 return -EINVAL;
375 }
376
377 if (s->accept && have_non_accept_socket(s)) {
378 log_error_unit(UNIT(s)->id, "%s configured for accepting sockets, but sockets are non-accepting. Refusing.",
379 UNIT(s)->id);
380 return -EINVAL;
381 }
382
383 if (s->accept && s->max_connections <= 0) {
384 log_error_unit(UNIT(s)->id, "%s's MaxConnection setting too small. Refusing.", UNIT(s)->id);
385 return -EINVAL;
386 }
e06c73cc 387
e821075a
LP
388 if (s->accept && UNIT_DEREF(s->service)) {
389 log_error_unit(UNIT(s)->id, "Explicit service configuration for accepting sockets not supported on %s. Refusing.", UNIT(s)->id);
390 return -EINVAL;
391 }
392
393 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
394 log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id);
395 return -EINVAL;
396 }
397
398 return 0;
399}
400
401static int socket_load(Unit *u) {
402 Socket *s = SOCKET(u);
403 int r;
404
405 assert(u);
406 assert(u->load_state == UNIT_STUB);
407
408 r = unit_load_fragment_and_dropin(u);
409 if (r < 0)
410 return r;
411
412 if (u->load_state == UNIT_LOADED) {
413 /* This is a new unit? Then let's add in some extras */
414 r = socket_add_extras(s);
e06c73cc
LP
415 if (r < 0)
416 return r;
23a177ef
LP
417 }
418
4f2d528d 419 return socket_verify(s);
44d8db9e
LP
420}
421
44a6b1b6 422_const_ static const char* listen_lookup(int family, int type) {
7a22745a
LP
423
424 if (family == AF_NETLINK)
425 return "ListenNetlink";
542563ba
LP
426
427 if (type == SOCK_STREAM)
428 return "ListenStream";
429 else if (type == SOCK_DGRAM)
430 return "ListenDatagram";
431 else if (type == SOCK_SEQPACKET)
432 return "ListenSequentialPacket";
433
034c6ed7 434 assert_not_reached("Unknown socket type");
542563ba
LP
435 return NULL;
436}
437
87f0e418 438static void socket_dump(Unit *u, FILE *f, const char *prefix) {
5cb5a6ff 439 SocketExecCommand c;
87f0e418 440 Socket *s = SOCKET(u);
542563ba 441 SocketPort *p;
82ba9f08 442 const char *prefix2;
5cb5a6ff
LP
443
444 assert(s);
fa068367 445 assert(f);
5cb5a6ff 446
e821075a 447 prefix2 = strappenda(prefix, "\t");
c43d20a0 448
5cb5a6ff
LP
449 fprintf(f,
450 "%sSocket State: %s\n"
81a5c6d0 451 "%sResult: %s\n"
542563ba 452 "%sBindIPv6Only: %s\n"
b5a0699f
LP
453 "%sBacklog: %u\n"
454 "%sSocketMode: %04o\n"
4fd5948e
LP
455 "%sDirectoryMode: %04o\n"
456 "%sKeepAlive: %s\n"
cebf8b20 457 "%sFreeBind: %s\n"
6b6d2dee 458 "%sTransparent: %s\n"
ec6370a2 459 "%sBroadcast: %s\n"
ede3deb4 460 "%sPassCredentials: %s\n"
54ecda32 461 "%sPassSecurity: %s\n"
cebf8b20 462 "%sTCPCongestion: %s\n",
a16e1123 463 prefix, socket_state_to_string(s->state),
81a5c6d0 464 prefix, socket_result_to_string(s->result),
c0120d99 465 prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
b5a0699f
LP
466 prefix, s->backlog,
467 prefix, s->socket_mode,
4fd5948e
LP
468 prefix, s->directory_mode,
469 prefix, yes_no(s->keep_alive),
cebf8b20 470 prefix, yes_no(s->free_bind),
6b6d2dee 471 prefix, yes_no(s->transparent),
ec6370a2 472 prefix, yes_no(s->broadcast),
d68af586 473 prefix, yes_no(s->pass_cred),
54ecda32 474 prefix, yes_no(s->pass_sec),
83a95334 475 prefix, strna(s->tcp_congestion));
542563ba 476
70123e68
LP
477 if (s->control_pid > 0)
478 fprintf(f,
bb00e604
LP
479 "%sControl PID: %lu\n",
480 prefix, (unsigned long) s->control_pid);
70123e68 481
acbb0225
LP
482 if (s->bind_to_device)
483 fprintf(f,
484 "%sBindToDevice: %s\n",
485 prefix, s->bind_to_device);
486
4f2d528d
LP
487 if (s->accept)
488 fprintf(f,
6cf6bbc2
LP
489 "%sAccepted: %u\n"
490 "%sNConnections: %u\n"
491 "%sMaxConnections: %u\n",
492 prefix, s->n_accepted,
493 prefix, s->n_connections,
494 prefix, s->max_connections);
4f2d528d 495
4fd5948e
LP
496 if (s->priority >= 0)
497 fprintf(f,
498 "%sPriority: %i\n",
499 prefix, s->priority);
500
501 if (s->receive_buffer > 0)
502 fprintf(f,
503 "%sReceiveBuffer: %zu\n",
504 prefix, s->receive_buffer);
505
506 if (s->send_buffer > 0)
507 fprintf(f,
508 "%sSendBuffer: %zu\n",
509 prefix, s->send_buffer);
510
511 if (s->ip_tos >= 0)
512 fprintf(f,
513 "%sIPTOS: %i\n",
514 prefix, s->ip_tos);
515
516 if (s->ip_ttl >= 0)
517 fprintf(f,
518 "%sIPTTL: %i\n",
519 prefix, s->ip_ttl);
520
521 if (s->pipe_size > 0)
522 fprintf(f,
523 "%sPipeSize: %zu\n",
524 prefix, s->pipe_size);
525
526 if (s->mark >= 0)
527 fprintf(f,
528 "%sMark: %i\n",
529 prefix, s->mark);
530
916abb21
LP
531 if (s->mq_maxmsg > 0)
532 fprintf(f,
533 "%sMessageQueueMaxMessages: %li\n",
534 prefix, s->mq_maxmsg);
535
536 if (s->mq_msgsize > 0)
537 fprintf(f,
538 "%sMessageQueueMessageSize: %li\n",
539 prefix, s->mq_msgsize);
540
718db961 541 if (s->reuse_port)
f7db7a69
SL
542 fprintf(f,
543 "%sReusePort: %s\n",
718db961 544 prefix, yes_no(s->reuse_port));
f7db7a69 545
0eb59ccf
AK
546 if (s->smack)
547 fprintf(f,
548 "%sSmackLabel: %s\n",
549 prefix, s->smack);
550
551 if (s->smack_ip_in)
552 fprintf(f,
553 "%sSmackLabelIPIn: %s\n",
554 prefix, s->smack_ip_in);
555
556 if (s->smack_ip_out)
557 fprintf(f,
558 "%sSmackLabelIPOut: %s\n",
559 prefix, s->smack_ip_out);
560
034c6ed7 561 LIST_FOREACH(port, p, s->ports) {
5cb5a6ff 562
542563ba
LP
563 if (p->type == SOCKET_SOCKET) {
564 const char *t;
565 int r;
e364ad06 566 char *k = NULL;
542563ba
LP
567
568 if ((r = socket_address_print(&p->address, &k)) < 0)
569 t = strerror(-r);
570 else
571 t = k;
572
7a22745a 573 fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t);
542563ba 574 free(k);
b0a3f2bc
LP
575 } else if (p->type == SOCKET_SPECIAL)
576 fprintf(f, "%sListenSpecial: %s\n", prefix, p->path);
916abb21
LP
577 else if (p->type == SOCKET_MQUEUE)
578 fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path);
b0a3f2bc 579 else
542563ba
LP
580 fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
581 }
5cb5a6ff
LP
582
583 exec_context_dump(&s->exec_context, f, prefix);
4819ff03 584 kill_context_dump(&s->kill_context, f, prefix);
5cb5a6ff 585
e537352b 586 for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
c43d20a0
LP
587 if (!s->exec_command[c])
588 continue;
5cb5a6ff 589
40d50879 590 fprintf(f, "%s-> %s:\n",
a16e1123 591 prefix, socket_exec_command_to_string(c));
c43d20a0
LP
592
593 exec_command_dump_list(s->exec_command[c], f, prefix2);
5cb5a6ff
LP
594 }
595}
596
4f2d528d
LP
597static int instance_from_socket(int fd, unsigned nr, char **instance) {
598 socklen_t l;
599 char *r;
600 union {
601 struct sockaddr sa;
602 struct sockaddr_un un;
603 struct sockaddr_in in;
604 struct sockaddr_in6 in6;
605 struct sockaddr_storage storage;
606 } local, remote;
607
608 assert(fd >= 0);
609 assert(instance);
610
611 l = sizeof(local);
612 if (getsockname(fd, &local.sa, &l) < 0)
613 return -errno;
614
615 l = sizeof(remote);
616 if (getpeername(fd, &remote.sa, &l) < 0)
617 return -errno;
618
619 switch (local.sa.sa_family) {
620
621 case AF_INET: {
622 uint32_t
623 a = ntohl(local.in.sin_addr.s_addr),
624 b = ntohl(remote.in.sin_addr.s_addr);
625
626 if (asprintf(&r,
77b088c2
LP
627 "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
628 nr,
4f2d528d
LP
629 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
630 ntohs(local.in.sin_port),
631 b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
632 ntohs(remote.in.sin_port)) < 0)
633 return -ENOMEM;
634
635 break;
636 }
637
638 case AF_INET6: {
c65a0b14 639 static const unsigned char ipv4_prefix[] = {
2b061f5a
LP
640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
641 };
642
643 if (memcmp(&local.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0 &&
644 memcmp(&remote.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
645 const uint8_t
646 *a = local.in6.sin6_addr.s6_addr+12,
647 *b = remote.in6.sin6_addr.s6_addr+12;
648
649 if (asprintf(&r,
77b088c2
LP
650 "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
651 nr,
2b061f5a
LP
652 a[0], a[1], a[2], a[3],
653 ntohs(local.in6.sin6_port),
654 b[0], b[1], b[2], b[3],
655 ntohs(remote.in6.sin6_port)) < 0)
656 return -ENOMEM;
657 } else {
658 char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
659
660 if (asprintf(&r,
77b088c2
LP
661 "%u-%s:%u-%s:%u",
662 nr,
2b061f5a
LP
663 inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
664 ntohs(local.in6.sin6_port),
665 inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
666 ntohs(remote.in6.sin6_port)) < 0)
667 return -ENOMEM;
668 }
4f2d528d
LP
669
670 break;
671 }
672
673 case AF_UNIX: {
674 struct ucred ucred;
eff05270 675 int k;
4f2d528d 676
eff05270
LP
677 k = getpeercred(fd, &ucred);
678 if (k < 0)
679 return k;
4f2d528d
LP
680
681 if (asprintf(&r,
bb00e604 682 "%u-%lu-%lu",
4f2d528d 683 nr,
bb00e604
LP
684 (unsigned long) ucred.pid,
685 (unsigned long) ucred.uid) < 0)
4f2d528d
LP
686 return -ENOMEM;
687
688 break;
689 }
690
691 default:
692 assert_not_reached("Unhandled socket type.");
693 }
694
695 *instance = r;
696 return 0;
697}
698
034c6ed7 699static void socket_close_fds(Socket *s) {
83c60c9f
LP
700 SocketPort *p;
701
702 assert(s);
703
034c6ed7 704 LIST_FOREACH(port, p, s->ports) {
718db961
LP
705
706 p->event_source = sd_event_source_unref(p->event_source);
707
83c60c9f
LP
708 if (p->fd < 0)
709 continue;
710
a16e1123
LP
711 close_nointr_nofail(p->fd);
712
713 /* One little note: we should never delete any sockets
714 * in the file system here! After all some other
715 * process we spawned might still have a reference of
716 * this fd and wants to continue to use it. Therefore
717 * we delete sockets in the file system before we
718 * create a new one, not after we stopped using
719 * one! */
9152c765 720
83c60c9f
LP
721 p->fd = -1;
722 }
723}
724
4fd5948e
LP
725static void socket_apply_socket_options(Socket *s, int fd) {
726 assert(s);
727 assert(fd >= 0);
728
729 if (s->keep_alive) {
730 int b = s->keep_alive;
731 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &b, sizeof(b)) < 0)
66870f90 732 log_warning_unit(UNIT(s)->id, "SO_KEEPALIVE failed: %m");
4fd5948e
LP
733 }
734
ec6370a2
LP
735 if (s->broadcast) {
736 int one = 1;
737 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
66870f90 738 log_warning_unit(UNIT(s)->id, "SO_BROADCAST failed: %m");
ec6370a2
LP
739 }
740
d68af586
MS
741 if (s->pass_cred) {
742 int one = 1;
743 if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
66870f90 744 log_warning_unit(UNIT(s)->id, "SO_PASSCRED failed: %m");
d68af586
MS
745 }
746
54ecda32
LP
747 if (s->pass_sec) {
748 int one = 1;
749 if (setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)) < 0)
66870f90 750 log_warning_unit(UNIT(s)->id, "SO_PASSSEC failed: %m");
54ecda32
LP
751 }
752
4fd5948e
LP
753 if (s->priority >= 0)
754 if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0)
66870f90 755 log_warning_unit(UNIT(s)->id, "SO_PRIORITY failed: %m");
4fd5948e
LP
756
757 if (s->receive_buffer > 0) {
758 int value = (int) s->receive_buffer;
7d9eaa84
LP
759
760 /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */
761
b8cef44e 762 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
7d9eaa84 763 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
66870f90 764 log_warning_unit(UNIT(s)->id, "SO_RCVBUF failed: %m");
4fd5948e
LP
765 }
766
767 if (s->send_buffer > 0) {
768 int value = (int) s->send_buffer;
b8cef44e 769 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
7d9eaa84 770 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
66870f90 771 log_warning_unit(UNIT(s)->id, "SO_SNDBUF failed: %m");
4fd5948e
LP
772 }
773
774 if (s->mark >= 0)
775 if (setsockopt(fd, SOL_SOCKET, SO_MARK, &s->mark, sizeof(s->mark)) < 0)
66870f90 776 log_warning_unit(UNIT(s)->id, "SO_MARK failed: %m");
4fd5948e
LP
777
778 if (s->ip_tos >= 0)
779 if (setsockopt(fd, IPPROTO_IP, IP_TOS, &s->ip_tos, sizeof(s->ip_tos)) < 0)
66870f90 780 log_warning_unit(UNIT(s)->id, "IP_TOS failed: %m");
4fd5948e 781
46925ac5
LP
782 if (s->ip_ttl >= 0) {
783 int r, x;
784
785 r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl));
5bfcc1c6
FF
786
787 if (socket_ipv6_is_supported())
788 x = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s->ip_ttl, sizeof(s->ip_ttl));
789 else {
790 x = -1;
791 errno = EAFNOSUPPORT;
792 }
46925ac5
LP
793
794 if (r < 0 && x < 0)
66870f90
ZJS
795 log_warning_unit(UNIT(s)->id,
796 "IP_TTL/IPV6_UNICAST_HOPS failed: %m");
46925ac5 797 }
cebf8b20
TT
798
799 if (s->tcp_congestion)
800 if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0)
66870f90 801 log_warning_unit(UNIT(s)->id, "TCP_CONGESTION failed: %m");
0eb59ccf 802
718db961
LP
803 if (s->reuse_port) {
804 int b = s->reuse_port;
f0511bd7 805 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &b, sizeof(b)) < 0)
f7db7a69
SL
806 log_warning_unit(UNIT(s)->id, "SO_REUSEPORT failed: %m");
807 }
808
9a4e038c
KS
809 if (s->smack_ip_in)
810 if (smack_label_ip_in_fd(fd, s->smack_ip_in) < 0)
811 log_error_unit(UNIT(s)->id, "smack_label_ip_in_fd: %m");
812
813 if (s->smack_ip_out)
814 if (smack_label_ip_out_fd(fd, s->smack_ip_out) < 0)
815 log_error_unit(UNIT(s)->id, "smack_label_ip_out_fd: %m");
4fd5948e
LP
816}
817
b15bdda8 818static void socket_apply_fifo_options(Socket *s, int fd) {
4fd5948e
LP
819 assert(s);
820 assert(fd >= 0);
821
822 if (s->pipe_size > 0)
823 if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0)
66870f90
ZJS
824 log_warning_unit(UNIT(s)->id,
825 "F_SETPIPE_SZ: %m");
0eb59ccf 826
9a4e038c
KS
827 if (s->smack)
828 if (smack_label_fd(fd, s->smack) < 0)
829 log_error_unit(UNIT(s)->id, "smack_label_fd: %m");
4fd5948e
LP
830}
831
b15bdda8
LP
832static int fifo_address_create(
833 const char *path,
834 mode_t directory_mode,
835 mode_t socket_mode,
b15bdda8
LP
836 int *_fd) {
837
7a58bfa4 838 int fd = -1, r = 0;
b15bdda8
LP
839 struct stat st;
840 mode_t old_mask;
841
842 assert(path);
843 assert(_fd);
844
d2e54fae 845 mkdir_parents_label(path, directory_mode);
b15bdda8 846
e9a5ef7c
KS
847 r = label_context_set(path, S_IFIFO);
848 if (r < 0)
56cf987f 849 goto fail;
b15bdda8
LP
850
851 /* Enforce the right access mode for the fifo */
852 old_mask = umask(~ socket_mode);
853
854 /* Include the original umask in our mask */
855 umask(~socket_mode | old_mask);
856
857 r = mkfifo(path, socket_mode);
858 umask(old_mask);
859
94bc2731 860 if (r < 0 && errno != EEXIST) {
b15bdda8
LP
861 r = -errno;
862 goto fail;
863 }
864
e4f44e73 865 if ((fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
b15bdda8
LP
866 r = -errno;
867 goto fail;
868 }
869
e9a5ef7c 870 label_context_clear();
7a58bfa4 871
b15bdda8
LP
872 if (fstat(fd, &st) < 0) {
873 r = -errno;
874 goto fail;
875 }
876
877 if (!S_ISFIFO(st.st_mode) ||
de0200fc 878 (st.st_mode & 0777) != (socket_mode & ~old_mask) ||
e4f44e73
DR
879 st.st_uid != getuid() ||
880 st.st_gid != getgid()) {
b15bdda8
LP
881
882 r = -EEXIST;
883 goto fail;
884 }
885
886 *_fd = fd;
887 return 0;
888
889fail:
e9a5ef7c 890 label_context_clear();
56cf987f 891
b15bdda8
LP
892 if (fd >= 0)
893 close_nointr_nofail(fd);
894
895 return r;
896}
897
b0a3f2bc
LP
898static int special_address_create(
899 const char *path,
900 int *_fd) {
901
902 int fd = -1, r = 0;
903 struct stat st;
904
905 assert(path);
906 assert(_fd);
907
908 if ((fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
909 r = -errno;
910 goto fail;
911 }
912
913 if (fstat(fd, &st) < 0) {
914 r = -errno;
915 goto fail;
916 }
917
918 /* Check whether this is a /proc, /sys or /dev file or char device */
919 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
920 r = -EEXIST;
921 goto fail;
922 }
923
924 *_fd = fd;
925 return 0;
926
927fail:
928 if (fd >= 0)
929 close_nointr_nofail(fd);
930
931 return r;
932}
933
916abb21
LP
934static int mq_address_create(
935 const char *path,
936 mode_t mq_mode,
937 long maxmsg,
938 long msgsize,
939 int *_fd) {
940
941 int fd = -1, r = 0;
942 struct stat st;
943 mode_t old_mask;
944 struct mq_attr _attr, *attr = NULL;
945
946 assert(path);
947 assert(_fd);
948
949 if (maxmsg > 0 && msgsize > 0) {
950 zero(_attr);
951 _attr.mq_flags = O_NONBLOCK;
952 _attr.mq_maxmsg = maxmsg;
953 _attr.mq_msgsize = msgsize;
954 attr = &_attr;
955 }
956
957 /* Enforce the right access mode for the mq */
958 old_mask = umask(~ mq_mode);
959
960 /* Include the original umask in our mask */
961 umask(~mq_mode | old_mask);
962
963 fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr);
964 umask(old_mask);
965
8ea913b2 966 if (fd < 0) {
916abb21
LP
967 r = -errno;
968 goto fail;
969 }
970
971 if (fstat(fd, &st) < 0) {
972 r = -errno;
973 goto fail;
974 }
975
976 if ((st.st_mode & 0777) != (mq_mode & ~old_mask) ||
977 st.st_uid != getuid() ||
978 st.st_gid != getgid()) {
979
980 r = -EEXIST;
981 goto fail;
982 }
983
984 *_fd = fd;
985 return 0;
986
987fail:
988 if (fd >= 0)
989 close_nointr_nofail(fd);
990
991 return r;
992}
993
034c6ed7 994static int socket_open_fds(Socket *s) {
83c60c9f
LP
995 SocketPort *p;
996 int r;
56cf987f 997 char *label = NULL;
049f8642 998 bool know_label = false;
83c60c9f
LP
999
1000 assert(s);
1001
034c6ed7 1002 LIST_FOREACH(port, p, s->ports) {
83c60c9f 1003
034c6ed7
LP
1004 if (p->fd >= 0)
1005 continue;
83c60c9f
LP
1006
1007 if (p->type == SOCKET_SOCKET) {
1008
049f8642
LP
1009 if (!know_label) {
1010
1011 if ((r = socket_instantiate_service(s)) < 0)
1012 return r;
1013
9444b1f2 1014 if (UNIT_ISSET(s->service) &&
57020a3a
LP
1015 SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
1016 r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
189583d7
LP
1017
1018 if (r < 0) {
a7444eda
LP
1019 if (r != -EPERM)
1020 return r;
1021 }
189583d7 1022 }
049f8642
LP
1023
1024 know_label = true;
1025 }
1026
175a3d25
LP
1027 r = socket_address_listen(
1028 &p->address,
1029 SOCK_CLOEXEC|SOCK_NONBLOCK,
1030 s->backlog,
1031 s->bind_ipv6_only,
1032 s->bind_to_device,
1033 s->free_bind,
1034 s->transparent,
1035 s->directory_mode,
1036 s->socket_mode,
1037 label);
1038 if (r < 0)
83c60c9f
LP
1039 goto rollback;
1040
175a3d25 1041 p->fd = r;
4fd5948e
LP
1042 socket_apply_socket_options(s, p->fd);
1043
b0a3f2bc
LP
1044 } else if (p->type == SOCKET_SPECIAL) {
1045
175a3d25
LP
1046 r = special_address_create(
1047 p->path,
1048 &p->fd);
1049 if (r < 0)
b0a3f2bc
LP
1050 goto rollback;
1051
b15bdda8 1052 } else if (p->type == SOCKET_FIFO) {
83c60c9f 1053
175a3d25
LP
1054 r = fifo_address_create(
1055 p->path,
1056 s->directory_mode,
1057 s->socket_mode,
1058 &p->fd);
1059 if (r < 0)
83c60c9f 1060 goto rollback;
83c60c9f 1061
b15bdda8 1062 socket_apply_fifo_options(s, p->fd);
916abb21 1063 } else if (p->type == SOCKET_MQUEUE) {
83c60c9f 1064
175a3d25
LP
1065 r = mq_address_create(
1066 p->path,
1067 s->socket_mode,
1068 s->mq_maxmsg,
1069 s->mq_msgsize,
1070 &p->fd);
1071 if (r < 0)
916abb21 1072 goto rollback;
b15bdda8
LP
1073 } else
1074 assert_not_reached("Unknown port type");
034c6ed7
LP
1075 }
1076
56cf987f 1077 label_free(label);
034c6ed7
LP
1078 return 0;
1079
1080rollback:
1081 socket_close_fds(s);
56cf987f 1082 label_free(label);
034c6ed7
LP
1083 return r;
1084}
1085
1086static void socket_unwatch_fds(Socket *s) {
1087 SocketPort *p;
718db961 1088 int r;
9152c765 1089
034c6ed7
LP
1090 assert(s);
1091
1092 LIST_FOREACH(port, p, s->ports) {
1093 if (p->fd < 0)
1094 continue;
1095
718db961
LP
1096 if (p->event_source) {
1097 r = sd_event_source_set_enabled(p->event_source, SD_EVENT_OFF);
1098 if (r < 0)
1099 log_debug_unit(UNIT(s)->id, "Failed to disable event source.");
1100 }
83c60c9f 1101 }
034c6ed7
LP
1102}
1103
1104static int socket_watch_fds(Socket *s) {
1105 SocketPort *p;
1106 int r;
1107
1108 assert(s);
83c60c9f 1109
034c6ed7
LP
1110 LIST_FOREACH(port, p, s->ports) {
1111 if (p->fd < 0)
1112 continue;
1113
718db961
LP
1114 if (p->event_source)
1115 r = sd_event_source_set_enabled(p->event_source, SD_EVENT_ON);
1116 else
151b9b96 1117 r = sd_event_add_io(UNIT(s)->manager->event, &p->event_source, p->fd, EPOLLIN, socket_dispatch_io, p);
4f2d528d 1118
718db961
LP
1119 if (r < 0) {
1120 log_warning_unit(UNIT(s)->id, "Failed to watch listening fds: %s", strerror(-r));
034c6ed7 1121 goto fail;
718db961 1122 }
034c6ed7 1123 }
83c60c9f 1124
542563ba 1125 return 0;
83c60c9f 1126
034c6ed7
LP
1127fail:
1128 socket_unwatch_fds(s);
1129 return r;
1130}
1131
1132static void socket_set_state(Socket *s, SocketState state) {
1133 SocketState old_state;
1134 assert(s);
1135
1136 old_state = s->state;
1137 s->state = state;
1138
1139 if (state != SOCKET_START_PRE &&
1140 state != SOCKET_START_POST &&
1141 state != SOCKET_STOP_PRE &&
1142 state != SOCKET_STOP_PRE_SIGTERM &&
1143 state != SOCKET_STOP_PRE_SIGKILL &&
1144 state != SOCKET_STOP_POST &&
80876c20
LP
1145 state != SOCKET_FINAL_SIGTERM &&
1146 state != SOCKET_FINAL_SIGKILL) {
718db961
LP
1147
1148 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
5e94833f 1149 socket_unwatch_control_pid(s);
034c6ed7 1150 s->control_command = NULL;
a16e1123 1151 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
e537352b 1152 }
034c6ed7 1153
a16e1123
LP
1154 if (state != SOCKET_LISTENING)
1155 socket_unwatch_fds(s);
1156
034c6ed7
LP
1157 if (state != SOCKET_START_POST &&
1158 state != SOCKET_LISTENING &&
1159 state != SOCKET_RUNNING &&
1160 state != SOCKET_STOP_PRE &&
1161 state != SOCKET_STOP_PRE_SIGTERM &&
1162 state != SOCKET_STOP_PRE_SIGKILL)
1163 socket_close_fds(s);
1164
e537352b 1165 if (state != old_state)
e821075a
LP
1166 log_debug_unit(UNIT(s)->id, "%s changed %s -> %s",
1167 UNIT(s)->id, socket_state_to_string(old_state), socket_state_to_string(state));
acbb0225 1168
e2f3b44c 1169 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
034c6ed7
LP
1170}
1171
a16e1123
LP
1172static int socket_coldplug(Unit *u) {
1173 Socket *s = SOCKET(u);
1174 int r;
1175
1176 assert(s);
1177 assert(s->state == SOCKET_DEAD);
1178
e821075a
LP
1179 if (s->deserialized_state == s->state)
1180 return 0;
a16e1123 1181
e821075a
LP
1182 if (s->deserialized_state == SOCKET_START_PRE ||
1183 s->deserialized_state == SOCKET_START_POST ||
1184 s->deserialized_state == SOCKET_STOP_PRE ||
1185 s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
1186 s->deserialized_state == SOCKET_STOP_PRE_SIGKILL ||
1187 s->deserialized_state == SOCKET_STOP_POST ||
1188 s->deserialized_state == SOCKET_FINAL_SIGTERM ||
1189 s->deserialized_state == SOCKET_FINAL_SIGKILL) {
a16e1123 1190
e821075a
LP
1191 if (s->control_pid <= 0)
1192 return -EBADMSG;
a16e1123 1193
e821075a
LP
1194 r = unit_watch_pid(UNIT(s), s->control_pid);
1195 if (r < 0)
1196 return r;
a16e1123 1197
e821075a
LP
1198 r = socket_arm_timer(s);
1199 if (r < 0)
1200 return r;
1201 }
a16e1123 1202
e821075a
LP
1203 if (s->deserialized_state == SOCKET_START_POST ||
1204 s->deserialized_state == SOCKET_LISTENING ||
1205 s->deserialized_state == SOCKET_RUNNING ||
1206 s->deserialized_state == SOCKET_STOP_PRE ||
1207 s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
1208 s->deserialized_state == SOCKET_STOP_PRE_SIGKILL) {
1209 r = socket_open_fds(s);
1210 if (r < 0)
1211 return r;
1212 }
a16e1123 1213
e821075a
LP
1214 if (s->deserialized_state == SOCKET_LISTENING) {
1215 r = socket_watch_fds(s);
1216 if (r < 0)
1217 return r;
a16e1123
LP
1218 }
1219
e821075a 1220 socket_set_state(s, s->deserialized_state);
a16e1123
LP
1221 return 0;
1222}
1223
e537352b 1224static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
034c6ed7
LP
1225 pid_t pid;
1226 int r;
9e2f7c11 1227 char **argv;
034c6ed7
LP
1228
1229 assert(s);
1230 assert(c);
1231 assert(_pid);
1232
4ad49000
LP
1233 unit_realize_cgroup(UNIT(s));
1234
613b411c
LP
1235 r = unit_setup_exec_runtime(UNIT(s));
1236 if (r < 0)
1237 goto fail;
1238
718db961 1239 r = socket_arm_timer(s);
36697dc0 1240 if (r < 0)
e537352b 1241 goto fail;
034c6ed7 1242
19f6d710
LP
1243 r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
1244 if (r < 0)
9e2f7c11 1245 goto fail;
9e2f7c11
LP
1246
1247 r = exec_spawn(c,
1248 argv,
1249 &s->exec_context,
1250 NULL, 0,
1124fe6f 1251 UNIT(s)->manager->environment,
9e2f7c11
LP
1252 true,
1253 true,
1e3ad081 1254 true,
1124fe6f 1255 UNIT(s)->manager->confirm_spawn,
13b84ec7 1256 UNIT(s)->manager->cgroup_supported,
4ad49000 1257 UNIT(s)->cgroup_path,
62bca2c6 1258 UNIT(s)->id,
09812eb7 1259 0,
f2b68789 1260 NULL,
613b411c 1261 s->exec_runtime,
9e2f7c11
LP
1262 &pid);
1263
1264 strv_free(argv);
1265 if (r < 0)
034c6ed7
LP
1266 goto fail;
1267
718db961
LP
1268 r = unit_watch_pid(UNIT(s), pid);
1269 if (r < 0)
034c6ed7
LP
1270 /* FIXME: we need to do something here */
1271 goto fail;
83c60c9f 1272
034c6ed7
LP
1273 *_pid = pid;
1274
1275 return 0;
1276
1277fail:
718db961 1278 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
83c60c9f
LP
1279
1280 return r;
542563ba
LP
1281}
1282
cfc4eb4c 1283static void socket_enter_dead(Socket *s, SocketResult f) {
034c6ed7
LP
1284 assert(s);
1285
cfc4eb4c
LP
1286 if (f != SOCKET_SUCCESS)
1287 s->result = f;
034c6ed7 1288
613b411c
LP
1289 exec_runtime_destroy(s->exec_runtime);
1290 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
1291
cfc4eb4c 1292 socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD);
034c6ed7
LP
1293}
1294
cfc4eb4c 1295static void socket_enter_signal(Socket *s, SocketState state, SocketResult f);
80876c20 1296
cfc4eb4c 1297static void socket_enter_stop_post(Socket *s, SocketResult f) {
034c6ed7
LP
1298 int r;
1299 assert(s);
1300
cfc4eb4c
LP
1301 if (f != SOCKET_SUCCESS)
1302 s->result = f;
034c6ed7 1303
5e94833f
LP
1304 socket_unwatch_control_pid(s);
1305
a16e1123
LP
1306 s->control_command_id = SOCKET_EXEC_STOP_POST;
1307
80876c20 1308 if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) {
e537352b 1309 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1310 goto fail;
1311
80876c20
LP
1312 socket_set_state(s, SOCKET_STOP_POST);
1313 } else
cfc4eb4c 1314 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS);
034c6ed7
LP
1315
1316 return;
1317
1318fail:
66870f90
ZJS
1319 log_warning_unit(UNIT(s)->id,
1320 "%s failed to run 'stop-post' task: %s",
1321 UNIT(s)->id, strerror(-r));
cfc4eb4c 1322 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1323}
1324
cfc4eb4c 1325static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) {
034c6ed7
LP
1326 int r;
1327
1328 assert(s);
1329
cfc4eb4c
LP
1330 if (f != SOCKET_SUCCESS)
1331 s->result = f;
034c6ed7 1332
cd2086fe
LP
1333 r = unit_kill_context(
1334 UNIT(s),
1335 &s->kill_context,
1336 state != SOCKET_STOP_PRE_SIGTERM && state != SOCKET_FINAL_SIGTERM,
1337 -1,
1338 s->control_pid,
1339 false);
1340 if (r < 0)
1341 goto fail;
034c6ed7 1342
cd2086fe 1343 if (r > 0) {
718db961 1344 r = socket_arm_timer(s);
36697dc0 1345 if (r < 0)
80876c20 1346 goto fail;
d6ea93e3 1347
80876c20 1348 socket_set_state(s, state);
ac84d1fb
LP
1349 } else if (state == SOCKET_STOP_PRE_SIGTERM)
1350 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_SUCCESS);
1351 else if (state == SOCKET_STOP_PRE_SIGKILL)
cfc4eb4c 1352 socket_enter_stop_post(s, SOCKET_SUCCESS);
ac84d1fb
LP
1353 else if (state == SOCKET_FINAL_SIGTERM)
1354 socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_SUCCESS);
80876c20 1355 else
cfc4eb4c 1356 socket_enter_dead(s, SOCKET_SUCCESS);
034c6ed7
LP
1357
1358 return;
1359
1360fail:
e821075a 1361 log_warning_unit(UNIT(s)->id, "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
034c6ed7
LP
1362
1363 if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
cfc4eb4c 1364 socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
034c6ed7 1365 else
cfc4eb4c 1366 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1367}
1368
cfc4eb4c 1369static void socket_enter_stop_pre(Socket *s, SocketResult f) {
034c6ed7
LP
1370 int r;
1371 assert(s);
1372
cfc4eb4c
LP
1373 if (f != SOCKET_SUCCESS)
1374 s->result = f;
034c6ed7 1375
5e94833f
LP
1376 socket_unwatch_control_pid(s);
1377
a16e1123
LP
1378 s->control_command_id = SOCKET_EXEC_STOP_PRE;
1379
80876c20 1380 if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) {
e537352b 1381 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1382 goto fail;
1383
80876c20
LP
1384 socket_set_state(s, SOCKET_STOP_PRE);
1385 } else
cfc4eb4c 1386 socket_enter_stop_post(s, SOCKET_SUCCESS);
034c6ed7
LP
1387
1388 return;
1389
1390fail:
e821075a 1391 log_warning_unit(UNIT(s)->id, "%s failed to run 'stop-pre' task: %s", UNIT(s)->id, strerror(-r));
cfc4eb4c 1392 socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1393}
1394
e9af15c3
LP
1395static void socket_enter_listening(Socket *s) {
1396 int r;
1397 assert(s);
1398
cfc4eb4c
LP
1399 r = socket_watch_fds(s);
1400 if (r < 0) {
e821075a 1401 log_warning_unit(UNIT(s)->id, "%s failed to watch sockets: %s", UNIT(s)->id, strerror(-r));
e9af15c3
LP
1402 goto fail;
1403 }
1404
1405 socket_set_state(s, SOCKET_LISTENING);
1406 return;
1407
1408fail:
cfc4eb4c 1409 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
e9af15c3
LP
1410}
1411
034c6ed7
LP
1412static void socket_enter_start_post(Socket *s) {
1413 int r;
1414 assert(s);
1415
cfc4eb4c
LP
1416 r = socket_open_fds(s);
1417 if (r < 0) {
e821075a 1418 log_warning_unit(UNIT(s)->id, "%s failed to listen on sockets: %s", UNIT(s)->id, strerror(-r));
034c6ed7
LP
1419 goto fail;
1420 }
1421
5e94833f
LP
1422 socket_unwatch_control_pid(s);
1423
a16e1123
LP
1424 s->control_command_id = SOCKET_EXEC_START_POST;
1425
80876c20 1426 if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
cfc4eb4c
LP
1427 r = socket_spawn(s, s->control_command, &s->control_pid);
1428 if (r < 0) {
e821075a 1429 log_warning_unit(UNIT(s)->id, "%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r));
034c6ed7
LP
1430 goto fail;
1431 }
1432
80876c20
LP
1433 socket_set_state(s, SOCKET_START_POST);
1434 } else
e9af15c3 1435 socket_enter_listening(s);
034c6ed7
LP
1436
1437 return;
1438
1439fail:
cfc4eb4c 1440 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1441}
1442
1443static void socket_enter_start_pre(Socket *s) {
1444 int r;
1445 assert(s);
1446
5e94833f
LP
1447 socket_unwatch_control_pid(s);
1448
a16e1123
LP
1449 s->control_command_id = SOCKET_EXEC_START_PRE;
1450
80876c20 1451 if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) {
e821075a
LP
1452 r = socket_spawn(s, s->control_command, &s->control_pid);
1453 if (r < 0)
034c6ed7
LP
1454 goto fail;
1455
80876c20
LP
1456 socket_set_state(s, SOCKET_START_PRE);
1457 } else
034c6ed7
LP
1458 socket_enter_start_post(s);
1459
1460 return;
1461
1462fail:
e821075a 1463 log_warning_unit(UNIT(s)->id, "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r));
cfc4eb4c 1464 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1465}
1466
4f2d528d 1467static void socket_enter_running(Socket *s, int cfd) {
718db961 1468 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
034c6ed7
LP
1469 int r;
1470
1471 assert(s);
1472
ba3e67a7
LP
1473 /* We don't take connections anymore if we are supposed to
1474 * shut down anyway */
31afa0a4 1475 if (unit_stop_pending(UNIT(s))) {
e821075a
LP
1476
1477 log_debug_unit(UNIT(s)->id, "Suppressing connection request on %s since unit stop is scheduled.", UNIT(s)->id);
5d909e3e 1478
7c610628
LP
1479 if (cfd >= 0)
1480 close_nointr_nofail(cfd);
1481 else {
1482 /* Flush all sockets by closing and reopening them */
1483 socket_close_fds(s);
1484
16ac4014
LP
1485 r = socket_open_fds(s);
1486 if (r < 0) {
1487 log_warning_unit(UNIT(s)->id, "%s failed to listen on sockets: %s", UNIT(s)->id, strerror(-r));
1488 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
1489 return;
1490 }
1491
1a710b43
MS
1492 r = socket_watch_fds(s);
1493 if (r < 0) {
e821075a 1494 log_warning_unit(UNIT(s)->id, "%s failed to watch sockets: %s", UNIT(s)->id, strerror(-r));
cfc4eb4c 1495 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
7c610628
LP
1496 }
1497 }
1498
ba3e67a7
LP
1499 return;
1500 }
1501
4f2d528d 1502 if (cfd < 0) {
57020a3a 1503 Iterator i;
e821075a 1504 Unit *other;
f976f3f6 1505 bool pending = false;
f976f3f6
LP
1506
1507 /* If there's already a start pending don't bother to
1508 * do anything */
e821075a
LP
1509 SET_FOREACH(other, UNIT(s)->dependencies[UNIT_TRIGGERS], i)
1510 if (unit_active_or_pending(other)) {
57020a3a
LP
1511 pending = true;
1512 break;
1513 }
f976f3f6 1514
1a710b43
MS
1515 if (!pending) {
1516 r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL);
1517 if (r < 0)
f976f3f6 1518 goto fail;
1a710b43 1519 }
4f2d528d
LP
1520
1521 socket_set_state(s, SOCKET_RUNNING);
1522 } else {
e55001eb 1523 _cleanup_free_ char *prefix = NULL, *instance = NULL, *name = NULL;
b15bdda8 1524 Service *service;
4f2d528d 1525
6cf6bbc2 1526 if (s->n_connections >= s->max_connections) {
e821075a 1527 log_warning_unit(UNIT(s)->id, "%s: Too many incoming connections (%u)", UNIT(s)->id, s->n_connections);
6cf6bbc2
LP
1528 close_nointr_nofail(cfd);
1529 return;
1530 }
1531
1a710b43
MS
1532 r = socket_instantiate_service(s);
1533 if (r < 0)
b15bdda8
LP
1534 goto fail;
1535
1a710b43
MS
1536 r = instance_from_socket(cfd, s->n_accepted, &instance);
1537 if (r < 0) {
1538 if (r != -ENOTCONN)
1539 goto fail;
1540
1541 /* ENOTCONN is legitimate if TCP RST was received.
1542 * This connection is over, but the socket unit lives on. */
1543 close_nointr_nofail(cfd);
1544 return;
1545 }
4f2d528d 1546
1a710b43
MS
1547 prefix = unit_name_to_prefix(UNIT(s)->id);
1548 if (!prefix) {
4f2d528d
LP
1549 r = -ENOMEM;
1550 goto fail;
1551 }
1552
1553 name = unit_name_build(prefix, instance, ".service");
b6dbbe1c 1554 if (!name) {
4f2d528d 1555 r = -ENOMEM;
b6dbbe1c
LP
1556 goto fail;
1557 }
4f2d528d 1558
1a710b43 1559 r = unit_add_name(UNIT_DEREF(s->service), name);
e55001eb 1560 if (r < 0)
4f2d528d 1561 goto fail;
b15bdda8 1562
57020a3a
LP
1563 service = SERVICE(UNIT_DEREF(s->service));
1564 unit_ref_unset(&s->service);
b15bdda8 1565 s->n_accepted ++;
4f2d528d 1566
1124fe6f 1567 UNIT(service)->no_gc = false;
6c073082 1568
b15bdda8 1569 unit_choose_id(UNIT(service), name);
b15bdda8 1570
1a710b43
MS
1571 r = service_set_socket_fd(service, cfd, s);
1572 if (r < 0)
4f2d528d
LP
1573 goto fail;
1574
1575 cfd = -1;
6cf6bbc2
LP
1576 s->n_connections ++;
1577
1a710b43
MS
1578 r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL);
1579 if (r < 0)
4f2d528d 1580 goto fail;
c4e2ceae
LP
1581
1582 /* Notify clients about changed counters */
1583 unit_add_to_dbus_queue(UNIT(s));
4f2d528d 1584 }
034c6ed7 1585
034c6ed7
LP
1586 return;
1587
1588fail:
e821075a
LP
1589 log_warning_unit(UNIT(s)->id, "%s failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",
1590 UNIT(s)->id, cfd >= 0 ? "template" : "non-template",
718db961 1591 bus_error_message(&error, r));
e821075a 1592
60089004 1593 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
4f2d528d
LP
1594
1595 if (cfd >= 0)
1596 close_nointr_nofail(cfd);
034c6ed7
LP
1597}
1598
cfc4eb4c 1599static void socket_run_next(Socket *s) {
034c6ed7
LP
1600 int r;
1601
1602 assert(s);
1603 assert(s->control_command);
1604 assert(s->control_command->command_next);
1605
5e94833f
LP
1606 socket_unwatch_control_pid(s);
1607
034c6ed7
LP
1608 s->control_command = s->control_command->command_next;
1609
e821075a
LP
1610 r = socket_spawn(s, s->control_command, &s->control_pid);
1611 if (r < 0)
034c6ed7
LP
1612 goto fail;
1613
1614 return;
1615
1616fail:
e821075a 1617 log_warning_unit(UNIT(s)->id, "%s failed to run next task: %s", UNIT(s)->id, strerror(-r));
80876c20
LP
1618
1619 if (s->state == SOCKET_START_POST)
cfc4eb4c 1620 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
034c6ed7 1621 else if (s->state == SOCKET_STOP_POST)
cfc4eb4c 1622 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
034c6ed7 1623 else
cfc4eb4c 1624 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1625}
1626
87f0e418
LP
1627static int socket_start(Unit *u) {
1628 Socket *s = SOCKET(u);
83c60c9f
LP
1629
1630 assert(s);
1631
034c6ed7
LP
1632 /* We cannot fulfill this request right now, try again later
1633 * please! */
1634 if (s->state == SOCKET_STOP_PRE ||
1635 s->state == SOCKET_STOP_PRE_SIGKILL ||
1636 s->state == SOCKET_STOP_PRE_SIGTERM ||
1637 s->state == SOCKET_STOP_POST ||
80876c20
LP
1638 s->state == SOCKET_FINAL_SIGTERM ||
1639 s->state == SOCKET_FINAL_SIGKILL)
034c6ed7
LP
1640 return -EAGAIN;
1641
83c60c9f
LP
1642 if (s->state == SOCKET_START_PRE ||
1643 s->state == SOCKET_START_POST)
034c6ed7 1644 return 0;
83c60c9f 1645
034c6ed7 1646 /* Cannot run this without the service being around */
9444b1f2 1647 if (UNIT_ISSET(s->service)) {
57020a3a
LP
1648 Service *service;
1649
1650 service = SERVICE(UNIT_DEREF(s->service));
1651
1124fe6f 1652 if (UNIT(service)->load_state != UNIT_LOADED) {
e821075a 1653 log_error_unit(u->id, "Socket service %s not loaded, refusing.", UNIT(service)->id);
4f2d528d 1654 return -ENOENT;
4ac9236f 1655 }
4f2d528d 1656
35b8ca3a 1657 /* If the service is already active we cannot start the
4f2d528d 1658 * socket */
57020a3a
LP
1659 if (service->state != SERVICE_DEAD &&
1660 service->state != SERVICE_FAILED &&
1661 service->state != SERVICE_AUTO_RESTART) {
e821075a 1662 log_error_unit(u->id, "Socket service %s already active, refusing.", UNIT(service)->id);
4f2d528d 1663 return -EBUSY;
4ac9236f 1664 }
7b4bf06b
LP
1665
1666#ifdef HAVE_SYSV_COMPAT
1b64d026 1667 if (service->is_sysv) {
d7607eac 1668 log_error_unit(u->id,
66870f90 1669 "Using SysV services for socket activation is not supported. Refusing.");
7b4bf06b
LP
1670 return -ENOENT;
1671 }
1672#endif
4f2d528d 1673 }
e537352b 1674
fdf20a31 1675 assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED);
83c60c9f 1676
cfc4eb4c 1677 s->result = SOCKET_SUCCESS;
034c6ed7 1678 socket_enter_start_pre(s);
e821075a 1679
034c6ed7
LP
1680 return 0;
1681}
83c60c9f 1682
87f0e418
LP
1683static int socket_stop(Unit *u) {
1684 Socket *s = SOCKET(u);
034c6ed7
LP
1685
1686 assert(s);
1687
e537352b
LP
1688 /* Already on it */
1689 if (s->state == SOCKET_STOP_PRE ||
1690 s->state == SOCKET_STOP_PRE_SIGTERM ||
1691 s->state == SOCKET_STOP_PRE_SIGKILL ||
1692 s->state == SOCKET_STOP_POST ||
80876c20 1693 s->state == SOCKET_FINAL_SIGTERM ||
3f6c78dc 1694 s->state == SOCKET_FINAL_SIGKILL)
e537352b
LP
1695 return 0;
1696
3f6c78dc
LP
1697 /* If there's already something running we go directly into
1698 * kill mode. */
1699 if (s->state == SOCKET_START_PRE ||
1700 s->state == SOCKET_START_POST) {
cfc4eb4c 1701 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS);
3f6c78dc
LP
1702 return -EAGAIN;
1703 }
1704
034c6ed7 1705 assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
83c60c9f 1706
cfc4eb4c 1707 socket_enter_stop_pre(s, SOCKET_SUCCESS);
542563ba
LP
1708 return 0;
1709}
1710
a16e1123
LP
1711static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
1712 Socket *s = SOCKET(u);
1713 SocketPort *p;
1714 int r;
1715
1716 assert(u);
1717 assert(f);
1718 assert(fds);
1719
1720 unit_serialize_item(u, f, "state", socket_state_to_string(s->state));
cfc4eb4c 1721 unit_serialize_item(u, f, "result", socket_result_to_string(s->result));
a16e1123
LP
1722 unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted);
1723
1724 if (s->control_pid > 0)
5925dd3c 1725 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
a16e1123
LP
1726
1727 if (s->control_command_id >= 0)
1728 unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id));
1729
1730 LIST_FOREACH(port, p, s->ports) {
1731 int copy;
1732
1733 if (p->fd < 0)
1734 continue;
1735
613b411c
LP
1736 copy = fdset_put_dup(fds, p->fd);
1737 if (copy < 0)
a16e1123
LP
1738 return copy;
1739
1740 if (p->type == SOCKET_SOCKET) {
613b411c 1741 _cleanup_free_ char *t = NULL;
a16e1123 1742
ee092817
LP
1743 r = socket_address_print(&p->address, &t);
1744 if (r < 0)
a16e1123
LP
1745 return r;
1746
7a22745a
LP
1747 if (socket_address_family(&p->address) == AF_NETLINK)
1748 unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t);
1749 else
1750 unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t);
613b411c 1751
b0a3f2bc
LP
1752 } else if (p->type == SOCKET_SPECIAL)
1753 unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path);
ee092817
LP
1754 else if (p->type == SOCKET_MQUEUE)
1755 unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path);
b0a3f2bc 1756 else {
a16e1123
LP
1757 assert(p->type == SOCKET_FIFO);
1758 unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path);
1759 }
1760 }
1761
1762 return 0;
1763}
1764
1765static int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1766 Socket *s = SOCKET(u);
a16e1123
LP
1767
1768 assert(u);
1769 assert(key);
1770 assert(value);
a16e1123
LP
1771
1772 if (streq(key, "state")) {
1773 SocketState state;
1774
ee092817
LP
1775 state = socket_state_from_string(value);
1776 if (state < 0)
e821075a 1777 log_debug_unit(u->id, "Failed to parse state value %s", value);
a16e1123
LP
1778 else
1779 s->deserialized_state = state;
cfc4eb4c
LP
1780 } else if (streq(key, "result")) {
1781 SocketResult f;
a16e1123 1782
cfc4eb4c
LP
1783 f = socket_result_from_string(value);
1784 if (f < 0)
e821075a 1785 log_debug_unit(u->id, "Failed to parse result value %s", value);
cfc4eb4c
LP
1786 else if (f != SOCKET_SUCCESS)
1787 s->result = f;
a16e1123
LP
1788
1789 } else if (streq(key, "n-accepted")) {
1790 unsigned k;
1791
e364ad06 1792 if (safe_atou(value, &k) < 0)
e821075a 1793 log_debug_unit(u->id, "Failed to parse n-accepted value %s", value);
a16e1123
LP
1794 else
1795 s->n_accepted += k;
1796 } else if (streq(key, "control-pid")) {
5925dd3c 1797 pid_t pid;
a16e1123 1798
e364ad06 1799 if (parse_pid(value, &pid) < 0)
e821075a 1800 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
a16e1123 1801 else
5925dd3c 1802 s->control_pid = pid;
a16e1123
LP
1803 } else if (streq(key, "control-command")) {
1804 SocketExecCommand id;
1805
66870f90
ZJS
1806 id = socket_exec_command_from_string(value);
1807 if (id < 0)
e821075a 1808 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
a16e1123
LP
1809 else {
1810 s->control_command_id = id;
1811 s->control_command = s->exec_command[id];
1812 }
1813 } else if (streq(key, "fifo")) {
1814 int fd, skip = 0;
1815 SocketPort *p;
1816
1817 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
e821075a 1818 log_debug_unit(u->id, "Failed to parse fifo value %s", value);
a16e1123
LP
1819 else {
1820
1821 LIST_FOREACH(port, p, s->ports)
b0a3f2bc
LP
1822 if (p->type == SOCKET_FIFO &&
1823 streq_ptr(p->path, value+skip))
1824 break;
1825
1826 if (p) {
1827 if (p->fd >= 0)
1828 close_nointr_nofail(p->fd);
1829 p->fd = fdset_remove(fds, fd);
1830 }
1831 }
1832
1833 } else if (streq(key, "special")) {
1834 int fd, skip = 0;
1835 SocketPort *p;
1836
1837 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
e821075a 1838 log_debug_unit(u->id, "Failed to parse special value %s", value);
b0a3f2bc
LP
1839 else {
1840
1841 LIST_FOREACH(port, p, s->ports)
1842 if (p->type == SOCKET_SPECIAL &&
1843 streq_ptr(p->path, value+skip))
a16e1123
LP
1844 break;
1845
1846 if (p) {
1847 if (p->fd >= 0)
1848 close_nointr_nofail(p->fd);
1849 p->fd = fdset_remove(fds, fd);
1850 }
1851 }
1852
ee092817
LP
1853 } else if (streq(key, "mqueue")) {
1854 int fd, skip = 0;
1855 SocketPort *p;
1856
1857 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
e821075a 1858 log_debug_unit(u->id, "Failed to parse mqueue value %s", value);
ee092817
LP
1859 else {
1860
1861 LIST_FOREACH(port, p, s->ports)
1862 if (p->type == SOCKET_MQUEUE &&
1863 streq_ptr(p->path, value+skip))
1864 break;
1865
1866 if (p) {
1867 if (p->fd >= 0)
1868 close_nointr_nofail(p->fd);
1869 p->fd = fdset_remove(fds, fd);
1870 }
1871 }
1872
a16e1123 1873 } else if (streq(key, "socket")) {
27ca8d7a 1874 int fd, type, skip = 0;
a16e1123
LP
1875 SocketPort *p;
1876
27ca8d7a 1877 if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd))
e821075a 1878 log_debug_unit(u->id, "Failed to parse socket value %s", value);
a16e1123
LP
1879 else {
1880
1881 LIST_FOREACH(port, p, s->ports)
27ca8d7a 1882 if (socket_address_is(&p->address, value+skip, type))
a16e1123
LP
1883 break;
1884
1885 if (p) {
1886 if (p->fd >= 0)
1887 close_nointr_nofail(p->fd);
1888 p->fd = fdset_remove(fds, fd);
1889 }
1890 }
1891
7a22745a
LP
1892 } else if (streq(key, "netlink")) {
1893 int fd, skip = 0;
1894 SocketPort *p;
1895
1896 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
e821075a 1897 log_debug_unit(u->id, "Failed to parse socket value %s", value);
7a22745a
LP
1898 else {
1899
1900 LIST_FOREACH(port, p, s->ports)
1901 if (socket_address_is_netlink(&p->address, value+skip))
1902 break;
1903
1904 if (p) {
1905 if (p->fd >= 0)
1906 close_nointr_nofail(p->fd);
1907 p->fd = fdset_remove(fds, fd);
1908 }
1909 }
a16e1123 1910 } else
e821075a 1911 log_debug_unit(UNIT(s)->id, "Unknown serialization key '%s'", key);
a16e1123
LP
1912
1913 return 0;
1914}
1915
01e10de3
LP
1916static int socket_distribute_fds(Unit *u, FDSet *fds) {
1917 Socket *s = SOCKET(u);
1918 SocketPort *p;
1919
1920 assert(u);
1921
1922 LIST_FOREACH(port, p, s->ports) {
1923 Iterator i;
1924 int fd;
1925
1926 if (p->type != SOCKET_SOCKET)
1927 continue;
1928
1929 if (p->fd >= 0)
1930 continue;
1931
1932 FDSET_FOREACH(fd, fds, i) {
1933 if (socket_address_matches_fd(&p->address, fd)) {
1934 p->fd = fdset_remove(fds, fd);
1935 s->deserialized_state = SOCKET_LISTENING;
1936 break;
1937 }
1938 }
1939 }
1940
1941 return 0;
1942}
1943
44a6b1b6 1944_pure_ static UnitActiveState socket_active_state(Unit *u) {
87f0e418 1945 assert(u);
5cb5a6ff 1946
acbb0225 1947 return state_translation_table[SOCKET(u)->state];
5cb5a6ff
LP
1948}
1949
44a6b1b6 1950_pure_ static const char *socket_sub_state_to_string(Unit *u) {
10a94420
LP
1951 assert(u);
1952
a16e1123 1953 return socket_state_to_string(SOCKET(u)->state);
10a94420
LP
1954}
1955
67419600
OS
1956const char* socket_port_type_to_string(SocketPort *p) {
1957
1958 assert(p);
1959
1960 switch (p->type) {
718db961
LP
1961
1962 case SOCKET_SOCKET:
1963
1964 switch (p->address.type) {
1965
1966 case SOCK_STREAM:
1967 return "Stream";
1968
1969 case SOCK_DGRAM:
1970 return "Datagram";
1971
1972 case SOCK_SEQPACKET:
1973 return "SequentialPacket";
1974
1975 case SOCK_RAW:
1976 if (socket_address_family(&p->address) == AF_NETLINK)
1977 return "Netlink";
1978
1979 default:
1980 return NULL;
1981 }
1982
1983 case SOCKET_SPECIAL:
1984 return "Special";
1985
1986 case SOCKET_MQUEUE:
1987 return "MessageQueue";
1988
1989 case SOCKET_FIFO:
1990 return "FIFO";
1991
1992 default:
1993 return NULL;
67419600
OS
1994 }
1995}
1996
44a6b1b6 1997_pure_ static bool socket_check_gc(Unit *u) {
6cf6bbc2
LP
1998 Socket *s = SOCKET(u);
1999
2000 assert(u);
2001
2002 return s->n_connections > 0;
2003}
2004
718db961
LP
2005static int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
2006 SocketPort *p = userdata;
4f2d528d 2007 int cfd = -1;
9152c765 2008
718db961 2009 assert(p);
8d567588 2010 assert(fd >= 0);
9152c765 2011
718db961
LP
2012 if (p->socket->state != SOCKET_LISTENING)
2013 return 0;
871d7de4 2014
718db961 2015 log_debug_unit(UNIT(p->socket)->id, "Incoming traffic on %s", UNIT(p->socket)->id);
9152c765 2016
718db961 2017 if (revents != EPOLLIN) {
641e01dc 2018
718db961 2019 if (revents & EPOLLHUP)
e821075a 2020 log_error_unit(UNIT(p->socket)->id, "%s: Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that.",
718db961 2021 UNIT(p->socket)->id);
641e01dc 2022 else
e821075a 2023 log_error_unit(UNIT(p->socket)->id, "%s: Got unexpected poll event (0x%x) on socket.",
718db961 2024 UNIT(p->socket)->id, revents);
641e01dc 2025
8d567588 2026 goto fail;
4f2d528d
LP
2027 }
2028
718db961
LP
2029 if (p->socket->accept &&
2030 p->type == SOCKET_SOCKET &&
2031 socket_address_can_accept(&p->address)) {
2032
4f2d528d
LP
2033 for (;;) {
2034
b14eda96
LP
2035 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK);
2036 if (cfd < 0) {
4f2d528d
LP
2037
2038 if (errno == EINTR)
2039 continue;
2040
718db961 2041 log_error_unit(UNIT(p->socket)->id,
66870f90 2042 "Failed to accept socket: %m");
8d567588 2043 goto fail;
4f2d528d
LP
2044 }
2045
2046 break;
2047 }
4fd5948e 2048
718db961 2049 socket_apply_socket_options(p->socket, cfd);
4f2d528d 2050 }
9152c765 2051
718db961
LP
2052 socket_enter_running(p->socket, cfd);
2053 return 0;
8d567588
LP
2054
2055fail:
718db961
LP
2056 socket_enter_stop_pre(p->socket, SOCKET_FAILURE_RESOURCES);
2057 return 0;
9152c765
LP
2058}
2059
87f0e418
LP
2060static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
2061 Socket *s = SOCKET(u);
cfc4eb4c 2062 SocketResult f;
5cb5a6ff
LP
2063
2064 assert(s);
034c6ed7 2065 assert(pid >= 0);
5cb5a6ff 2066
8c47c732
LP
2067 if (pid != s->control_pid)
2068 return;
542563ba 2069
034c6ed7
LP
2070 s->control_pid = 0;
2071
96342de6 2072 if (is_clean_exit(code, status, NULL))
cfc4eb4c
LP
2073 f = SOCKET_SUCCESS;
2074 else if (code == CLD_EXITED)
2075 f = SOCKET_FAILURE_EXIT_CODE;
2076 else if (code == CLD_KILLED)
2077 f = SOCKET_FAILURE_SIGNAL;
2078 else if (code == CLD_DUMPED)
2079 f = SOCKET_FAILURE_CORE_DUMP;
2080 else
2081 assert_not_reached("Unknown code");
8c47c732 2082
b708e7ce 2083 if (s->control_command) {
6ea832a2 2084 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
a16e1123 2085
b708e7ce 2086 if (s->control_command->ignore)
cfc4eb4c 2087 f = SOCKET_SUCCESS;
b708e7ce
LP
2088 }
2089
66870f90
ZJS
2090 log_full_unit(f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
2091 u->id,
2092 "%s control process exited, code=%s status=%i",
2093 u->id, sigchld_code_to_string(code), status);
034c6ed7 2094
cfc4eb4c
LP
2095 if (f != SOCKET_SUCCESS)
2096 s->result = f;
2097
2098 if (s->control_command &&
2099 s->control_command->command_next &&
2100 f == SOCKET_SUCCESS) {
2101
66870f90
ZJS
2102 log_debug_unit(u->id,
2103 "%s running next command for state %s",
2104 u->id, socket_state_to_string(s->state));
cfc4eb4c 2105 socket_run_next(s);
acbb0225 2106 } else {
a16e1123
LP
2107 s->control_command = NULL;
2108 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
2109
034c6ed7
LP
2110 /* No further commands for this step, so let's figure
2111 * out what to do next */
5cb5a6ff 2112
66870f90
ZJS
2113 log_debug_unit(u->id,
2114 "%s got final SIGCHLD for state %s",
2115 u->id, socket_state_to_string(s->state));
acbb0225 2116
034c6ed7
LP
2117 switch (s->state) {
2118
2119 case SOCKET_START_PRE:
cfc4eb4c 2120 if (f == SOCKET_SUCCESS)
acbb0225 2121 socket_enter_start_post(s);
034c6ed7 2122 else
cfc4eb4c 2123 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f);
034c6ed7
LP
2124 break;
2125
2126 case SOCKET_START_POST:
cfc4eb4c 2127 if (f == SOCKET_SUCCESS)
e9af15c3 2128 socket_enter_listening(s);
034c6ed7 2129 else
cfc4eb4c 2130 socket_enter_stop_pre(s, f);
034c6ed7
LP
2131 break;
2132
2133 case SOCKET_STOP_PRE:
2134 case SOCKET_STOP_PRE_SIGTERM:
2135 case SOCKET_STOP_PRE_SIGKILL:
cfc4eb4c 2136 socket_enter_stop_post(s, f);
034c6ed7
LP
2137 break;
2138
2139 case SOCKET_STOP_POST:
80876c20
LP
2140 case SOCKET_FINAL_SIGTERM:
2141 case SOCKET_FINAL_SIGKILL:
cfc4eb4c 2142 socket_enter_dead(s, f);
034c6ed7
LP
2143 break;
2144
2145 default:
2146 assert_not_reached("Uh, control process died at wrong time.");
2147 }
2148 }
c4e2ceae
LP
2149
2150 /* Notify clients about changed exit status */
2151 unit_add_to_dbus_queue(u);
034c6ed7 2152}
5cb5a6ff 2153
718db961
LP
2154static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
2155 Socket *s = SOCKET(userdata);
5cb5a6ff 2156
034c6ed7 2157 assert(s);
718db961 2158 assert(s->timer_event_source == source);
034c6ed7
LP
2159
2160 switch (s->state) {
2161
2162 case SOCKET_START_PRE:
718db961
LP
2163 log_warning_unit(UNIT(s)->id,
2164 "%s starting timed out. Terminating.", UNIT(s)->id);
cfc4eb4c 2165 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
da19d5c1 2166 break;
80876c20 2167
034c6ed7 2168 case SOCKET_START_POST:
718db961
LP
2169 log_warning_unit(UNIT(s)->id,
2170 "%s starting timed out. Stopping.", UNIT(s)->id);
cfc4eb4c 2171 socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2172 break;
2173
2174 case SOCKET_STOP_PRE:
718db961
LP
2175 log_warning_unit(UNIT(s)->id,
2176 "%s stopping timed out. Terminating.", UNIT(s)->id);
cfc4eb4c 2177 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2178 break;
2179
2180 case SOCKET_STOP_PRE_SIGTERM:
4819ff03 2181 if (s->kill_context.send_sigkill) {
718db961
LP
2182 log_warning_unit(UNIT(s)->id,
2183 "%s stopping timed out. Killing.", UNIT(s)->id);
cfc4eb4c 2184 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT);
ba035df2 2185 } else {
718db961 2186 log_warning_unit(UNIT(s)->id,
66870f90 2187 "%s stopping timed out. Skipping SIGKILL. Ignoring.",
718db961 2188 UNIT(s)->id);
cfc4eb4c 2189 socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
ba035df2 2190 }
034c6ed7
LP
2191 break;
2192
2193 case SOCKET_STOP_PRE_SIGKILL:
718db961
LP
2194 log_warning_unit(UNIT(s)->id,
2195 "%s still around after SIGKILL. Ignoring.", UNIT(s)->id);
cfc4eb4c 2196 socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2197 break;
2198
2199 case SOCKET_STOP_POST:
718db961
LP
2200 log_warning_unit(UNIT(s)->id,
2201 "%s stopping timed out (2). Terminating.", UNIT(s)->id);
cfc4eb4c 2202 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2203 break;
2204
80876c20 2205 case SOCKET_FINAL_SIGTERM:
4819ff03 2206 if (s->kill_context.send_sigkill) {
718db961
LP
2207 log_warning_unit(UNIT(s)->id,
2208 "%s stopping timed out (2). Killing.", UNIT(s)->id);
cfc4eb4c 2209 socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT);
ba035df2 2210 } else {
718db961 2211 log_warning_unit(UNIT(s)->id,
66870f90 2212 "%s stopping timed out (2). Skipping SIGKILL. Ignoring.",
718db961 2213 UNIT(s)->id);
cfc4eb4c 2214 socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
ba035df2 2215 }
034c6ed7
LP
2216 break;
2217
80876c20 2218 case SOCKET_FINAL_SIGKILL:
718db961 2219 log_warning_unit(UNIT(s)->id,
66870f90 2220 "%s still around after SIGKILL (2). Entering failed mode.",
718db961 2221 UNIT(s)->id);
cfc4eb4c 2222 socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2223 break;
2224
2225 default:
2226 assert_not_reached("Timeout at wrong time.");
2227 }
718db961
LP
2228
2229 return 0;
5cb5a6ff
LP
2230}
2231
44d8db9e
LP
2232int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
2233 int *rfds;
2234 unsigned rn_fds, k;
2235 SocketPort *p;
2236
2237 assert(s);
2238 assert(fds);
2239 assert(n_fds);
2240
2241 /* Called from the service code for requesting our fds */
2242
2243 rn_fds = 0;
2244 LIST_FOREACH(port, p, s->ports)
2245 if (p->fd >= 0)
2246 rn_fds++;
2247
de3756ab
LP
2248 if (rn_fds <= 0) {
2249 *fds = NULL;
2250 *n_fds = 0;
2251 return 0;
2252 }
2253
e364ad06 2254 if (!(rfds = new(int, rn_fds)))
44d8db9e
LP
2255 return -ENOMEM;
2256
2257 k = 0;
2258 LIST_FOREACH(port, p, s->ports)
2259 if (p->fd >= 0)
2260 rfds[k++] = p->fd;
2261
2262 assert(k == rn_fds);
2263
2264 *fds = rfds;
2265 *n_fds = rn_fds;
2266
2267 return 0;
2268}
2269
e821075a
LP
2270static void socket_reset_failed(Unit *u) {
2271 Socket *s = SOCKET(u);
2272
2273 assert(s);
2274
2275 if (s->state == SOCKET_FAILED)
2276 socket_set_state(s, SOCKET_DEAD);
2277
2278 s->result = SOCKET_SUCCESS;
2279}
2280
d137a488 2281static void socket_notify_service_dead(Socket *s, bool failed_permanent) {
ceee3d82
LP
2282 assert(s);
2283
6cf6bbc2
LP
2284 /* The service is dead. Dang!
2285 *
2286 * This is strictly for one-instance-for-all-connections
2287 * services. */
ceee3d82
LP
2288
2289 if (s->state == SOCKET_RUNNING) {
e821075a 2290 log_debug_unit(UNIT(s)->id, "%s got notified about service death (failed permanently: %s)", UNIT(s)->id, yes_no(failed_permanent));
6bda96a0
LP
2291 if (failed_permanent)
2292 socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_FAILED_PERMANENT);
c2f34808
MS
2293 else
2294 socket_enter_listening(s);
ceee3d82
LP
2295 }
2296}
2297
6cf6bbc2
LP
2298void socket_connection_unref(Socket *s) {
2299 assert(s);
2300
2301 /* The service is dead. Yay!
2302 *
35b8ca3a 2303 * This is strictly for one-instance-per-connection
6cf6bbc2
LP
2304 * services. */
2305
2306 assert(s->n_connections > 0);
2307 s->n_connections--;
2308
e821075a 2309 log_debug_unit(UNIT(s)->id, "%s: One connection closed, %u left.", UNIT(s)->id, s->n_connections);
5632e374
LP
2310}
2311
d137a488
UTL
2312static void socket_trigger_notify(Unit *u, Unit *other) {
2313 Socket *s = SOCKET(u);
e821075a 2314 Service *se;
d137a488
UTL
2315
2316 assert(u);
2317 assert(other);
2318
2319 /* Don't propagate state changes from the service if we are
2320 already down or accepting connections */
2321 if ((s->state != SOCKET_RUNNING &&
2322 s->state != SOCKET_LISTENING) ||
2323 s->accept)
2324 return;
2325
2326 if (other->load_state != UNIT_LOADED ||
2327 other->type != UNIT_SERVICE)
2328 return;
2329
e821075a
LP
2330 se = SERVICE(other);
2331
d137a488
UTL
2332 if (se->state == SERVICE_FAILED)
2333 socket_notify_service_dead(s, se->result == SERVICE_FAILURE_START_LIMIT);
2334
2335 if (se->state == SERVICE_DEAD ||
2336 se->state == SERVICE_STOP ||
2337 se->state == SERVICE_STOP_SIGTERM ||
2338 se->state == SERVICE_STOP_SIGKILL ||
2339 se->state == SERVICE_STOP_POST ||
2340 se->state == SERVICE_FINAL_SIGTERM ||
2341 se->state == SERVICE_FINAL_SIGKILL ||
2342 se->state == SERVICE_AUTO_RESTART)
2343 socket_notify_service_dead(s, false);
2344
2345 if (se->state == SERVICE_RUNNING)
2346 socket_set_state(s, SOCKET_RUNNING);
2347}
2348
718db961 2349static int socket_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
814cc562 2350 return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
8a0867d6
LP
2351}
2352
68db7a3b
ZJS
2353static int socket_get_timeout(Unit *u, uint64_t *timeout) {
2354 Socket *s = SOCKET(u);
2355 int r;
2356
2357 if (!s->timer_event_source)
2358 return 0;
2359
2360 r = sd_event_source_get_time(s->timer_event_source, timeout);
2361 if (r < 0)
2362 return r;
2363
2364 return 1;
2365}
2366
a16e1123
LP
2367static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
2368 [SOCKET_DEAD] = "dead",
2369 [SOCKET_START_PRE] = "start-pre",
2370 [SOCKET_START_POST] = "start-post",
2371 [SOCKET_LISTENING] = "listening",
2372 [SOCKET_RUNNING] = "running",
2373 [SOCKET_STOP_PRE] = "stop-pre",
2374 [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
2375 [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
2376 [SOCKET_STOP_POST] = "stop-post",
2377 [SOCKET_FINAL_SIGTERM] = "final-sigterm",
2378 [SOCKET_FINAL_SIGKILL] = "final-sigkill",
fdf20a31 2379 [SOCKET_FAILED] = "failed"
a16e1123
LP
2380};
2381
2382DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
2383
2384static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
2385 [SOCKET_EXEC_START_PRE] = "StartPre",
2386 [SOCKET_EXEC_START_POST] = "StartPost",
2387 [SOCKET_EXEC_STOP_PRE] = "StopPre",
2388 [SOCKET_EXEC_STOP_POST] = "StopPost"
2389};
2390
2391DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand);
2392
cfc4eb4c
LP
2393static const char* const socket_result_table[_SOCKET_RESULT_MAX] = {
2394 [SOCKET_SUCCESS] = "success",
2395 [SOCKET_FAILURE_RESOURCES] = "resources",
2396 [SOCKET_FAILURE_TIMEOUT] = "timeout",
2397 [SOCKET_FAILURE_EXIT_CODE] = "exit-code",
2398 [SOCKET_FAILURE_SIGNAL] = "signal",
c2f34808 2399 [SOCKET_FAILURE_CORE_DUMP] = "core-dump",
6bda96a0 2400 [SOCKET_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent"
cfc4eb4c
LP
2401};
2402
2403DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult);
2404
87f0e418 2405const UnitVTable socket_vtable = {
7d17cfbc 2406 .object_size = sizeof(Socket),
718db961
LP
2407 .exec_context_offset = offsetof(Socket, exec_context),
2408 .cgroup_context_offset = offsetof(Socket, cgroup_context),
2409 .kill_context_offset = offsetof(Socket, kill_context),
613b411c 2410 .exec_runtime_offset = offsetof(Socket, exec_runtime),
3ef63c31 2411
f975e971
LP
2412 .sections =
2413 "Unit\0"
2414 "Socket\0"
2415 "Install\0",
4ad49000 2416 .private_section = "Socket",
71645aca 2417
034c6ed7
LP
2418 .init = socket_init,
2419 .done = socket_done,
a16e1123
LP
2420 .load = socket_load,
2421
2422 .coldplug = socket_coldplug,
034c6ed7 2423
5cb5a6ff
LP
2424 .dump = socket_dump,
2425
542563ba
LP
2426 .start = socket_start,
2427 .stop = socket_stop,
5cb5a6ff 2428
718db961
LP
2429 .kill = socket_kill,
2430
68db7a3b
ZJS
2431 .get_timeout = socket_get_timeout,
2432
a16e1123
LP
2433 .serialize = socket_serialize,
2434 .deserialize_item = socket_deserialize_item,
01e10de3 2435 .distribute_fds = socket_distribute_fds,
a16e1123 2436
5cb5a6ff 2437 .active_state = socket_active_state,
10a94420 2438 .sub_state_to_string = socket_sub_state_to_string,
5cb5a6ff 2439
6cf6bbc2
LP
2440 .check_gc = socket_check_gc,
2441
034c6ed7 2442 .sigchld_event = socket_sigchld_event,
4139c1b2 2443
d137a488
UTL
2444 .trigger_notify = socket_trigger_notify,
2445
fdf20a31 2446 .reset_failed = socket_reset_failed,
5632e374 2447
c4e2ceae 2448 .bus_interface = "org.freedesktop.systemd1.Socket",
718db961 2449 .bus_vtable = bus_socket_vtable,
74c964d3
LP
2450 .bus_set_property = bus_socket_set_property,
2451 .bus_commit_properties = bus_socket_commit_properties,
c6918296
MS
2452
2453 .status_message_formats = {
2454 /*.starting_stopping = {
2455 [0] = "Starting socket %s...",
2456 [1] = "Stopping socket %s...",
2457 },*/
2458 .finished_start_job = {
2459 [JOB_DONE] = "Listening on %s.",
2460 [JOB_FAILED] = "Failed to listen on %s.",
2461 [JOB_DEPENDENCY] = "Dependency failed for %s.",
2462 [JOB_TIMEOUT] = "Timed out starting %s.",
2463 },
2464 .finished_stop_job = {
2465 [JOB_DONE] = "Closed %s.",
2466 [JOB_FAILED] = "Failed stopping %s.",
2467 [JOB_TIMEOUT] = "Timed out stopping %s.",
2468 },
2469 },
5cb5a6ff 2470};