socket.c revision 6ec4ed645e37ba7dd5628747ea78ec1663599ab7
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2010 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart 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
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
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/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
8bdbb8d9cbe1d35708385573d70984ab4533812dLennart Poettering#include <arpa/inet.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <fcntl.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <mqueue.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <netinet/tcp.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <signal.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/epoll.h>
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering#include <sys/stat.h>
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering#include <unistd.h>
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering#include "sd-event.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering#include "bus-error.h"
d538bfc71331d2e48363283decd77a61599021dbCristian Rodríguez#include "bus-util.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "copy.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "dbus-socket.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "def.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "exit-status.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "formats-util.h"
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering#include "label.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "log.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "missing.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "mkdir.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "path-util.h"
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#include "selinux-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "signal-util.h"
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering#include "smack-util.h"
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering#include "socket.h"
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering#include "special.h"
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering#include "strv.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "unit-name.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "unit-printf.h"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering#include "unit.h"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [SOCKET_DEAD] = UNIT_INACTIVE,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [SOCKET_START_PRE] = UNIT_ACTIVATING,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [SOCKET_START_CHOWN] = UNIT_ACTIVATING,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [SOCKET_START_POST] = UNIT_ACTIVATING,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [SOCKET_LISTENING] = UNIT_ACTIVE,
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen [SOCKET_RUNNING] = UNIT_ACTIVE,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING,
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering [SOCKET_FAILED] = UNIT_FAILED
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering};
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
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);
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_init(Unit *u) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Socket *s = SOCKET(u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(u->load_state == UNIT_STUB);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s->backlog = SOMAXCONN;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s->timeout_usec = u->manager->default_timeout_start_usec;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s->directory_mode = 0755;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s->socket_mode = 0666;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->max_connections = 64;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->priority = -1;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->ip_tos = -1;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->ip_ttl = -1;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->mark = -1;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
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
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering}
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poetteringstatic void socket_unwatch_control_pid(Socket *s) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering assert(s);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (s->control_pid <= 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering unit_unwatch_pid(UNIT(s), s->control_pid);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering s->control_pid = 0;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poetteringstatic void socket_cleanup_fd_list(SocketPort *p) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering int k = p->n_auxiliary_fds;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering while (k--)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering safe_close(p->auxiliary_fds[k]);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering p->auxiliary_fds = mfree(p->auxiliary_fds);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering p->n_auxiliary_fds = 0;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringvoid socket_free_ports(Socket *s) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering SocketPort *p;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen assert(s);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering while ((p = s->ports)) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen LIST_REMOVE(port, s->ports, p);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_event_source_unref(p->event_source);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering socket_cleanup_fd_list(p);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering safe_close(p->fd);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering free(p->path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(p);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic void socket_done(Unit *u) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen Socket *s = SOCKET(u);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen assert(s);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen socket_free_ports(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
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->control_command = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering socket_unwatch_control_pid(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen unit_ref_unset(&s->service);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s->tcp_congestion = mfree(s->tcp_congestion);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen s->bind_to_device = mfree(s->bind_to_device);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering free(s->smack);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering free(s->smack_ip_in);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering free(s->smack_ip_out);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering strv_free(s->symlinks);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering free(s->user);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering free(s->group);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poetteringstatic int socket_arm_timer(Socket *s) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering int r;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering assert(s);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (s->timeout_usec <= 0) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return 0;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (s->timer_event_source) {
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering r = sd_event_add_time(
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering UNIT(s)->manager->event,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering &s->timer_event_source,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering CLOCK_MONOTONIC,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering now(CLOCK_MONOTONIC) + s->timeout_usec, 0,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering socket_dispatch_timer, s);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (r < 0)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return r;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering (void) sd_event_source_set_description(s->timer_event_source, "socket-timer");
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return 0;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poetteringint socket_instantiate_service(Socket *s) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *prefix = NULL, *name = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Unit *u;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(s);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
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. */
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (UNIT_DEREF(s->service))
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!s->accept)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = unit_name_to_prefix(UNIT(s)->id, &prefix);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (asprintf(&name, "%s@%u.service", prefix, s->n_accepted) < 0)
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering return -ENOMEM;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = manager_load_unit(UNIT(s)->manager, name, NULL, NULL, &u);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering u->no_gc = true;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering unit_ref_set(&s->service, u);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic bool have_non_accept_socket(Socket *s) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering SocketPort *p;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(s);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!s->accept)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return true;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering LIST_FOREACH(port, p, s->ports) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (p->type != SOCKET_SOCKET)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return true;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!socket_address_can_accept(&p->address))
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return true;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return false;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringstatic int socket_add_mount_links(Socket *s) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering SocketPort *p;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(s);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering LIST_FOREACH(port, p, s->ports) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering const char *path = NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (p->type == SOCKET_SOCKET)
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 path = p->path;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (!path)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering continue;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering r = unit_require_mounts_for(UNIT(s), path);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringstatic int socket_add_device_link(Socket *s) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering char *t;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering assert(s);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (!s->bind_to_device || streq(s->bind_to_device, "lo"))
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return 0;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering t = strjoina("/sys/subsystem/net/devices/", s->bind_to_device);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return unit_add_node_link(UNIT(s), t, false);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringstatic int socket_add_default_dependencies(Socket *s) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering int r;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering assert(s);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
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 if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering_pure_ static bool socket_has_exec(Socket *s) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering unsigned i;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering assert(s);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (s->exec_command[i])
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return true;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return false;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering}
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringstatic int socket_add_extras(Socket *s) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering Unit *u = UNIT(s);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int r;
8937e7b68940d0fa0d0aab90eb7425fa7dccebc9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering assert(s);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (have_non_accept_socket(s)) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!UNIT_DEREF(s->service)) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering Unit *x;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = unit_load_related_unit(u, ".service", &x);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering unit_ref_set(&s->service, x);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = socket_add_mount_links(s);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = socket_add_device_link(s);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = unit_patch_contexts(u);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (socket_has_exec(s)) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = unit_add_exec_dependencies(u, &s->exec_context);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (r < 0)
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = unit_set_default_slice(u);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (u->default_dependencies) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = socket_add_default_dependencies(s);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (r < 0)
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return r;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering return 0;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering}
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poetteringstatic const char *socket_find_symlink_target(Socket *s) {
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering const char *found = NULL;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering SocketPort *p;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering LIST_FOREACH(port, p, s->ports) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering const char *f = NULL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering switch (p->type) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering case SOCKET_FIFO:
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering f = p->path;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering break;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering case SOCKET_SOCKET:
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (p->address.sockaddr.un.sun_path[0] != 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering f = p->address.sockaddr.un.sun_path;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering break;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering default:
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering break;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (f) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (found)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering found = f;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return found;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poetteringstatic int socket_verify(Socket *s) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(s);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (UNIT(s)->load_state != UNIT_LOADED)
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return 0;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!s->ports) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_unit_error(UNIT(s), "Unit lacks Listen setting. Refusing.");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
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 return -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (s->accept && s->max_connections <= 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_unit_error(UNIT(s), "MaxConnection= setting too small. Refusing.");
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return -EINVAL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
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 return -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
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 return -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
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.");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic int socket_load(Unit *u) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering Socket *s = SOCKET(u);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering int r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(u);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(u->load_state == UNIT_STUB);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = unit_load_fragment_and_dropin(u);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (u->load_state == UNIT_LOADED) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering /* This is a new unit? Then let's add in some extras */
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = socket_add_extras(s);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return socket_verify(s);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering_const_ static const char* listen_lookup(int family, int type) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (family == AF_NETLINK)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return "ListenNetlink";
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (type == SOCK_STREAM)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return "ListenStream";
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering else if (type == SOCK_DGRAM)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return "ListenDatagram";
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering else if (type == SOCK_SEQPACKET)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return "ListenSequentialPacket";
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert_not_reached("Unknown socket type");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic void socket_dump(Unit *u, FILE *f, const char *prefix) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering char time_string[FORMAT_TIMESPAN_MAX];
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering SocketExecCommand c;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering Socket *s = SOCKET(u);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering SocketPort *p;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering const char *prefix2;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(s);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert(f);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers prefix = strempty(prefix);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers prefix2 = strjoina(prefix, "\t");
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fprintf(f,
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, s->backlog,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering prefix, s->socket_mode,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering prefix, s->directory_mode,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->keep_alive),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->no_delay),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->free_bind),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->transparent),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->broadcast),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->pass_cred),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->pass_sec),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, strna(s->tcp_congestion),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->remove_on_stop),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->writable),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->selinux_context_from_net));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->control_pid > 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sControl PID: "PID_FMT"\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, s->control_pid);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->bind_to_device)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sBindToDevice: %s\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, s->bind_to_device);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->accept)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sAccepted: %u\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sNConnections: %u\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "%sMaxConnections: %u\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, s->n_accepted,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, s->n_connections,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, s->max_connections);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (s->priority >= 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fprintf(f,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sPriority: %i\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, s->priority);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (s->receive_buffer > 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fprintf(f,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sReceiveBuffer: %zu\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, s->receive_buffer);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (s->send_buffer > 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fprintf(f,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sSendBuffer: %zu\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, s->send_buffer);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (s->ip_tos >= 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fprintf(f,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sIPTOS: %i\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, s->ip_tos);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (s->ip_ttl >= 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fprintf(f,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sIPTTL: %i\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, s->ip_ttl);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (s->pipe_size > 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering fprintf(f,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "%sPipeSize: %zu\n",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering prefix, s->pipe_size);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (s->mark >= 0)
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering fprintf(f,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sMark: %i\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering prefix, s->mark);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (s->mq_maxmsg > 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering fprintf(f,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sMessageQueueMaxMessages: %li\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering prefix, s->mq_maxmsg);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (s->mq_msgsize > 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering fprintf(f,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sMessageQueueMessageSize: %li\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering prefix, s->mq_msgsize);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (s->reuse_port)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering fprintf(f,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sReusePort: %s\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix, yes_no(s->reuse_port));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->smack)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fprintf(f,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sSmackLabel: %s\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, s->smack);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (s->smack_ip_in)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fprintf(f,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sSmackLabelIPIn: %s\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, s->smack_ip_in);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (s->smack_ip_out)
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek fprintf(f,
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek "%sSmackLabelIPOut: %s\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, s->smack_ip_out);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (!isempty(s->user) || !isempty(s->group))
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fprintf(f,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sOwnerUser: %s\n"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "%sOwnerGroup: %s\n",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, strna(s->user),
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering prefix, strna(s->group));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->keep_alive_time > 0)
a6c616024db23fef34152c1432892824a07799ccLennart Poettering fprintf(f,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "%sKeepAliveTimeSec: %s\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_time, USEC_PER_SEC));
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (s->keep_alive_interval)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering fprintf(f,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sKeepAliveIntervalSec: %s\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_interval, USEC_PER_SEC));
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (s->keep_alive_cnt)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering fprintf(f,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "%sKeepAliveProbes: %u\n",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers prefix, s->keep_alive_cnt);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
a6c616024db23fef34152c1432892824a07799ccLennart Poettering if (s->defer_accept)
a6c616024db23fef34152c1432892824a07799ccLennart Poettering fprintf(f,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "%sDeferAcceptSec: %s\n",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->defer_accept, USEC_PER_SEC));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering LIST_FOREACH(port, p, s->ports) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (p->type == SOCKET_SOCKET) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *t;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers int r;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers char *k = NULL;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = socket_address_print(&p->address, &k);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt t = strerror(-r);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering t = k;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(k);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (p->type == SOCKET_SPECIAL)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fprintf(f, "%sListenSpecial: %s\n", prefix, p->path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (p->type == SOCKET_USB_FUNCTION)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fprintf(f, "%sListenUSBFunction: %s\n", prefix, p->path);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers else if (p->type == SOCKET_MQUEUE)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering else
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers exec_context_dump(&s->exec_context, f, prefix);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers kill_context_dump(&s->kill_context, f, prefix);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (!s->exec_command[c])
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering continue;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering fprintf(f, "%s-> %s:\n",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering prefix, socket_exec_command_to_string(c));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers exec_command_dump_list(s->exec_command[c], f, prefix2);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int instance_from_socket(int fd, unsigned nr, char **instance) {
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters socklen_t l;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen char *r;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt union sockaddr_union local, remote;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering assert(fd >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(instance);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering l = sizeof(local);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (getsockname(fd, &local.sa, &l) < 0)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return -errno;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers l = sizeof(remote);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (getpeername(fd, &remote.sa, &l) < 0)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return -errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering switch (local.sa.sa_family) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering case AF_INET: {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint32_t
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering a = ntohl(local.in.sin_addr.s_addr),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering b = ntohl(remote.in.sin_addr.s_addr);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (asprintf(&r,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering nr,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
8c841f21f5042b11acc91cc1b039cb162cbbe8f4Djalal Harouni ntohs(local.in.sin_port),
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ntohs(remote.in.sin_port)) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen case AF_INET6: {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen static const unsigned char ipv4_prefix[] = {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen };
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
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) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering const uint8_t
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen *a = local.in6.sin6_addr.s6_addr+12,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen *b = remote.in6.sin6_addr.s6_addr+12;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (asprintf(&r,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen nr,
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering a[0], a[1], a[2], a[3],
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering ntohs(local.in6.sin6_port),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering b[0], b[1], b[2], b[3],
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers ntohs(remote.in6.sin6_port)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -ENOMEM;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers } else {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (asprintf(&r,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "%u-%s:%u-%s:%u",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering nr,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering ntohs(local.in6.sin6_port),
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering ntohs(remote.in6.sin6_port)) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -ENOMEM;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering }
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering case AF_UNIX: {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering struct ucred ucred;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int k;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering k = getpeercred(fd, &ucred);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (k >= 0) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (asprintf(&r,
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering "%u-"PID_FMT"-"UID_FMT,
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering nr, ucred.pid, ucred.uid) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -ENOMEM;
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 if (asprintf(&r,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "%u-unknown",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering nr) < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -ENOMEM;
9a14fb6285bdb089d4fc195410de3362cb4f586fThomas Hindoe Paaboel Andersen } else
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return k;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering default:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert_not_reached("Unhandled socket type.");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering *instance = r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return 0;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic void socket_close_fds(Socket *s) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering SocketPort *p;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char **i;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(s);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering LIST_FOREACH(port, p, s->ports) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering p->event_source = sd_event_source_unref(p->event_source);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (p->fd < 0)
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering continue;
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering p->fd = safe_close(p->fd);
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering socket_cleanup_fd_list(p);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
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! */
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->remove_on_stop) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering switch (p->type) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case SOCKET_FIFO:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering unlink(p->path);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering break;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering case SOCKET_MQUEUE:
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering mq_unlink(p->path);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering break;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering case SOCKET_SOCKET:
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering socket_address_unlink(&p->address);
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering break;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering default:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->remove_on_stop)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering STRV_FOREACH(i, s->symlinks)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering unlink(*i);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic void socket_apply_socket_options(Socket *s, int fd) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(s);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(fd >= 0);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->keep_alive) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int b = s->keep_alive;
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->keep_alive_time) {
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->keep_alive_interval) {
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->keep_alive_cnt) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int value = s->keep_alive_cnt;
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->defer_accept) {
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->no_delay) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int b = s->no_delay;
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->broadcast) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int one = 1;
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->pass_cred) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int one = 1;
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->pass_sec) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int one = 1;
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->priority >= 0)
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
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->receive_buffer > 0) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int value = (int) s->receive_buffer;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->send_buffer > 0) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int value = (int) s->send_buffer;
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 }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->mark >= 0)
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
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s->ip_tos >= 0)
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
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->ip_ttl >= 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers int x;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (socket_ipv6_is_supported())
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering x = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s->ip_ttl, sizeof(s->ip_ttl));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering else {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering x = -1;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering errno = EAFNOSUPPORT;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
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 }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (s->tcp_congestion)
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");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (s->smack_ip_in) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = mac_smack_apply_fd(fd, SMACK_ATTR_IPIN, s->smack_ip_in);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_in_fd: %m");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (s->smack_ip_out) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = mac_smack_apply_fd(fd, SMACK_ATTR_IPOUT, s->smack_ip_out);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_out_fd: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void socket_apply_fifo_options(Socket *s, int fd) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(s);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(fd >= 0);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering if (s->pipe_size > 0)
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");
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->smack) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = mac_smack_apply_fd(fd, SMACK_ATTR_ACCESS, s->smack);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering if (r < 0)
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering log_unit_error_errno(UNIT(s), r, "SMACK relabelling failed, ignoring: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int fifo_address_create(
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering const char *path,
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering mode_t directory_mode,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering mode_t socket_mode) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering _cleanup_close_ int fd = -1;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering mode_t old_mask;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering struct stat st;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering int r;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(path);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering mkdir_parents_label(path, directory_mode);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = mac_selinux_create_file_prepare(path, S_IFIFO);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (r < 0)
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering return r;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering /* Enforce the right access mode for the fifo */
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering old_mask = umask(~ socket_mode);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering /* Include the original umask in our mask */
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering (void) umask(~socket_mode | old_mask);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = mkfifo(path, socket_mode);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering (void) umask(old_mask);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (r < 0 && errno != EEXIST) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = -errno;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering goto fail;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering fd = open(path, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (fd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = -errno;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto fail;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mac_selinux_create_file_clear();
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (fstat(fd, &st) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = -errno;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto fail;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!S_ISFIFO(st.st_mode) ||
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering (st.st_mode & 0777) != (socket_mode & ~old_mask) ||
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering st.st_uid != getuid() ||
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering st.st_gid != getgid()) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = -EEXIST;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto fail;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = fd;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering fd = -1;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringfail:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mac_selinux_create_file_clear();
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int special_address_create(const char *path, bool writable) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_close_ int fd = -1;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering struct stat st;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering fd = open(path, (writable ? O_RDWR : O_RDONLY)|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (fd < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -errno;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (fstat(fd, &st) < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -errno;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
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))
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -EEXIST;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = fd;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering fd = -1;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int usbffs_address_create(const char *path) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _cleanup_close_ int fd = -1;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering struct stat st;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int r;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(path);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (fd < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -errno;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (fstat(fd, &st) < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -errno;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
bb4a228207815df88cdf68acd9e46ec19e0d3e30Lennart Poettering /* Check whether this is a regular file (ffs endpoint)*/
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (!S_ISREG(st.st_mode))
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -EEXIST;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
bb4a228207815df88cdf68acd9e46ec19e0d3e30Lennart Poettering r = fd;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering fd = -1;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return r;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int mq_address_create(
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering const char *path,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering mode_t mq_mode,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering long maxmsg,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering long msgsize) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _cleanup_close_ int fd = -1;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering struct stat st;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering mode_t old_mask;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering struct mq_attr _attr, *attr = NULL;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert(path);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (maxmsg > 0 && msgsize > 0) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _attr = (struct mq_attr) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering .mq_flags = O_NONBLOCK,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering .mq_maxmsg = maxmsg,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering .mq_msgsize = msgsize,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering };
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering attr = &_attr;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering /* Enforce the right access mode for the mq */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering old_mask = umask(~ mq_mode);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering /* Include the original umask in our mask */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering (void) umask(~mq_mode | old_mask);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering (void) umask(old_mask);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (fd < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -errno;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (fstat(fd, &st) < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -errno;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if ((st.st_mode & 0777) != (mq_mode & ~old_mask) ||
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering st.st_uid != getuid() ||
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering st.st_gid != getgid())
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -EEXIST;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = fd;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering fd = -1;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int socket_symlink(Socket *s) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering const char *p;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering char **i;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert(s);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering p = socket_find_symlink_target(s);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (!p)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return 0;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering STRV_FOREACH(i, s->symlinks)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering symlink_label(p, *i);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int usbffs_write_descs(int fd, Service *s) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!s->usb_function_descriptors || !s->usb_function_strings)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -EINVAL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = copy_file_fd(s->usb_function_descriptors, fd, false);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return copy_file_fd(s->usb_function_strings, fd, false);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int usbffs_select_ep(const struct dirent *d) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return d->d_name[0] != '.' && !streq(d->d_name, "ep0");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int usbffs_dispatch_eps(SocketPort *p) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_free_ struct dirent **ent = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_free_ char *path = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r, i, n, k;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = path_get_parent(p->path, &path);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = scandir(path, &ent, usbffs_select_ep, alphasort);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -errno;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering n = r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->auxiliary_fds = new(int, n);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!p->auxiliary_fds)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -ENOMEM;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->n_auxiliary_fds = n;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering k = 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering for (i = 0; i < n; ++i) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_free_ char *ep = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering ep = path_make_absolute(ent[i]->d_name, path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!ep)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -ENOMEM;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering path_kill_slashes(ep);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = usbffs_address_create(ep);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto fail;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->auxiliary_fds[k] = r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering ++k;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering free(ent[i]);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringfail:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering close_many(p->auxiliary_fds, k);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->auxiliary_fds = mfree(p->auxiliary_fds);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->n_auxiliary_fds = 0;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int socket_open_fds(Socket *s) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_(mac_selinux_freep) char *label = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering bool know_label = false;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering SocketPort *p;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(s);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering LIST_FOREACH(port, p, s->ports) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (p->fd >= 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering continue;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering switch (p->type) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering case SOCKET_SOCKET:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!know_label) {
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
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (s->selinux_context_from_net) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Get it from the network label */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = mac_selinux_get_our_label(&label);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0 && r != -EOPNOTSUPP)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto rollback;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering } else {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Get it from the executable we are about to start */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = socket_instantiate_service(s);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto rollback;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (UNIT_ISSET(s->service) &&
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 goto rollback;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering know_label = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = socket_address_listen(
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &p->address,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering SOCK_CLOEXEC|SOCK_NONBLOCK,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->backlog,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->bind_ipv6_only,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->bind_to_device,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->reuse_port,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->free_bind,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->transparent,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->directory_mode,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->socket_mode,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering label);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto rollback;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->fd = r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering socket_apply_socket_options(s, p->fd);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering socket_symlink(s);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering break;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering case SOCKET_SPECIAL:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->fd = special_address_create(p->path, s->writable);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (p->fd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = p->fd;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto rollback;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering break;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering case SOCKET_FIFO:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->fd = fifo_address_create(
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->path,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->directory_mode,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->socket_mode);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (p->fd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = p->fd;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto rollback;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering socket_apply_fifo_options(s, p->fd);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering socket_symlink(s);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering break;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering case SOCKET_MQUEUE:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->fd = mq_address_create(
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->path,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->socket_mode,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->mq_maxmsg,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering s->mq_msgsize);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (p->fd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = p->fd;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto rollback;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering break;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering case SOCKET_USB_FUNCTION:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p->fd = usbffs_address_create(p->path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (p->fd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = p->fd;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto rollback;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering }
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering r = usbffs_write_descs(p->fd, SERVICE(UNIT_DEREF(s->service)));
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering if (r < 0)
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering goto rollback;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering r = usbffs_dispatch_eps(p);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering if (r < 0)
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering goto rollback;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering break;
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering default:
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering assert_not_reached("Unknown port type");
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering }
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering }
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering return 0;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poetteringrollback:
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering socket_close_fds(s);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering return r;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering}
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poetteringstatic void socket_unwatch_fds(Socket *s) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering SocketPort *p;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int r;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering assert(s);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering LIST_FOREACH(port, p, s->ports) {
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering if (p->fd < 0)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering continue;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!p->event_source)
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering continue;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_event_source_set_enabled(p->event_source, SD_EVENT_OFF);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_unit_debug_errno(UNIT(s), r, "Failed to disable event source: %m");
bf441e3d9371a7e5aa1def66cfc40f0118884644Lennart Poettering }
de33fc625725d199629ed074d6278504deb23debLennart Poettering}
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int socket_watch_fds(Socket *s) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering SocketPort *p;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int r;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering assert(s);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt LIST_FOREACH(port, p, s->ports) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (p->fd < 0)
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering continue;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (p->event_source) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt r = sd_event_source_set_enabled(p->event_source, SD_EVENT_ON);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (r < 0)
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering goto fail;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering } else {
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering r = sd_event_add_io(UNIT(s)->manager->event, &p->event_source, p->fd, EPOLLIN, socket_dispatch_io, p);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering if (r < 0)
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering goto fail;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering (void) sd_event_source_set_description(p->event_source, "socket-port-io");
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering }
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering }
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering return 0;
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poetteringfail:
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to watch listening fds: %m");
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering socket_unwatch_fds(s);
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering return r;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering}
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poetteringstatic void socket_set_state(Socket *s, SocketState state) {
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering SocketState old_state;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering assert(s);
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering old_state = s->state;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering s->state = state;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering if (!IN_SET(state,
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering SOCKET_START_PRE,
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering SOCKET_START_CHOWN,
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering SOCKET_START_POST,
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering SOCKET_STOP_PRE,
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering SOCKET_STOP_PRE_SIGTERM,
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering SOCKET_STOP_PRE_SIGKILL,
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering SOCKET_STOP_POST,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering SOCKET_FINAL_SIGTERM,
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering SOCKET_FINAL_SIGKILL)) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering socket_unwatch_control_pid(s);
ee451d766a64117a41ec36dd71e61683c9d9b83cLennart Poettering s->control_command = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (state != SOCKET_LISTENING)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering socket_unwatch_fds(s);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!IN_SET(state,
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering SOCKET_START_CHOWN,
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering SOCKET_START_POST,
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering SOCKET_LISTENING,
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering SOCKET_RUNNING,
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt SOCKET_STOP_PRE,
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt SOCKET_STOP_PRE_SIGTERM,
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering SOCKET_STOP_PRE_SIGKILL))
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering socket_close_fds(s);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (state != old_state)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_unit_debug(UNIT(s), "Changed %s -> %s", socket_state_to_string(old_state), socket_state_to_string(state));
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
da054c3782f25b3b18243f6c76dcfcf90ba70274Lennart Poettering unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering}
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic int socket_coldplug(Unit *u) {
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering Socket *s = SOCKET(u);
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering int r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering assert(s);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering assert(s->state == SOCKET_DEAD);
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering
0ec5543c4c0318552a4dcdd83210793347b93081Lennart Poettering if (s->deserialized_state == s->state)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 0;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (IN_SET(s->deserialized_state,
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering SOCKET_START_PRE,
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering SOCKET_START_CHOWN,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_START_POST,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_STOP_PRE,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_STOP_PRE_SIGTERM,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering SOCKET_STOP_PRE_SIGKILL,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_STOP_POST,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_FINAL_SIGTERM,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_FINAL_SIGKILL)) {
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (s->control_pid <= 0)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering return -EBADMSG;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering r = unit_watch_pid(UNIT(s), s->control_pid);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (r < 0)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering return r;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering r = socket_arm_timer(s);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (r < 0)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering return r;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering }
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (IN_SET(s->deserialized_state,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_START_CHOWN,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_START_POST,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_LISTENING,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_RUNNING,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_STOP_PRE,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_STOP_PRE_SIGTERM,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering SOCKET_STOP_PRE_SIGKILL)) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = socket_open_fds(s);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (s->deserialized_state == SOCKET_LISTENING) {
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering r = socket_watch_fds(s);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering socket_set_state(s, s->deserialized_state);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return 0;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering}
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poetteringstatic int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering _cleanup_free_ char **argv = NULL;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering pid_t pid;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering int r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering ExecParameters exec_params = {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering .apply_permissions = true,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering .apply_chroot = true,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering .apply_tty_stdin = true,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering .bus_endpoint_fd = -1,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering };
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering assert(s);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering assert(c);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering assert(_pid);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering (void) unit_realize_cgroup(UNIT(s));
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (s->reset_cpu_usage) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering (void) unit_reset_cpu_usage(UNIT(s));
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering s->reset_cpu_usage = false;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = unit_setup_exec_runtime(UNIT(s));
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering goto fail;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = socket_arm_timer(s);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering goto fail;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering goto fail;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering exec_params.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
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = exec_spawn(UNIT(s),
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering c,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering &s->exec_context,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering &exec_params,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering s->exec_runtime,
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering &pid);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering goto fail;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = unit_watch_pid(UNIT(s), pid);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering /* FIXME: we need to do something here */
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering goto fail;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering *_pid = pid;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return 0;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poetteringfail:
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering}
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poetteringstatic int socket_chown(Socket *s, pid_t *_pid) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering pid_t pid;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering int r;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering r = socket_arm_timer(s);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (r < 0)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering goto fail;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
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? */
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering pid = fork();
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (pid < 0)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering return -errno;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (pid == 0) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering SocketPort *p;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering uid_t uid = UID_INVALID;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering gid_t gid = GID_INVALID;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering int ret;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering (void) ignore_signals(SIGPIPE, -1);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering log_forget_fds();
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (!isempty(s->user)) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering const char *user = s->user;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering r = get_user_creds(&user, &uid, &gid, NULL, NULL);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (r < 0) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering ret = EXIT_USER;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering goto fail_child;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (!isempty(s->group)) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering const char *group = s->group;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering r = get_group_creds(&group, &gid);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (r < 0) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering ret = EXIT_GROUP;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering goto fail_child;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering LIST_FOREACH(port, p, s->ports) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering const char *path = NULL;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (p->type == SOCKET_SOCKET)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering path = socket_address_get_path(&p->address);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering else if (p->type == SOCKET_FIFO)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering path = p->path;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (!path)
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering continue;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (chown(path, uid, gid) < 0) {
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering r = -errno;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering ret = EXIT_CHOWN;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering goto fail_child;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering _exit(0);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering fail_child:
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering log_open();
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering log_error_errno(r, "Failed to chown socket at step %s: %m", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD));
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering _exit(ret);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering }
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering r = unit_watch_pid(UNIT(s), pid);
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering if (r < 0)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering goto fail;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering *_pid = pid;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return 0;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringfail:
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->timer_event_source = sd_event_source_unref(s->timer_event_source);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return r;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering}
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poetteringstatic void socket_enter_dead(Socket *s, SocketResult f) {
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering assert(s);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (f != SOCKET_SUCCESS)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->result = f;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering exec_runtime_destroy(s->exec_runtime);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->exec_runtime = exec_runtime_unref(s->exec_runtime);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering}
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poetteringstatic void socket_enter_signal(Socket *s, SocketState state, SocketResult f);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringstatic void socket_enter_stop_post(Socket *s, SocketResult f) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering int r;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering assert(s);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (f != SOCKET_SUCCESS)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->result = f;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_unwatch_control_pid(s);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->control_command_id = SOCKET_EXEC_STOP_POST;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST];
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (s->control_command) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (r < 0)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering goto fail;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_set_state(s, SOCKET_STOP_POST);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering } else
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringfail:
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 Poettering}
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringstatic void socket_enter_signal(Socket *s, SocketState state, SocketResult f) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering int r;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering assert(s);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (f != SOCKET_SUCCESS)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->result = f;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering r = unit_kill_context(
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering UNIT(s),
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering &s->kill_context,
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering (state != SOCKET_STOP_PRE_SIGTERM && state != SOCKET_FINAL_SIGTERM) ?
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering KILL_KILL : KILL_TERMINATE,
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering -1,
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->control_pid,
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering false);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (r < 0)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering goto fail;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (r > 0) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering r = socket_arm_timer(s);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (r < 0)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering goto fail;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_set_state(s, state);
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 else if (state == SOCKET_FINAL_SIGTERM)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_SUCCESS);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering else
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_dead(s, SOCKET_SUCCESS);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringfail:
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
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 else
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering}
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poetteringstatic void socket_enter_stop_pre(Socket *s, SocketResult f) {
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering int r;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering assert(s);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering if (f != SOCKET_SUCCESS)
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering s->result = f;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_unwatch_control_pid(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command_id = SOCKET_EXEC_STOP_PRE;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE];
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (s->control_command) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_set_state(s, SOCKET_STOP_PRE);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_post(s, SOCKET_SUCCESS);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringfail:
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 Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_enter_listening(Socket *s) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_watch_fds(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to watch sockets: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_set_state(s, SOCKET_LISTENING);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringfail:
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_enter_start_post(Socket *s) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_unwatch_control_pid(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
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (s->control_command) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-post' task: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_set_state(s, SOCKET_START_POST);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_listening(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringfail:
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_enter_start_chown(Socket *s) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_open_fds(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to listen on sockets: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!isempty(s->user) || !isempty(s->group)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_unwatch_control_pid(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command_id = SOCKET_EXEC_START_CHOWN;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command = NULL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_chown(s, &s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to fork 'start-chown' task: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_set_state(s, SOCKET_START_CHOWN);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_start_post(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringfail:
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_enter_start_pre(Socket *s) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_unwatch_control_pid(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
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (s->control_command) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-pre' task: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_set_state(s, SOCKET_START_PRE);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_start_chown(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringfail:
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
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 int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* We don't take connections anymore if we are supposed to
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * shut down anyway */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (unit_stop_pending(UNIT(s))) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(UNIT(s), "Suppressing connection request since unit stop is scheduled.");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (cfd >= 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering safe_close(cfd);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Flush all sockets by closing and reopening them */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_close_fds(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_open_fds(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0) {
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 return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_watch_fds(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0) {
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 }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (cfd < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Iterator i;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Unit *other;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering bool pending = false;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
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 if (unit_active_or_pending(other)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering pending = true;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering break;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!pending) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (!UNIT_ISSET(s->service)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error(UNIT(s), "Service to activate vanished, refusing activation.");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = -ENOENT;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_set_state(s, SOCKET_RUNNING);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering _cleanup_free_ char *prefix = NULL, *instance = NULL, *name = NULL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Service *service;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
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 safe_close(cfd);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_instantiate_service(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = instance_from_socket(cfd, s->n_accepted, &instance);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r != -ENOTCONN)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* ENOTCONN is legitimate if TCP RST was received.
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * This connection is over, but the socket unit lives on. */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering safe_close(cfd);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = unit_name_to_prefix(UNIT(s)->id, &prefix);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = unit_name_build(prefix, instance, ".service", &name);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = unit_add_name(UNIT_DEREF(s->service), name);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering service = SERVICE(UNIT_DEREF(s->service));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_ref_unset(&s->service);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->n_accepted ++;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering UNIT(service)->no_gc = false;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_choose_id(UNIT(service), name);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = service_set_socket_fd(service, cfd, s, s->selinux_context_from_net);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering cfd = -1;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->n_connections ++;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Notify clients about changed counters */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_add_to_dbus_queue(UNIT(s));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringfail:
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 cfd >= 0 ? "template" : "non-template",
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering bus_error_message(&error, r));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering safe_close(cfd);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic void socket_run_next(Socket *s) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s->control_command);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s->control_command->command_next);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_unwatch_control_pid(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->control_command = s->control_command->command_next;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringfail:
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_warning_errno(UNIT(s), r, "Failed to run next task: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (s->state == SOCKET_START_POST)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else if (s->state == SOCKET_STOP_POST)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic int socket_start(Unit *u) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Socket *s = SOCKET(u);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* We cannot fulfill this request right now, try again later
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * please! */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (IN_SET(s->state,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_STOP_PRE,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_STOP_PRE_SIGKILL,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_STOP_PRE_SIGTERM,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_STOP_POST,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_FINAL_SIGTERM,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_FINAL_SIGKILL))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EAGAIN;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Already on it! */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (IN_SET(s->state,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_START_PRE,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_START_CHOWN,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_START_POST))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Cannot run this without the service being around */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (UNIT_ISSET(s->service)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Service *service;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering service = SERVICE(UNIT_DEREF(s->service));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
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 return -ENOENT;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* If the service is already active we cannot start the
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering * socket */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (service->state != SERVICE_DEAD &&
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering service->state != SERVICE_FAILED &&
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering service->state != SERVICE_AUTO_RESTART) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error(u, "Socket service %s already active, refusing.", UNIT(service)->id);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EBUSY;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->result = SOCKET_SUCCESS;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->reset_cpu_usage = true;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_start_pre(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 1;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic int socket_stop(Unit *u) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Socket *s = SOCKET(u);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* Already on it */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (IN_SET(s->state,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_STOP_PRE,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_STOP_PRE_SIGTERM,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_STOP_PRE_SIGKILL,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_STOP_POST,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_FINAL_SIGTERM,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_FINAL_SIGKILL))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering /* If there's already something running we go directly into
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering * kill mode. */
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (IN_SET(s->state,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_START_PRE,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_START_CHOWN,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SOCKET_START_POST)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EAGAIN;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_enter_stop_pre(s, SOCKET_SUCCESS);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 1;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Socket *s = SOCKET(u);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SocketPort *p;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(u);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(f);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(fds);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
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
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (s->control_pid > 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (s->control_command_id >= 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id));
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering LIST_FOREACH(port, p, s->ports) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering int copy;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (p->fd < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering continue;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering copy = fdset_put_dup(fds, p->fd);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (copy < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return copy;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (p->type == SOCKET_SOCKET) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering _cleanup_free_ char *t = NULL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering r = socket_address_print(&p->address, &t);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
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 else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else if (p->type == SOCKET_SPECIAL)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else if (p->type == SOCKET_MQUEUE)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else if (p->type == SOCKET_USB_FUNCTION)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "ffs", "%i %s", copy, p->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(p->type == SOCKET_FIFO);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Socket *s = SOCKET(u);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(u);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(key);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (streq(key, "state")) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SocketState state;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering state = socket_state_from_string(value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (state < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(u, "Failed to parse state value: %s", value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->deserialized_state = state;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else if (streq(key, "result")) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SocketResult f;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering f = socket_result_from_string(value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (f < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(u, "Failed to parse result value: %s", value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else if (f != SOCKET_SUCCESS)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->result = f;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else if (streq(key, "n-accepted")) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering unsigned k;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (safe_atou(value, &k) < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(u, "Failed to parse n-accepted value: %s", value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering s->n_accepted += k;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering } else if (streq(key, "control-pid")) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering pid_t pid;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (parse_pid(value, &pid) < 0)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_debug(u, "Failed to parse control-pid value: %s", value);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering s->control_pid = pid;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering } else if (streq(key, "control-command")) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering SocketExecCommand id;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering id = socket_exec_command_from_string(value);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (id < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_unit_debug(u, "Failed to parse exec-command value: %s", value);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering else {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering s->control_command_id = id;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering s->control_command = s->exec_command[id];
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering } else if (streq(key, "fifo")) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int fd, skip = 0;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering SocketPort *p;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
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);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering else {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering LIST_FOREACH(port, p, s->ports)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (p->type == SOCKET_FIFO &&
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering path_equal_or_files_same(p->path, value+skip))
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering break;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
7f444afa1b62920265fec99a61cb4dc53d521956Lennart Poettering if (p) {
7f444afa1b62920265fec99a61cb4dc53d521956Lennart Poettering safe_close(p->fd);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering p->fd = fdset_remove(fds, fd);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering } else if (streq(key, "special")) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int fd, skip = 0;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering SocketPort *p;
ebd011d95b61a86258dece9864f65b7c4af721c0Lennart Poettering
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);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering else {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering LIST_FOREACH(port, p, s->ports)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (p->type == SOCKET_SPECIAL &&
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering path_equal_or_files_same(p->path, value+skip))
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering break;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (p) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering safe_close(p->fd);
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering p->fd = fdset_remove(fds, fd);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering }
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering } else if (streq(key, "mqueue")) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering int fd, skip = 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering SocketPort *p;
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering
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);
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering else {
b5b38b41c37dbe1a117af9bf99e94b58ac91239aLennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering LIST_FOREACH(port, p, s->ports)
f7621db0e38c3e96d48766ae648f1b7a0949ea13Lennart Poettering if (p->type == SOCKET_MQUEUE &&
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering streq(p->path, value+skip))
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (p) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering safe_close(p->fd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->fd = fdset_remove(fds, fd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen } else if (streq(key, "socket")) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int fd, type, skip = 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering SocketPort *p;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
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);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering else {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LIST_FOREACH(port, p, s->ports)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (socket_address_is(&p->address, value+skip, type))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (p) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering safe_close(p->fd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->fd = fdset_remove(fds, fd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (streq(key, "netlink")) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int fd, skip = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering SocketPort *p;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
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);
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering else {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering LIST_FOREACH(port, p, s->ports)
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (socket_address_is_netlink(&p->address, value+skip))
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering break;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (p) {
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering safe_close(p->fd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->fd = fdset_remove(fds, fd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (streq(key, "ffs")) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int fd, skip = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering SocketPort *p;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
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 else {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering LIST_FOREACH(port, p, s->ports)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (p->type == SOCKET_USB_FUNCTION &&
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering path_equal_or_files_same(p->path, value+skip))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (p) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering safe_close(p->fd);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering p->fd = fdset_remove(fds, fd);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering }
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering }
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_unit_debug(UNIT(s), "Unknown serialization key: %s", key);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int socket_distribute_fds(Unit *u, FDSet *fds) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Socket *s = SOCKET(u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering SocketPort *p;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LIST_FOREACH(port, p, s->ports) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Iterator i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int fd;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (p->type != SOCKET_SOCKET)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering continue;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (p->fd >= 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering continue;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering FDSET_FOREACH(fd, fds, i) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (socket_address_matches_fd(&p->address, fd)) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering p->fd = fdset_remove(fds, fd);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering s->deserialized_state = SOCKET_LISTENING;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering break;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering }
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering }
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen_pure_ static UnitActiveState socket_active_state(Unit *u) {
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen assert(u);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen return state_translation_table[SOCKET(u)->state];
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering_pure_ static const char *socket_sub_state_to_string(Unit *u) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return socket_state_to_string(SOCKET(u)->state);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringconst char* socket_port_type_to_string(SocketPort *p) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(p);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering switch (p->type) {
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering case SOCKET_SOCKET:
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering switch (p->address.type) {
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering case SOCK_STREAM:
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return "Stream";
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering case SOCK_DGRAM:
de33fc625725d199629ed074d6278504deb23debLennart Poettering return "Datagram";
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case SOCK_SEQPACKET:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return "SequentialPacket";
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering case SOCK_RAW:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (socket_address_family(&p->address) == AF_NETLINK)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return "Netlink";
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering default:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering case SOCKET_SPECIAL:
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering return "Special";
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering case SOCKET_MQUEUE:
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering return "MessageQueue";
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering case SOCKET_FIFO:
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering return "FIFO";
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering case SOCKET_USB_FUNCTION:
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return "USBFunction";
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering default:
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return NULL;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering_pure_ static bool socket_check_gc(Unit *u) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering Socket *s = SOCKET(u);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering assert(u);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return s->n_connections > 0;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering SocketPort *p = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int cfd = -1;
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(p);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(fd >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (p->socket->state != SOCKET_LISTENING)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_unit_debug(UNIT(p->socket), "Incoming traffic");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (revents != EPOLLIN) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (revents & EPOLLHUP)
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 else
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error(UNIT(p->socket), "Got unexpected poll event (0x%x) on socket.", revents);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (p->socket->accept &&
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering p->type == SOCKET_SOCKET &&
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering socket_address_can_accept(&p->address)) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering for (;;) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (cfd < 0) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (errno == EINTR)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering continue;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering log_unit_error_errno(UNIT(p->socket), errno, "Failed to accept socket: %m");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering goto fail;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering break;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering socket_apply_socket_options(p->socket, cfd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering socket_enter_running(p->socket, cfd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
249968612f16a71df909d6e73785c18a9ff36a65Lennart Poetteringfail:
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering socket_enter_stop_pre(p->socket, SOCKET_FAILURE_RESOURCES);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Socket *s = SOCKET(u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering SocketResult f;
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(s);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(pid >= 0);
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (pid != s->control_pid)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt return;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen s->control_pid = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (is_clean_exit(code, status, NULL))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering f = SOCKET_SUCCESS;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (code == CLD_EXITED)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering f = SOCKET_FAILURE_EXIT_CODE;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering else if (code == CLD_KILLED)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering f = SOCKET_FAILURE_SIGNAL;
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering else if (code == CLD_DUMPED)
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering f = SOCKET_FAILURE_CORE_DUMP;
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_not_reached("Unknown sigchld code");
if (s->control_command) {
exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
if (s->control_command->ignore)
f = SOCKET_SUCCESS;
}
log_unit_full(u, f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE, 0,
"Control process exited, code=%s status=%i",
sigchld_code_to_string(code), status);
if (f != SOCKET_SUCCESS)
s->result = f;
if (s->control_command &&
s->control_command->command_next &&
f == SOCKET_SUCCESS) {
log_unit_debug(u, "Running next command for state %s", socket_state_to_string(s->state));
socket_run_next(s);
} else {
s->control_command = NULL;
s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
/* No further commands for this step, so let's figure
* out what to do next */
log_unit_debug(u, "Got final SIGCHLD for state %s", socket_state_to_string(s->state));
switch (s->state) {
case SOCKET_START_PRE:
if (f == SOCKET_SUCCESS)
socket_enter_start_chown(s);
else
socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f);
break;
case SOCKET_START_CHOWN:
if (f == SOCKET_SUCCESS)
socket_enter_start_post(s);
else
socket_enter_stop_pre(s, f);
break;
case SOCKET_START_POST:
if (f == SOCKET_SUCCESS)
socket_enter_listening(s);
else
socket_enter_stop_pre(s, f);
break;
case SOCKET_STOP_PRE:
case SOCKET_STOP_PRE_SIGTERM:
case SOCKET_STOP_PRE_SIGKILL:
socket_enter_stop_post(s, f);
break;
case SOCKET_STOP_POST:
case SOCKET_FINAL_SIGTERM:
case SOCKET_FINAL_SIGKILL:
socket_enter_dead(s, f);
break;
default:
assert_not_reached("Uh, control process died at wrong time.");
}
}
/* Notify clients about changed exit status */
unit_add_to_dbus_queue(u);
}
static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
Socket *s = SOCKET(userdata);
assert(s);
assert(s->timer_event_source == source);
switch (s->state) {
case SOCKET_START_PRE:
log_unit_warning(UNIT(s), "Starting timed out. Terminating.");
socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_START_CHOWN:
case SOCKET_START_POST:
log_unit_warning(UNIT(s), "Starting timed out. Stopping.");
socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_STOP_PRE:
log_unit_warning(UNIT(s), "Stopping timed out. Terminating.");
socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_STOP_PRE_SIGTERM:
if (s->kill_context.send_sigkill) {
log_unit_warning(UNIT(s), "Stopping timed out. Killing.");
socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT);
} else {
log_unit_warning(UNIT(s), "Stopping timed out. Skipping SIGKILL. Ignoring.");
socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
}
break;
case SOCKET_STOP_PRE_SIGKILL:
log_unit_warning(UNIT(s), "Processes still around after SIGKILL. Ignoring.");
socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_STOP_POST:
log_unit_warning(UNIT(s), "Stopping timed out (2). Terminating.");
socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_FINAL_SIGTERM:
if (s->kill_context.send_sigkill) {
log_unit_warning(UNIT(s), "Stopping timed out (2). Killing.");
socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT);
} else {
log_unit_warning(UNIT(s), "Stopping timed out (2). Skipping SIGKILL. Ignoring.");
socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
}
break;
case SOCKET_FINAL_SIGKILL:
log_unit_warning(UNIT(s), "Still around after SIGKILL (2). Entering failed mode.");
socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
break;
default:
assert_not_reached("Timeout at wrong time.");
}
return 0;
}
int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
int *rfds;
unsigned rn_fds, k;
int i;
SocketPort *p;
assert(s);
assert(fds);
assert(n_fds);
/* Called from the service code for requesting our fds */
rn_fds = 0;
LIST_FOREACH(port, p, s->ports) {
if (p->fd >= 0)
rn_fds++;
rn_fds += p->n_auxiliary_fds;
}
if (rn_fds <= 0) {
*fds = NULL;
*n_fds = 0;
return 0;
}
rfds = new(int, rn_fds);
if (!rfds)
return -ENOMEM;
k = 0;
LIST_FOREACH(port, p, s->ports) {
if (p->fd >= 0)
rfds[k++] = p->fd;
for (i = 0; i < p->n_auxiliary_fds; ++i)
rfds[k++] = p->auxiliary_fds[i];
}
assert(k == rn_fds);
*fds = rfds;
*n_fds = rn_fds;
return 0;
}
static void socket_reset_failed(Unit *u) {
Socket *s = SOCKET(u);
assert(s);
if (s->state == SOCKET_FAILED)
socket_set_state(s, SOCKET_DEAD);
s->result = SOCKET_SUCCESS;
}
static void socket_notify_service_dead(Socket *s, bool failed_permanent) {
assert(s);
/* The service is dead. Dang!
*
* This is strictly for one-instance-for-all-connections
* services. */
if (s->state == SOCKET_RUNNING) {
log_unit_debug(UNIT(s), "Got notified about service death (failed permanently: %s)", yes_no(failed_permanent));
if (failed_permanent)
socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_FAILED_PERMANENT);
else
socket_enter_listening(s);
}
}
void socket_connection_unref(Socket *s) {
assert(s);
/* The service is dead. Yay!
*
* This is strictly for one-instance-per-connection
* services. */
assert(s->n_connections > 0);
s->n_connections--;
log_unit_debug(UNIT(s), "One connection closed, %u left.", s->n_connections);
}
static void socket_trigger_notify(Unit *u, Unit *other) {
Socket *s = SOCKET(u);
Service *se;
assert(u);
assert(other);
/* Don't propagate state changes from the service if we are
already down or accepting connections */
if ((s->state != SOCKET_RUNNING &&
s->state != SOCKET_LISTENING) ||
s->accept)
return;
if (other->load_state != UNIT_LOADED ||
other->type != UNIT_SERVICE)
return;
se = SERVICE(other);
if (se->state == SERVICE_FAILED)
socket_notify_service_dead(s, se->result == SERVICE_FAILURE_START_LIMIT);
if (se->state == SERVICE_DEAD ||
se->state == SERVICE_FINAL_SIGTERM ||
se->state == SERVICE_FINAL_SIGKILL ||
se->state == SERVICE_AUTO_RESTART)
socket_notify_service_dead(s, false);
if (se->state == SERVICE_RUNNING)
socket_set_state(s, SOCKET_RUNNING);
}
static int socket_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
}
static int socket_get_timeout(Unit *u, uint64_t *timeout) {
Socket *s = SOCKET(u);
int r;
if (!s->timer_event_source)
return 0;
r = sd_event_source_get_time(s->timer_event_source, timeout);
if (r < 0)
return r;
return 1;
}
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
[SOCKET_EXEC_START_PRE] = "StartPre",
[SOCKET_EXEC_START_CHOWN] = "StartChown",
[SOCKET_EXEC_START_POST] = "StartPost",
[SOCKET_EXEC_STOP_PRE] = "StopPre",
[SOCKET_EXEC_STOP_POST] = "StopPost"
};
DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand);
static const char* const socket_result_table[_SOCKET_RESULT_MAX] = {
[SOCKET_SUCCESS] = "success",
[SOCKET_FAILURE_RESOURCES] = "resources",
[SOCKET_FAILURE_TIMEOUT] = "timeout",
[SOCKET_FAILURE_EXIT_CODE] = "exit-code",
[SOCKET_FAILURE_SIGNAL] = "signal",
[SOCKET_FAILURE_CORE_DUMP] = "core-dump",
[SOCKET_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent"
};
DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult);
const UnitVTable socket_vtable = {
.object_size = sizeof(Socket),
.exec_context_offset = offsetof(Socket, exec_context),
.cgroup_context_offset = offsetof(Socket, cgroup_context),
.kill_context_offset = offsetof(Socket, kill_context),
.exec_runtime_offset = offsetof(Socket, exec_runtime),
.sections =
"Unit\0"
"Socket\0"
"Install\0",
.private_section = "Socket",
.init = socket_init,
.done = socket_done,
.load = socket_load,
.coldplug = socket_coldplug,
.dump = socket_dump,
.start = socket_start,
.stop = socket_stop,
.kill = socket_kill,
.get_timeout = socket_get_timeout,
.serialize = socket_serialize,
.deserialize_item = socket_deserialize_item,
.distribute_fds = socket_distribute_fds,
.active_state = socket_active_state,
.sub_state_to_string = socket_sub_state_to_string,
.check_gc = socket_check_gc,
.sigchld_event = socket_sigchld_event,
.trigger_notify = socket_trigger_notify,
.reset_failed = socket_reset_failed,
.bus_vtable = bus_socket_vtable,
.bus_set_property = bus_socket_set_property,
.bus_commit_properties = bus_socket_commit_properties,
.status_message_formats = {
/*.starting_stopping = {
[0] = "Starting socket %s...",
[1] = "Stopping socket %s...",
},*/
.finished_start_job = {
[JOB_DONE] = "Listening on %s.",
[JOB_FAILED] = "Failed to listen on %s.",
[JOB_TIMEOUT] = "Timed out starting %s.",
},
.finished_stop_job = {
[JOB_DONE] = "Closed %s.",
[JOB_FAILED] = "Failed stopping %s.",
[JOB_TIMEOUT] = "Timed out stopping %s.",
},
},
};