socket.c revision 6ec4ed645e37ba7dd5628747ea78ec1663599ab7
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2010 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen [SOCKET_RUNNING] = UNIT_ACTIVE,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poetteringstatic int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s->timeout_usec = u->manager->default_timeout_start_usec;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->exec_context.std_output = u->manager->default_std_output;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->exec_context.std_error = u->manager->default_std_error;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poetteringstatic void socket_unwatch_control_pid(Socket *s) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering unit_unwatch_pid(UNIT(s), s->control_pid);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poetteringstatic void socket_cleanup_fd_list(SocketPort *p) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering p->auxiliary_fds = mfree(p->auxiliary_fds);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering while ((p = s->ports)) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen s->exec_runtime = exec_runtime_unref(s->exec_runtime);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s->tcp_congestion = mfree(s->tcp_congestion);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering now(CLOCK_MONOTONIC) + s->timeout_usec, 0,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering (void) sd_event_source_set_description(s->timer_event_source, "socket-timer");
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poetteringint socket_instantiate_service(Socket *s) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *prefix = NULL, *name = NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* This fills in s->service if it isn't filled in yet. For
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering * Accept=yes sockets we create the next connection service
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering * here. For Accept=no this is mostly a NOP since the service
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering * is figured out at load time anyway. */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = unit_name_to_prefix(UNIT(s)->id, &prefix);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (asprintf(&name, "%s@%u.service", prefix, s->n_accepted) < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = manager_load_unit(UNIT(s)->manager, name, NULL, NULL, &u);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic bool have_non_accept_socket(Socket *s) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!socket_address_can_accept(&p->address))
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringstatic int socket_add_mount_links(Socket *s) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering path = socket_address_get_path(&p->address);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering else if (IN_SET(p->type, SOCKET_FIFO, SOCKET_SPECIAL, SOCKET_USB_FUNCTION))
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering r = unit_require_mounts_for(UNIT(s), path);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringstatic int socket_add_device_link(Socket *s) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (!s->bind_to_device || streq(s->bind_to_device, "lo"))
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering t = strjoina("/sys/subsystem/net/devices/", s->bind_to_device);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return unit_add_node_link(UNIT(s), t, false);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringstatic int socket_add_default_dependencies(Socket *s) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering_pure_ static bool socket_has_exec(Socket *s) {
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = unit_load_related_unit(u, ".service", &x);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = unit_add_exec_dependencies(u, &s->exec_context);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poetteringstatic const char *socket_find_symlink_target(Socket *s) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering const char *f = NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (p->address.sockaddr.un.sun_path[0] != 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_unit_error(UNIT(s), "Unit lacks Listen setting. Refusing.");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (s->accept && have_non_accept_socket(s)) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_unit_error(UNIT(s), "Unit configured for accepting sockets, but sockets are non-accepting. Refusing.");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (s->accept && s->max_connections <= 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_unit_error(UNIT(s), "MaxConnection= setting too small. Refusing.");
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (s->accept && UNIT_DEREF(s->service)) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering log_unit_error(UNIT(s), "Explicit service configuration for accepting socket units not supported. Refusing.");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_unit_error(UNIT(s), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing.");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!strv_isempty(s->symlinks) && !socket_find_symlink_target(s)) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_unit_error(UNIT(s), "Unit has symlinks set but none or more than one node in the file system. Refusing.");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering /* This is a new unit? Then let's add in some extras */
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering_const_ static const char* listen_lookup(int family, int type) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return "ListenNetlink";
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return "ListenStream";
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return "ListenDatagram";
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return "ListenSequentialPacket";
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert_not_reached("Unknown socket type");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic void socket_dump(Unit *u, FILE *f, const char *prefix) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sSocket State: %s\n"
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sResult: %s\n"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sBindIPv6Only: %s\n"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sBacklog: %u\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sSocketMode: %04o\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sDirectoryMode: %04o\n"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "%sKeepAlive: %s\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sNoDelay: %s\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sFreeBind: %s\n"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sTransparent: %s\n"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sBroadcast: %s\n"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "%sPassCredentials: %s\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sPassSecurity: %s\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sTCPCongestion: %s\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sRemoveOnStop: %s\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sWritable: %s\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sSELinuxContextFromNet: %s\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, socket_state_to_string(s->state),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, socket_result_to_string(s->result),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->selinux_context_from_net));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sBindToDevice: %s\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sAccepted: %u\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sNConnections: %u\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sMaxConnections: %u\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sPriority: %i\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sReceiveBuffer: %zu\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sSendBuffer: %zu\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sIPTOS: %i\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sIPTTL: %i\n",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "%sPipeSize: %zu\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sMark: %i\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sMessageQueueMaxMessages: %li\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sMessageQueueMessageSize: %li\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sReusePort: %s\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sSmackLabel: %s\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sSmackLabelIPIn: %s\n",
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek "%sSmackLabelIPOut: %s\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (!isempty(s->user) || !isempty(s->group))
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sOwnerUser: %s\n"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sOwnerGroup: %s\n",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "%sKeepAliveTimeSec: %s\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_time, USEC_PER_SEC));
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sKeepAliveIntervalSec: %s\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_interval, USEC_PER_SEC));
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sKeepAliveProbes: %u\n",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "%sDeferAcceptSec: %s\n",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->defer_accept, USEC_PER_SEC));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *t;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fprintf(f, "%sListenSpecial: %s\n", prefix, p->path);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fprintf(f, "%sListenUSBFunction: %s\n", prefix, p->path);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering prefix, socket_exec_command_to_string(c));
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers exec_command_dump_list(s->exec_command[c], f, prefix2);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int instance_from_socket(int fd, unsigned nr, char **instance) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen static const unsigned char ipv4_prefix[] = {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (memcmp(&local.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0 &&
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen memcmp(&remote.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "%u-%s:%u-%s:%u",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering } else if (k == -ENODATA) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering /* This handles the case where somebody is
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering * connecting from another pid/uid namespace
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering * (e.g. from outside of our container). */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert_not_reached("Unhandled socket type.");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering p->event_source = sd_event_source_unref(p->event_source);
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering /* One little note: we should normally not delete any
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * sockets in the file system here! After all some
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * other process we spawned might still have a
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * reference of this fd and wants to continue to use
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * it. Therefore we delete sockets in the file system
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * before we create a new one, not after we stopped
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * using one! */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic void socket_apply_socket_options(Socket *s, int fd) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &b, sizeof(b)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "SO_KEEPALIVE failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int value = s->keep_alive_time / USEC_PER_SEC;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &value, sizeof(value)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "TCP_KEEPIDLE failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int value = s->keep_alive_interval / USEC_PER_SEC;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &value, sizeof(value)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "TCP_KEEPINTVL failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &value, sizeof(value)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "TCP_KEEPCNT failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int value = s->defer_accept / USEC_PER_SEC;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_TCP, TCP_DEFER_ACCEPT, &value, sizeof(value)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "TCP_DEFER_ACCEPT failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &b, sizeof(b)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "TCP_NODELAY failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "SO_BROADCAST failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "SO_PASSCRED failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "SO_PASSSEC failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "SO_PRIORITY failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "SO_RCVBUF failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "SO_SNDBUF failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_MARK, &s->mark, sizeof(s->mark)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "SO_MARK failed: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (setsockopt(fd, IPPROTO_IP, IP_TOS, &s->ip_tos, sizeof(s->ip_tos)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "IP_TOS failed: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->ip_ttl >= 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering x = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s->ip_ttl, sizeof(s->ip_ttl));
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (r < 0 && x < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "IP_TTL/IPV6_UNICAST_HOPS failed: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "TCP_CONGESTION failed: %m");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = mac_smack_apply_fd(fd, SMACK_ATTR_IPIN, s->smack_ip_in);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_in_fd: %m");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = mac_smack_apply_fd(fd, SMACK_ATTR_IPOUT, s->smack_ip_out);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_out_fd: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void socket_apply_fifo_options(Socket *s, int fd) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_unit_warning_errno(UNIT(s), errno, "Setting pipe size failed, ignoring: %m");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = mac_smack_apply_fd(fd, SMACK_ATTR_ACCESS, s->smack);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering log_unit_error_errno(UNIT(s), r, "SMACK relabelling failed, ignoring: %m");
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering mkdir_parents_label(path, directory_mode);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = mac_selinux_create_file_prepare(path, S_IFIFO);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering /* Enforce the right access mode for the fifo */
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering /* Include the original umask in our mask */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering fd = open(path, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering (st.st_mode & 0777) != (socket_mode & ~old_mask) ||
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int special_address_create(const char *path, bool writable) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering fd = open(path, (writable ? O_RDWR : O_RDONLY)|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Check whether this is a /proc, /sys or /dev file or char device */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode))
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int usbffs_address_create(const char *path) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
bb4a228207815df88cdf68acd9e46ec19e0d3e30Lennart Poettering /* Check whether this is a regular file (ffs endpoint)*/
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering /* Enforce the right access mode for the mq */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering /* Include the original umask in our mask */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if ((st.st_mode & 0777) != (mq_mode & ~old_mask) ||
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering const char *p;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int usbffs_write_descs(int fd, Service *s) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!s->usb_function_descriptors || !s->usb_function_strings)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = copy_file_fd(s->usb_function_descriptors, fd, false);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return copy_file_fd(s->usb_function_strings, fd, false);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int usbffs_select_ep(const struct dirent *d) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return d->d_name[0] != '.' && !streq(d->d_name, "ep0");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int usbffs_dispatch_eps(SocketPort *p) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_free_ struct dirent **ent = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r, i, n, k;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = scandir(path, &ent, usbffs_select_ep, alphasort);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering for (i = 0; i < n; ++i) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering ep = path_make_absolute(ent[i]->d_name, path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->auxiliary_fds = mfree(p->auxiliary_fds);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_(mac_selinux_freep) char *label = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Figure out label, if we don't it know
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering * yet. We do it once, for the first
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering * socket where we need this and
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering * remember it for the rest. */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Get it from the network label */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0 && r != -EOPNOTSUPP)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Get it from the executable we are about to start */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = mac_selinux_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0 && r != -EPERM && r != -EOPNOTSUPP)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->fd = special_address_create(p->path, s->writable);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (p->fd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (p->fd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (p->fd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (p->fd < 0) {
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering r = usbffs_write_descs(p->fd, SERVICE(UNIT_DEREF(s->service)));
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poetteringstatic void socket_unwatch_fds(Socket *s) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_event_source_set_enabled(p->event_source, SD_EVENT_OFF);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_unit_debug_errno(UNIT(s), r, "Failed to disable event source: %m");
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt r = sd_event_source_set_enabled(p->event_source, SD_EVENT_ON);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering r = sd_event_add_io(UNIT(s)->manager->event, &p->event_source, p->fd, EPOLLIN, socket_dispatch_io, p);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering (void) sd_event_source_set_description(p->event_source, "socket-port-io");
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to watch listening fds: %m");
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poetteringstatic void socket_set_state(Socket *s, SocketState state) {
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_unit_debug(UNIT(s), "Changed %s -> %s", socket_state_to_string(old_state), socket_state_to_string(state));
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering r = unit_watch_pid(UNIT(s), s->control_pid);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (s->deserialized_state == SOCKET_LISTENING) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering socket_set_state(s, s->deserialized_state);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poetteringstatic int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering exec_params.environment = UNIT(s)->manager->environment;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering exec_params.confirm_spawn = UNIT(s)->manager->confirm_spawn;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering exec_params.cgroup_path = UNIT(s)->cgroup_path;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering exec_params.cgroup_delegate = s->cgroup_context.delegate;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering /* FIXME: we need to do something here */
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poetteringstatic int socket_chown(Socket *s, pid_t *_pid) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering /* We have to resolve the user names out-of-process, hence
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering * let's fork here. It's messy, but well, what can we do? */
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering r = get_user_creds(&user, &uid, &gid, NULL, NULL);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering path = socket_address_get_path(&p->address);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering log_error_errno(r, "Failed to chown socket at step %s: %m", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD));
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poetteringstatic void socket_enter_dead(Socket *s, SocketResult f) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->exec_runtime = exec_runtime_unref(s->exec_runtime);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poetteringstatic void socket_enter_signal(Socket *s, SocketState state, SocketResult f);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringstatic void socket_enter_stop_post(Socket *s, SocketResult f) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->control_command_id = SOCKET_EXEC_STOP_POST;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST];
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to run 'stop-post' task: %m");
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringstatic void socket_enter_signal(Socket *s, SocketState state, SocketResult f) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering (state != SOCKET_STOP_PRE_SIGTERM && state != SOCKET_FINAL_SIGTERM) ?
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering } else if (state == SOCKET_STOP_PRE_SIGTERM)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_SUCCESS);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering else if (state == SOCKET_STOP_PRE_SIGKILL)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_stop_post(s, SOCKET_SUCCESS);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_SUCCESS);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringstatic void socket_enter_stop_pre(Socket *s, SocketResult f) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command_id = SOCKET_EXEC_STOP_PRE;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE];
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_post(s, SOCKET_SUCCESS);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to run 'stop-pre' task: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_enter_listening(Socket *s) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to watch sockets: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_enter_start_post(Socket *s) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command_id = SOCKET_EXEC_START_POST;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command = s->exec_command[SOCKET_EXEC_START_POST];
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-post' task: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_enter_start_chown(Socket *s) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to listen on sockets: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!isempty(s->user) || !isempty(s->group)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command_id = SOCKET_EXEC_START_CHOWN;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to fork 'start-chown' task: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_enter_start_pre(Socket *s) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command_id = SOCKET_EXEC_START_PRE;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command = s->exec_command[SOCKET_EXEC_START_PRE];
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-pre' task: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_enter_running(Socket *s, int cfd) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* We don't take connections anymore if we are supposed to
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * shut down anyway */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(UNIT(s), "Suppressing connection request since unit stop is scheduled.");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Flush all sockets by closing and reopening them */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to listen on sockets: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to watch sockets: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* If there's already a start pending don't bother to
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * do anything */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SET_FOREACH(other, UNIT(s)->dependencies[UNIT_TRIGGERS], i)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error(UNIT(s), "Service to activate vanished, refusing activation.");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering _cleanup_free_ char *prefix = NULL, *instance = NULL, *name = NULL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (s->n_connections >= s->max_connections) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning(UNIT(s), "Too many incoming connections (%u)", s->n_connections);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = instance_from_socket(cfd, s->n_accepted, &instance);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* ENOTCONN is legitimate if TCP RST was received.
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * This connection is over, but the socket unit lives on. */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = unit_name_to_prefix(UNIT(s)->id, &prefix);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = unit_name_build(prefix, instance, ".service", &name);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = unit_add_name(UNIT_DEREF(s->service), name);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering service = SERVICE(UNIT_DEREF(s->service));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = service_set_socket_fd(service, cfd, s, s->selinux_context_from_net);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Notify clients about changed counters */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning(UNIT(s), "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s->control_command->command_next);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command = s->control_command->command_next;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to run next task: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* We cannot fulfill this request right now, try again later
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Already on it! */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Cannot run this without the service being around */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering service = SERVICE(UNIT_DEREF(s->service));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (UNIT(service)->load_state != UNIT_LOADED) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error(u, "Socket service %s not loaded, refusing.", UNIT(service)->id);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* If the service is already active we cannot start the
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering service->state != SERVICE_AUTO_RESTART) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error(u, "Socket service %s already active, refusing.", UNIT(service)->id);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Already on it */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* If there's already something running we go directly into
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * kill mode. */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_SUCCESS);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item(u, f, "state", socket_state_to_string(s->state));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item(u, f, "result", socket_result_to_string(s->result));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_address_print(&p->address, &t);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (socket_address_family(&p->address) == AF_NETLINK)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "ffs", "%i %s", copy, p->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(u, "Failed to parse state value: %s", value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(u, "Failed to parse result value: %s", value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(u, "Failed to parse n-accepted value: %s", value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(u, "Failed to parse control-pid value: %s", value);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering } else if (streq(key, "control-command")) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering id = socket_exec_command_from_string(value);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_unit_debug(u, "Failed to parse exec-command value: %s", value);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->control_command = s->exec_command[id];
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_unit_debug(u, "Failed to parse fifo value: %s", value);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering path_equal_or_files_same(p->path, value+skip))
e45fc5e738b0b7700e8b4f3c4b25c58a49b44b27Lennart Poettering if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering log_unit_debug(u, "Failed to parse special value: %s", value);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering path_equal_or_files_same(p->path, value+skip))
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering log_unit_debug(u, "Failed to parse mqueue value: %s", value);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen } else if (streq(key, "socket")) {
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(u, "Failed to parse socket value: %s", value);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (socket_address_is(&p->address, value+skip, type))
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_unit_debug(u, "Failed to parse socket value: %s", value);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (socket_address_is_netlink(&p->address, value+skip))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_unit_debug(u, "Failed to parse ffs value: %s", value);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering path_equal_or_files_same(p->path, value+skip))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_unit_debug(UNIT(s), "Unknown serialization key: %s", key);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int socket_distribute_fds(Unit *u, FDSet *fds) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (socket_address_matches_fd(&p->address, fd)) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering s->deserialized_state = SOCKET_LISTENING;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen_pure_ static UnitActiveState socket_active_state(Unit *u) {
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen return state_translation_table[SOCKET(u)->state];
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering_pure_ static const char *socket_sub_state_to_string(Unit *u) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return socket_state_to_string(SOCKET(u)->state);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringconst char* socket_port_type_to_string(SocketPort *p) {
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return "Stream";
de33fc625725d199629ed074d6278504deb23debLennart Poettering return "Datagram";
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return "SequentialPacket";
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (socket_address_family(&p->address) == AF_NETLINK)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return "Netlink";
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return "Special";
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering return "MessageQueue";
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering return "FIFO";
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return "USBFunction";
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_pure_ static bool socket_check_gc(Unit *u) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (p->socket->state != SOCKET_LISTENING)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_unit_debug(UNIT(p->socket), "Incoming traffic");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error(UNIT(p->socket), "Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that.");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error(UNIT(p->socket), "Got unexpected poll event (0x%x) on socket.", revents);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_address_can_accept(&p->address)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error_errno(UNIT(p->socket), errno, "Failed to accept socket: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering socket_apply_socket_options(p->socket, cfd);
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering socket_enter_stop_pre(p->socket, SOCKET_FAILURE_RESOURCES);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_not_reached("Unknown sigchld code");
if (s->control_command) {
f = SOCKET_SUCCESS;
if (f != SOCKET_SUCCESS)
s->result = f;
if (s->control_command &&
f == SOCKET_SUCCESS) {
socket_run_next(s);
switch (s->state) {
case SOCKET_START_PRE:
if (f == SOCKET_SUCCESS)
case SOCKET_START_CHOWN:
if (f == SOCKET_SUCCESS)
socket_enter_stop_pre(s, f);
case SOCKET_START_POST:
if (f == SOCKET_SUCCESS)
socket_enter_stop_pre(s, f);
case SOCKET_STOP_PRE:
case SOCKET_STOP_PRE_SIGTERM:
case SOCKET_STOP_PRE_SIGKILL:
socket_enter_stop_post(s, f);
case SOCKET_STOP_POST:
case SOCKET_FINAL_SIGTERM:
case SOCKET_FINAL_SIGKILL:
socket_enter_dead(s, f);
assert(s);
switch (s->state) {
case SOCKET_START_PRE:
case SOCKET_START_CHOWN:
case SOCKET_START_POST:
case SOCKET_STOP_PRE:
case SOCKET_STOP_PRE_SIGTERM:
case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST:
case SOCKET_FINAL_SIGTERM:
case SOCKET_FINAL_SIGKILL:
int *rfds;
unsigned rn_fds, k;
SocketPort *p;
assert(s);
rn_fds = 0;
if (p->fd >= 0)
rn_fds++;
if (rn_fds <= 0) {
*n_fds = 0;
if (!rfds)
return -ENOMEM;
if (p->fd >= 0)
for (i = 0; i < p->n_auxiliary_fds; ++i)
assert(s);
assert(s);
log_unit_debug(UNIT(s), "Got notified about service death (failed permanently: %s)", yes_no(failed_permanent));
if (failed_permanent)
assert(s);
s->n_connections--;
assert(u);
s->accept)
socket_notify_service_dead(s, false);
if (!s->timer_event_source)
.sections =
.finished_start_job = {
.finished_stop_job = {