socket.c revision 2b3e18de74ca89b374dd4f7a2c30e5731d347841
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/***
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek This file is part of systemd.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Copyright 2010 Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (at your option) any later version.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek***/
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include <sys/types.h>
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include <sys/stat.h>
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include <unistd.h>
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include <errno.h>
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include <fcntl.h>
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include <sys/epoll.h>
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include <signal.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <arpa/inet.h>
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include <mqueue.h>
b4bbcaa9c44260e88402cb8f9a5fb8ac7f35e123Thomas Hindoe Paaboel Andersen#ifdef HAVE_XATTR
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include <attr/xattr.h>
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering#endif
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include "unit.h"
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include "socket.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "netinet/tcp.h"
430f0182b72373145c839dbfe99d2382855cb8f8Lennart Poettering#include "log.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "load-dropin.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "load-fragment.h"
a09561746f15b84da9471b5c4be74e53d19e4f3fLennart Poettering#include "strv.h"
0dec689b098cf62b948d43dc78bde859665056ecTom Gundersen#include "mkdir.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "path-util.h"
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering#include "unit-name.h"
958b66ea16deddd794b3a52643bd44633e165eadLennart Poettering#include "unit-printf.h"
f4f15635ec05293ffcc83a5b39f624bbabbd8fd0Lennart Poettering#include "dbus-socket.h"
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include "missing.h"
958b66ea16deddd794b3a52643bd44633e165eadLennart Poettering#include "special.h"
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering#include "dbus-common.h"
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include "label.h"
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#include "exit-status.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "def.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek [SOCKET_DEAD] = UNIT_INACTIVE,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek [SOCKET_START_PRE] = UNIT_ACTIVATING,
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering [SOCKET_START_POST] = UNIT_ACTIVATING,
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering [SOCKET_LISTENING] = UNIT_ACTIVE,
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering [SOCKET_RUNNING] = UNIT_ACTIVE,
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING,
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING,
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering [SOCKET_FAILED] = UNIT_FAILED
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering};
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic void socket_init(Unit *u) {
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek Socket *s = SOCKET(u);
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering assert(u);
4a0b58c4a30ecaa61202f845ed86f75b36370cd0Lennart Poettering assert(u->load_state == UNIT_STUB);
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->backlog = SOMAXCONN;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->timeout_usec = DEFAULT_TIMEOUT_USEC;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->directory_mode = 0755;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk s->socket_mode = 0666;
7f1ad696a273703789b624fe0b209fb63e953016Lennart Poettering
7f1ad696a273703789b624fe0b209fb63e953016Lennart Poettering s->max_connections = 64;
e150e82097211f09b911c7784a89ef9efed713caMichał Bartoszkiewicz
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->priority = -1;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering s->ip_tos = -1;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->ip_ttl = -1;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->mark = -1;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo exec_context_init(&s->exec_context);
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo s->exec_context.std_output = u->manager->default_std_output;
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo s->exec_context.std_error = u->manager->default_std_error;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering kill_context_init(&s->kill_context);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering}
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic void socket_unwatch_control_pid(Socket *s) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering assert(s);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (s->control_pid <= 0)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer unit_unwatch_pid(UNIT(s), s->control_pid);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering s->control_pid = 0;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering}
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid socket_free_ports(Socket *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketPort *p;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering assert(s);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering while ((p = s->ports)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_REMOVE(SocketPort, port, s->ports, p);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (p->fd >= 0) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering unit_unwatch_fd(UNIT(s), &p->fd_watch);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek close_nointr_nofail(p->fd);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering }
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering free(p->path);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering free(p);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void socket_done(Unit *u) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering Socket *s = SOCKET(u);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_free_ports(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering s->control_command = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_unwatch_control_pid(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unit_ref_unset(&s->service);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek free(s->tcp_congestion);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering s->tcp_congestion = NULL;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek free(s->bind_to_device);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering s->bind_to_device = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek free(s->smack);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek free(s->smack_ip_in);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek free(s->smack_ip_out);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unit_unwatch_timer(u, &s->timer_watch);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic int socket_instantiate_service(Socket *s) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering char *prefix, *name;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering int r;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering Unit *u;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering /* This fills in s->service if it isn't filled in yet. For
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek * Accept=yes sockets we create the next connection service
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering * here. For Accept=no this is mostly a NOP since the service
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering * is figured out at load time anyway. */
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (UNIT_DEREF(s->service))
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return 0;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s->accept);
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek if (!(prefix = unit_name_to_prefix(UNIT(s)->id)))
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return -ENOMEM;
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek r = asprintf(&name, "%s@%u.service", prefix, s->n_accepted);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek free(prefix);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek if (r < 0)
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek return -ENOMEM;
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek r = manager_load_unit(UNIT(s)->manager, name, NULL, NULL, &u);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek free(name);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek if (r < 0)
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek return r;
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek#ifdef HAVE_SYSV_COMPAT
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek if (SERVICE(u)->is_sysv) {
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek log_error("Using SysV services for socket activation is not supported. Refusing.");
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek return -ENOENT;
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek }
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek#endif
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek u->no_gc = true;
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek unit_ref_set(&s->service, u);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek}
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic bool have_non_accept_socket(Socket *s) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering SocketPort *p;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering assert(s);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (!s->accept)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return true;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering LIST_FOREACH(port, p, s->ports) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (p->type != SOCKET_SOCKET)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return true;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (!socket_address_can_accept(&p->address))
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return true;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering }
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return false;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering}
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic int socket_verify(Socket *s) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering assert(s);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek if (UNIT(s)->load_state != UNIT_LOADED)
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek return 0;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!s->ports) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_unit(UNIT(s)->id,
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek "%s lacks Listen setting. Refusing.", UNIT(s)->id);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -EINVAL;
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->accept && have_non_accept_socket(s)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_unit(UNIT(s)->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%s configured for accepting sockets, but sockets are non-accepting. Refusing.",
34c10968cbe3b5591b3c0ce225b8694edd9709d0Lennart Poettering UNIT(s)->id);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -EINVAL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek if (s->accept && s->max_connections <= 0) {
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek log_error_unit(UNIT(s)->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%s's MaxConnection setting too small. Refusing.", UNIT(s)->id);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -EINVAL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo if (s->accept && UNIT_DEREF(s->service)) {
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo log_error_unit(UNIT(s)->id,
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo "Explicit service configuration for accepting sockets not supported on %s. Refusing.",
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo UNIT(s)->id);
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo return -EINVAL;
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo }
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
e167d7fd8d5fe918b6d675e16aeca2c43398a5b2Lennart Poettering log_error_unit(UNIT(s)->id,
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.",
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo UNIT(s)->id);
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo return -EINVAL;
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo }
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo return 0;
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo}
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputostatic bool socket_needs_mount(Socket *s, const char *prefix) {
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo SocketPort *p;
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo assert(s);
e167d7fd8d5fe918b6d675e16aeca2c43398a5b2Lennart Poettering
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo LIST_FOREACH(port, p, s->ports) {
e167d7fd8d5fe918b6d675e16aeca2c43398a5b2Lennart Poettering
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo if (p->type == SOCKET_SOCKET) {
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo if (socket_address_needs_mount(&p->address, prefix))
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo return true;
e167d7fd8d5fe918b6d675e16aeca2c43398a5b2Lennart Poettering } else if (p->type == SOCKET_FIFO || p->type == SOCKET_SPECIAL) {
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo if (path_startswith(p->path, prefix))
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo return true;
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
ed375bebf46c1251f4baa170b39ee93761dbdb19Zbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint socket_add_one_mount_link(Socket *s, Mount *m) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(m);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (UNIT(s)->load_state != UNIT_LOADED ||
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek UNIT(m)->load_state != UNIT_LOADED)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!socket_needs_mount(s, m->where))
f7dc3ab9f43b67abcbd34062b9352ab42debec49Lennart Poettering return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (r < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
4a0b58c4a30ecaa61202f845ed86f75b36370cd0Lennart Poettering}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int socket_add_mount_links(Socket *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Unit *other;
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek int r;
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT]) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = socket_add_one_mount_link(s, MOUNT(other));
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt if (r < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int socket_add_device_link(Socket *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char *t;
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek int r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
4a0b58c4a30ecaa61202f845ed86f75b36370cd0Lennart Poettering assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!s->bind_to_device || streq(s->bind_to_device, "lo"))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (asprintf(&t, "/sys/subsystem/net/devices/%s", s->bind_to_device) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -ENOMEM;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = unit_add_node_link(UNIT(s), t, false);
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering free(t);
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering return r;
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering}
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poetteringstatic int socket_add_default_dependencies(Socket *s) {
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering int r;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek assert(s);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek if (r < 0)
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek return r;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek if (UNIT(s)->manager->running_as == SYSTEMD_SYSTEM) {
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek if (r < 0)
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering return r;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek }
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek}
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek_pure_ static bool socket_has_exec(Socket *s) {
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek unsigned i;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->exec_command[i])
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return true;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic int socket_load(Unit *u) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering Socket *s = SOCKET(u);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int r;
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt
4a0b58c4a30ecaa61202f845ed86f75b36370cd0Lennart Poettering assert(u);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek assert(u->load_state == UNIT_STUB);
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek if ((r = unit_load_fragment_and_dropin(u)) < 0)
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek return r;
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* This is a new unit? Then let's add in some extras */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (u->load_state == UNIT_LOADED) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (have_non_accept_socket(s)) {
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (!UNIT_DEREF(s->service)) {
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk Unit *x;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk r = unit_load_related_unit(u, ".service", &x);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (r < 0)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk return r;
65089b82401cd395786a7987c470056ff3f01151Lennart Poettering
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk unit_ref_set(&s->service, x);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk }
65c1d46b0923771955519329160a1e4c7cd027b0Lennart Poettering
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (r < 0)
65089b82401cd395786a7987c470056ff3f01151Lennart Poettering return r;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk }
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if ((r = socket_add_mount_links(s)) < 0)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return r;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt if ((r = socket_add_device_link(s)) < 0)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return r;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (socket_has_exec(s))
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk return r;
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering if ((r = unit_add_default_cgroups(u)) < 0)
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering return r;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (UNIT(s)->default_dependencies)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if ((r = socket_add_default_dependencies(s)) < 0)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return r;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering r = unit_exec_context_defaults(u, &s->exec_context);
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering if (r < 0)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return r;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek }
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return socket_verify(s);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering}
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering_const_ static const char* listen_lookup(int family, int type) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek if (family == AF_NETLINK)
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek return "ListenNetlink";
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (type == SOCK_STREAM)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return "ListenStream";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering else if (type == SOCK_DGRAM)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return "ListenDatagram";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering else if (type == SOCK_SEQPACKET)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return "ListenSequentialPacket";
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering assert_not_reached("Unknown socket type");
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek return NULL;
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek}
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic void socket_dump(Unit *u, FILE *f, const char *prefix) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketExecCommand c;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Socket *s = SOCKET(u);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketPort *p;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char *prefix2;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering char *p2;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering assert(f);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering p2 = strappend(prefix, "\t");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix2 = p2 ? p2 : prefix;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sSocket State: %s\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sResult: %s\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sBindIPv6Only: %s\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sBacklog: %u\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sSocketMode: %04o\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sDirectoryMode: %04o\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sKeepAlive: %s\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sFreeBind: %s\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sTransparent: %s\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sBroadcast: %s\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sPassCredentials: %s\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sPassSecurity: %s\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sTCPCongestion: %s\n",
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, socket_state_to_string(s->state),
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, socket_result_to_string(s->result),
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, s->backlog,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, s->socket_mode,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, s->directory_mode,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, yes_no(s->keep_alive),
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, yes_no(s->free_bind),
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, yes_no(s->transparent),
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, yes_no(s->broadcast),
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, yes_no(s->pass_cred),
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, yes_no(s->pass_sec),
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, strna(s->tcp_congestion));
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (s->control_pid > 0)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering fprintf(f,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sControl PID: %lu\n",
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, (unsigned long) s->control_pid);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (s->bind_to_device)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering fprintf(f,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sBindToDevice: %s\n",
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, s->bind_to_device);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (s->accept)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering fprintf(f,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sAccepted: %u\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sNConnections: %u\n"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "%sMaxConnections: %u\n",
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, s->n_accepted,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, s->n_connections,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix, s->max_connections);
8531ae707d4d0203e83304d4af948b8169a5fce1Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->priority >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sPriority: %i\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->priority);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
fa6ac76083b8ffc1309876459f54f9f0e2843731Lennart Poettering if (s->receive_buffer > 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sReceiveBuffer: %zu\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->receive_buffer);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->send_buffer > 0)
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering fprintf(f,
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering "%sSendBuffer: %zu\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->send_buffer);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->ip_tos >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sIPTOS: %i\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->ip_tos);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->ip_ttl >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sIPTTL: %i\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->ip_ttl);
fa6ac76083b8ffc1309876459f54f9f0e2843731Lennart Poettering
fa6ac76083b8ffc1309876459f54f9f0e2843731Lennart Poettering if (s->pipe_size > 0)
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering fprintf(f,
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering "%sPipeSize: %zu\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->pipe_size);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->mark >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sMark: %i\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->mark);
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->mq_maxmsg > 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sMessageQueueMaxMessages: %li\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->mq_maxmsg);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->mq_msgsize > 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sMessageQueueMessageSize: %li\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->mq_msgsize);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->smack)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sSmackLabel: %s\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->smack);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (s->smack_ip_in)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sSmackLabelIPIn: %s\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->smack_ip_in);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->smack_ip_out)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%sSmackLabelIPOut: %s\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek prefix, s->smack_ip_out);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering LIST_FOREACH(port, p, s->ports) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (p->type == SOCKET_SOCKET) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char *t;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int r;
8266e1c04db8cabe3c68510a0c1f07c09ecdb2e8Lennart Poettering char *k = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((r = socket_address_print(&p->address, &k)) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek t = strerror(-r);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering t = k;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek free(k);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (p->type == SOCKET_SPECIAL)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f, "%sListenSpecial: %s\n", prefix, p->path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else if (p->type == SOCKET_MQUEUE)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path);
8266e1c04db8cabe3c68510a0c1f07c09ecdb2e8Lennart Poettering else
8266e1c04db8cabe3c68510a0c1f07c09ecdb2e8Lennart Poettering fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
8266e1c04db8cabe3c68510a0c1f07c09ecdb2e8Lennart Poettering }
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek exec_context_dump(&s->exec_context, f, prefix);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek kill_context_dump(&s->kill_context, f, prefix);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!s->exec_command[c])
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering continue;
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fprintf(f, "%s-> %s:\n",
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek prefix, socket_exec_command_to_string(c));
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek exec_command_dump_list(s->exec_command[c], f, prefix2);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering free(p2);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering}
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
d378991747d67fff1d4dc39e7fb2bc8f49f1b561Mirco Tischlerstatic int instance_from_socket(int fd, unsigned nr, char **instance) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek socklen_t l;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek char *r;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek union {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek struct sockaddr sa;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek struct sockaddr_un un;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek struct sockaddr_in in;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek struct sockaddr_in6 in6;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering struct sockaddr_storage storage;
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering } local, remote;
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering assert(fd >= 0);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek assert(instance);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek l = sizeof(local);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (getsockname(fd, &local.sa, &l) < 0)
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering return -errno;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering l = sizeof(remote);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (getpeername(fd, &remote.sa, &l) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return -errno;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek switch (local.sa.sa_family) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek case AF_INET: {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek uint32_t
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek a = ntohl(local.in.sin_addr.s_addr),
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek b = ntohl(remote.in.sin_addr.s_addr);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek if (asprintf(&r,
c2457105d76e3daf159f554a9bafb9751b23d756Holger Hans Peter Freyther "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek nr,
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
c2457105d76e3daf159f554a9bafb9751b23d756Holger Hans Peter Freyther ntohs(local.in.sin_port),
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek ntohs(remote.in.sin_port)) < 0)
c2457105d76e3daf159f554a9bafb9751b23d756Holger Hans Peter Freyther return -ENOMEM;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek case AF_INET6: {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek static const unsigned char ipv4_prefix[] = {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek };
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (memcmp(&local.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0 &&
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering memcmp(&remote.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const uint8_t
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek *a = local.in6.sin6_addr.s6_addr+12,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek *b = remote.in6.sin6_addr.s6_addr+12;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
9bdbc2e2ec523dbefe1c1c7e164b5544aff0b185Lukas Nykryn if (asprintf(&r,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering nr,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek a[0], a[1], a[2], a[3],
3a83211689bdf4ab617a4fb79e11980c50918123Shawn Landden ntohs(local.in6.sin6_port),
3a83211689bdf4ab617a4fb79e11980c50918123Shawn Landden b[0], b[1], b[2], b[3],
3a83211689bdf4ab617a4fb79e11980c50918123Shawn Landden ntohs(remote.in6.sin6_port)) < 0)
3a83211689bdf4ab617a4fb79e11980c50918123Shawn Landden return -ENOMEM;
3a83211689bdf4ab617a4fb79e11980c50918123Shawn Landden } else {
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
3a83211689bdf4ab617a4fb79e11980c50918123Shawn Landden
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (asprintf(&r,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%u-%s:%u-%s:%u",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek nr,
0a20e3c10761378869af7bbef2733e3ae879d0f1Holger Hans Peter Freyther inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek ntohs(local.in6.sin6_port),
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek ntohs(remote.in6.sin6_port)) < 0)
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering return -ENOMEM;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering }
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering case AF_UNIX: {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek struct ucred ucred;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek l = sizeof(ucred);
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering return -errno;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (asprintf(&r,
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering "%u-%lu-%lu",
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek nr,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (unsigned long) ucred.pid,
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering (unsigned long) ucred.uid) < 0)
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering return -ENOMEM;
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering default:
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering assert_not_reached("Unhandled socket type.");
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek *instance = r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poetteringstatic void socket_close_fds(Socket *s) {
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering SocketPort *p;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering assert(s);
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering LIST_FOREACH(port, p, s->ports) {
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering if (p->fd < 0)
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering continue;
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering unit_unwatch_fd(UNIT(s), &p->fd_watch);
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering close_nointr_nofail(p->fd);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek /* One little note: we should never delete any sockets
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering * in the file system here! After all some other
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering * process we spawned might still have a reference of
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering * this fd and wants to continue to use it. Therefore
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering * we delete sockets in the file system before we
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering * create a new one, not after we stopped using
0a244b8ecb6dfcb381fe831dc2aa9bacb2c12975Lennart Poettering * one! */
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
0a244b8ecb6dfcb381fe831dc2aa9bacb2c12975Lennart Poettering p->fd = -1;
0a244b8ecb6dfcb381fe831dc2aa9bacb2c12975Lennart Poettering }
0a244b8ecb6dfcb381fe831dc2aa9bacb2c12975Lennart Poettering}
0a244b8ecb6dfcb381fe831dc2aa9bacb2c12975Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poetteringstatic void socket_apply_socket_options(Socket *s, int fd) {
2d43b190901902dbd98ccea77c1d1ddc9e2a9955Dan McGee assert(s);
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering assert(fd >= 0);
2d43b190901902dbd98ccea77c1d1ddc9e2a9955Dan McGee
ef1673d16907726d83bdff2e57b5261997a85020Mirco Tischler if (s->keep_alive) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int b = s->keep_alive;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &b, sizeof(b)) < 0)
6355e75610a8d47fc3ba5ab8bd442172a2cfe574Lennart Poettering log_warning_unit(UNIT(s)->id, "SO_KEEPALIVE failed: %m");
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering }
f8294e4175918117ca6c131720bcf287eadcd029Josh Triplett
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (s->broadcast) {
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering int one = 1;
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering log_warning_unit(UNIT(s)->id, "SO_BROADCAST failed: %m");
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering if (s->pass_cred) {
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering int one = 1;
e7ff4e7fe9f3abd2297e4ef7b95dcb2804e051c3Greg Kroah-Hartman if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering log_warning_unit(UNIT(s)->id, "SO_PASSCRED failed: %m");
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering }
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->pass_sec) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int one = 1;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_warning_unit(UNIT(s)->id, "SO_PASSSEC failed: %m");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek }
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->priority >= 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_warning_unit(UNIT(s)->id, "SO_PRIORITY failed: %m");
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->receive_buffer > 0) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek int value = (int) s->receive_buffer;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_warning_unit(UNIT(s)->id, "SO_RCVBUF failed: %m");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek }
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->send_buffer > 0) {
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering int value = (int) s->send_buffer;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_warning_unit(UNIT(s)->id, "SO_SNDBUF failed: %m");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek }
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->mark >= 0)
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering if (setsockopt(fd, SOL_SOCKET, SO_MARK, &s->mark, sizeof(s->mark)) < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_warning_unit(UNIT(s)->id, "SO_MARK failed: %m");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->ip_tos >= 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (setsockopt(fd, IPPROTO_IP, IP_TOS, &s->ip_tos, sizeof(s->ip_tos)) < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_warning_unit(UNIT(s)->id, "IP_TOS failed: %m");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering if (s->ip_ttl >= 0) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek int r, x;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl));
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (socket_ipv6_is_supported())
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek x = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s->ip_ttl, sizeof(s->ip_ttl));
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek else {
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek x = -1;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek errno = EAFNOSUPPORT;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek }
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (r < 0 && x < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_warning_unit(UNIT(s)->id,
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek "IP_TTL/IPV6_UNICAST_HOPS failed: %m");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek }
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->tcp_congestion)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0)
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering log_warning_unit(UNIT(s)->id, "TCP_CONGESTION failed: %m");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering#ifdef HAVE_SMACK
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->smack_ip_in)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_error_unit(UNIT(s)->id,
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek "fsetxattr(\"security.SMACK64IPIN\"): %m");
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->smack_ip_out)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (fsetxattr(fd, "security.SMACK64IPOUT", s->smack_ip_out, strlen(s->smack_ip_out), 0) < 0)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_error_unit(UNIT(s)->id,
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek "fsetxattr(\"security.SMACK64IPOUT\"): %m");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek#endif
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek}
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmekstatic void socket_apply_fifo_options(Socket *s, int fd) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek assert(s);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek assert(fd >= 0);
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->pipe_size > 0)
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0)
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering log_warning_unit(UNIT(s)->id,
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering "F_SETPIPE_SZ: %m");
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering#ifdef HAVE_SMACK
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (s->smack)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (fsetxattr(fd, "security.SMACK64", s->smack, strlen(s->smack), 0) < 0)
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering log_error_unit(UNIT(s)->id,
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek "fsetxattr(\"security.SMACK64\"): %m");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek#endif
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek}
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmekstatic int fifo_address_create(
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char *path,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek mode_t directory_mode,
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering mode_t socket_mode,
a569398925430de1f8479262e8ab39502054f2e9Lennart Poettering int *_fd) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int fd = -1, r = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek struct stat st;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek mode_t old_mask;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering assert(path);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering assert(_fd);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering mkdir_parents_label(path, directory_mode);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = label_context_set(path, S_IFIFO);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (r < 0)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Enforce the right access mode for the fifo */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek old_mask = umask(~ socket_mode);
da4993920cdf5527b8528f0a483b54ab3cbc1971Kay Sievers
40adcda869bda55f44b57fd3a2bd71d006dfb51bLennart Poettering /* Include the original umask in our mask */
759c945a43577d56e85a927f15e7d9aaa94a4e4aColin Walters umask(~socket_mode | old_mask);
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering
edc3797f7cd9e37c24e5241cac3263e7c918f732Lennart Poettering r = mkfifo(path, socket_mode);
edc3797f7cd9e37c24e5241cac3263e7c918f732Lennart Poettering umask(old_mask);
edc3797f7cd9e37c24e5241cac3263e7c918f732Lennart Poettering
edc3797f7cd9e37c24e5241cac3263e7c918f732Lennart Poettering if (r < 0 && errno != EEXIST) {
7517e17443225fafea86b21e42a36af69feb1dbcTorstein Husebø r = -errno;
8a0889dfdafa3054c894e54852d8a9e3a7e8390bLennart Poettering goto fail;
da4993920cdf5527b8528f0a483b54ab3cbc1971Kay Sievers }
da4993920cdf5527b8528f0a483b54ab3cbc1971Kay Sievers
759c945a43577d56e85a927f15e7d9aaa94a4e4aColin Walters if ((fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering r = -errno;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek label_context_clear();
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek if (fstat(fd, &st) < 0) {
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek r = -errno;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!S_ISFIFO(st.st_mode) ||
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (st.st_mode & 0777) != (socket_mode & ~old_mask) ||
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek st.st_uid != getuid() ||
4850d39ab72e7cb00a6e9c9aa4745c997674efa6Lennart Poettering st.st_gid != getgid()) {
b6fa25552e538eca207072e12d223e3523b21a19Evgeny Vereshchagin
b6fa25552e538eca207072e12d223e3523b21a19Evgeny Vereshchagin r = -EEXIST;
b6fa25552e538eca207072e12d223e3523b21a19Evgeny Vereshchagin goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
4850d39ab72e7cb00a6e9c9aa4745c997674efa6Lennart Poettering
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek *_fd = fd;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poetteringfail:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek label_context_clear();
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (fd >= 0)
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek close_nointr_nofail(fd);
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek return r;
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek}
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmekstatic int special_address_create(
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek const char *path,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int *_fd) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int fd = -1, r = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek struct stat st;
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek assert(path);
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek assert(_fd);
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek if ((fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek r = -errno;
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek goto fail;
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek }
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek if (fstat(fd, &st) < 0) {
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek r = -errno;
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek goto fail;
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek }
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek /* Check whether this is a /proc, /sys or /dev file or char device */
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek r = -EEXIST;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek *_fd = fd;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poetteringfail:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (fd >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek close_nointr_nofail(fd);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek return r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyerstatic int mq_address_create(
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering const char *path,
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek mode_t mq_mode,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek long maxmsg,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek long msgsize,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int *_fd) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int fd = -1, r = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek struct stat st;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek mode_t old_mask;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek struct mq_attr _attr, *attr = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(path);
2f5df74a5ec135ab2baebf26af6f088e5b4b8205Holger Hans Peter Freyther assert(_fd);
2f5df74a5ec135ab2baebf26af6f088e5b4b8205Holger Hans Peter Freyther
2f5df74a5ec135ab2baebf26af6f088e5b4b8205Holger Hans Peter Freyther if (maxmsg > 0 && msgsize > 0) {
2f5df74a5ec135ab2baebf26af6f088e5b4b8205Holger Hans Peter Freyther zero(_attr);
2f5df74a5ec135ab2baebf26af6f088e5b4b8205Holger Hans Peter Freyther _attr.mq_flags = O_NONBLOCK;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _attr.mq_maxmsg = maxmsg;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _attr.mq_msgsize = msgsize;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek attr = &_attr;
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering }
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Enforce the right access mode for the mq */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek old_mask = umask(~ mq_mode);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Include the original umask in our mask */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek umask(~mq_mode | old_mask);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek umask(old_mask);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (fd < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = -errno;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (fstat(fd, &st) < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = -errno;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if ((st.st_mode & 0777) != (mq_mode & ~old_mask) ||
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek st.st_uid != getuid() ||
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek st.st_gid != getgid()) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = -EEXIST;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek }
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek *_fd = fd;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poetteringfail:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (fd >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek close_nointr_nofail(fd);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
caa2f4c0c9613b2e02aafa308c8fb092576014a9Zbigniew Jędrzejewski-Szmek return r;
84267e4043cf88bf540b5bf9cd65e194670a4ffaLennart Poettering}
09eba4d46b1119c758fba38a520a38c8d19af739Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int socket_open_fds(Socket *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketPort *p;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int r;
caa2f4c0c9613b2e02aafa308c8fb092576014a9Zbigniew Jędrzejewski-Szmek char *label = NULL;
caa2f4c0c9613b2e02aafa308c8fb092576014a9Zbigniew Jędrzejewski-Szmek bool know_label = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_FOREACH(port, p, s->ports) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (p->fd >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek continue;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
ac892057c2ddd8f06323c73ebd80423cc3ec7190Dimitri John Ledkov if (p->type == SOCKET_SOCKET) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (!know_label) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((r = socket_instantiate_service(s)) < 0)
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering return r;
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (UNIT_DEREF(s->service) &&
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
433dd100442e8197868def975c6fd38b48dc6439Lukas Nykryn if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt if (r != -EPERM)
e40ec7aec5e64cd0cfa5fc556d6a9747229b5794Zbigniew Jędrzejewski-Szmek return r;
433dd100442e8197868def975c6fd38b48dc6439Lukas Nykryn }
433dd100442e8197868def975c6fd38b48dc6439Lukas Nykryn }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek know_label = true;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((r = socket_address_listen(
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering &p->address,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->backlog,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->bind_ipv6_only,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->bind_to_device,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->free_bind,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->transparent,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->directory_mode,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->socket_mode,
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo label,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek &p->fd)) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto rollback;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_apply_socket_options(s, p->fd);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (p->type == SOCKET_SPECIAL) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((r = special_address_create(
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek p->path,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek &p->fd)) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto rollback;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
fc1d70af2101e16c9e6f3c5bfd5ab315ee9e6daeLennart Poettering } else if (p->type == SOCKET_FIFO) {
fc1d70af2101e16c9e6f3c5bfd5ab315ee9e6daeLennart Poettering
fc1d70af2101e16c9e6f3c5bfd5ab315ee9e6daeLennart Poettering if ((r = fifo_address_create(
fc1d70af2101e16c9e6f3c5bfd5ab315ee9e6daeLennart Poettering p->path,
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo s->directory_mode,
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt s->socket_mode,
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt &p->fd)) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto rollback;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering socket_apply_fifo_options(s, p->fd);
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek } else if (p->type == SOCKET_MQUEUE) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if ((r = mq_address_create(
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek p->path,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->socket_mode,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->mq_maxmsg,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->mq_msgsize,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek &p->fd)) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto rollback;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert_not_reached("Unknown port type");
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering }
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering label_free(label);
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekrollback:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_close_fds(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek label_free(label);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void socket_unwatch_fds(Socket *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketPort *p;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_FOREACH(port, p, s->ports) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (p->fd < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek continue;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unit_unwatch_fd(UNIT(s), &p->fd_watch);
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering }
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
00a168618906bea43c3c57e20b9152582c324bf8Olivier Brunelstatic int socket_watch_fds(Socket *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketPort *p;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt assert(s);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_FOREACH(port, p, s->ports) {
93b73b064c663d6248bebfbbbd82989b5ca10fc5Lennart Poettering if (p->fd < 0)
93b73b064c663d6248bebfbbbd82989b5ca10fc5Lennart Poettering continue;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek p->fd_watch.socket_accept =
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->accept &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek p->type == SOCKET_SOCKET &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_address_can_accept(&p->address);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((r = unit_watch_fd(UNIT(s), p->fd, EPOLLIN, &p->fd_watch)) < 0)
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering goto fail;
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekfail:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_unwatch_fds(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void socket_set_state(Socket *s, SocketState state) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketState old_state;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek old_state = s->state;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->state = state;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (state != SOCKET_START_PRE &&
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering state != SOCKET_START_POST &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek state != SOCKET_STOP_PRE &&
253f59dff9c93ee1d2c33444b5715e42bc1c6889Lennart Poettering state != SOCKET_STOP_PRE_SIGTERM &&
253f59dff9c93ee1d2c33444b5715e42bc1c6889Lennart Poettering state != SOCKET_STOP_PRE_SIGKILL &&
253f59dff9c93ee1d2c33444b5715e42bc1c6889Lennart Poettering state != SOCKET_STOP_POST &&
253f59dff9c93ee1d2c33444b5715e42bc1c6889Lennart Poettering state != SOCKET_FINAL_SIGTERM &&
253f59dff9c93ee1d2c33444b5715e42bc1c6889Lennart Poettering state != SOCKET_FINAL_SIGKILL) {
253f59dff9c93ee1d2c33444b5715e42bc1c6889Lennart Poettering unit_unwatch_timer(UNIT(s), &s->timer_watch);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_unwatch_control_pid(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->control_command = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (state != SOCKET_LISTENING)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_unwatch_fds(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
804ae586d475d77946debb22c1bc9ee049d4750cLennart Poettering if (state != SOCKET_START_POST &&
804ae586d475d77946debb22c1bc9ee049d4750cLennart Poettering state != SOCKET_LISTENING &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek state != SOCKET_RUNNING &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek state != SOCKET_STOP_PRE &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek state != SOCKET_STOP_PRE_SIGTERM &&
804ae586d475d77946debb22c1bc9ee049d4750cLennart Poettering state != SOCKET_STOP_PRE_SIGKILL)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_close_fds(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
c6878637502b1717a110a9a7e8bba32a8583fcdfLennart Poettering if (state != old_state)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug_unit(UNIT(s)->id,
763c7aa288485cf5ab627fe1d25ff58e76f9dacbZbigniew Jędrzejewski-Szmek "%s changed %s -> %s", UNIT(s)->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_state_to_string(old_state),
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek socket_state_to_string(state));
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek}
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poetteringstatic int socket_coldplug(Unit *u) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Socket *s = SOCKET(u);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8531ae707d4d0203e83304d4af948b8169a5fce1Lennart Poettering assert(s);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering assert(s->state == SOCKET_DEAD);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (s->deserialized_state != s->state) {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (s->deserialized_state == SOCKET_START_PRE ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_START_POST ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_STOP_PRE ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_STOP_PRE_SIGKILL ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_STOP_POST ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_FINAL_SIGTERM ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_FINAL_SIGKILL) {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (s->control_pid <= 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering return -EBADMSG;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering r = unit_watch_pid(UNIT(s), s->control_pid);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (r < 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering return r;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (r < 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering return r;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering }
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (s->deserialized_state == SOCKET_START_POST ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_LISTENING ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_RUNNING ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_STOP_PRE ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->deserialized_state == SOCKET_STOP_PRE_SIGKILL)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if ((r = socket_open_fds(s)) < 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering return r;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (s->deserialized_state == SOCKET_LISTENING)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if ((r = socket_watch_fds(s)) < 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering return r;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_set_state(s, s->deserialized_state);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return 0;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering}
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering pid_t pid;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering int r;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering char **argv;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(c);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering assert(_pid);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (r < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering argv = unit_full_printf_strv(UNIT(s), c->argv);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!argv) {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering r = -ENOMEM;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering r = exec_spawn(c,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering argv,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering &s->exec_context,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering NULL, 0,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering UNIT(s)->manager->environment,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering true,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering true,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering true,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering UNIT(s)->manager->confirm_spawn,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering UNIT(s)->cgroup_bondings,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering UNIT(s)->cgroup_attributes,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering NULL,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering UNIT(s)->id,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering NULL,
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering &pid);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering strv_free(argv);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (r < 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering goto fail;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering /* FIXME: we need to do something here */
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering goto fail;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering *_pid = pid;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poetteringfail:
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering unit_unwatch_timer(UNIT(s), &s->timer_watch);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering return r;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering}
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poetteringstatic void socket_enter_dead(Socket *s, SocketResult f) {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering assert(s);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (f != SOCKET_SUCCESS)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->result = f;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering exec_context_tmp_dirs_done(&s->exec_context);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering}
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poetteringstatic void socket_enter_signal(Socket *s, SocketState state, SocketResult f);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poetteringstatic void socket_enter_stop_post(Socket *s, SocketResult f) {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering int r;
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering assert(s);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (f != SOCKET_SUCCESS)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->result = f;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering socket_unwatch_control_pid(s);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering s->control_command_id = SOCKET_EXEC_STOP_POST;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering goto fail;
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_set_state(s, SOCKET_STOP_POST);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering } else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringfail:
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering log_warning_unit(UNIT(s)->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%s failed to run 'stop-post' task: %s",
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering UNIT(s)->id, strerror(-r));
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering}
74055aa76278232ff05574fc47c4e6b3560554a7Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic void socket_enter_signal(Socket *s, SocketState state, SocketResult f) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering int r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering assert(s);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering if (f != SOCKET_SUCCESS)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->result = f;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = unit_kill_context(
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering UNIT(s),
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering &s->kill_context,
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering state != SOCKET_STOP_PRE_SIGTERM && state != SOCKET_FINAL_SIGTERM,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek -1,
dbd6e31cf91ab86a4a2fffeb50ccef211da3126dLennart Poettering s->control_pid,
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering false);
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering if (r < 0)
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering goto fail;
dbd6e31cf91ab86a4a2fffeb50ccef211da3126dLennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r > 0) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (r < 0)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering goto fail;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_set_state(s, state);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering } else if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_enter_stop_post(s, SOCKET_SUCCESS);
4daf54a851e4fb7ed1a13c3117bba12528fd2c7fZbigniew Jędrzejewski-Szmek else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_enter_dead(s, SOCKET_SUCCESS);
6203e07a83214a55bb1f88508fcda2005c601deaLennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekfail:
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering log_warning_unit(UNIT(s)->id,
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering "%s failed to kill processes: %s",
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering UNIT(s)->id, strerror(-r));
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering else
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering}
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poetteringstatic void socket_enter_stop_pre(Socket *s, SocketResult f) {
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering int r;
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering assert(s);
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering if (f != SOCKET_SUCCESS)
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering s->result = f;
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering socket_unwatch_control_pid(s);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering s->control_command_id = SOCKET_EXEC_STOP_PRE;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering socket_set_state(s, SOCKET_STOP_PRE);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering } else
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering socket_enter_stop_post(s, SOCKET_SUCCESS);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering return;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringfail:
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_warning_unit(UNIT(s)->id,
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering "%s failed to run 'stop-pre' task: %s",
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering UNIT(s)->id, strerror(-r));
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poetteringstatic void socket_enter_listening(Socket *s) {
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering int r;
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering assert(s);
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering r = socket_watch_fds(s);
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering if (r < 0) {
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering log_warning_unit(UNIT(s)->id,
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering "%s failed to watch sockets: %s",
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering UNIT(s)->id, strerror(-r));
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering socket_set_state(s, SOCKET_LISTENING);
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering return;
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poetteringfail:
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering}
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poetteringstatic void socket_enter_start_post(Socket *s) {
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering int r;
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering assert(s);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering r = socket_open_fds(s);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering if (r < 0) {
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering log_warning_unit(UNIT(s)->id,
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering "%s failed to listen on sockets: %s",
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering UNIT(s)->id, strerror(-r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_unwatch_control_pid(s);
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani s->control_command_id = SOCKET_EXEC_START_POST;
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering r = socket_spawn(s, s->control_command, &s->control_pid);
b5884878a2874447b2a9f07f324a7cd909d96d48Lennart Poettering if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_unit(UNIT(s)->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "%s failed to run 'start-post' task: %s",
b5884878a2874447b2a9f07f324a7cd909d96d48Lennart Poettering UNIT(s)->id, strerror(-r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani }
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani
ff82c36c792a23a03994af2ae40cbd441e128bb4Zbigniew Jędrzejewski-Szmek socket_set_state(s, SOCKET_START_POST);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani socket_enter_listening(s);
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani return;
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahanifail:
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void socket_enter_start_pre(Socket *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int r;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_unwatch_control_pid(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->control_command_id = SOCKET_EXEC_START_PRE;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek goto fail;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_set_state(s, SOCKET_START_PRE);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek socket_enter_start_post(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return;
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensenfail:
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen log_warning_unit(UNIT(s)->id,
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen "%s failed to run 'start-pre' task: %s",
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen UNIT(s)->id, strerror(-r));
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void socket_enter_running(Socket *s, int cfd) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int r;
804ae586d475d77946debb22c1bc9ee049d4750cLennart Poettering DBusError error;
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(s);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek dbus_error_init(&error);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* We don't take connections anymore if we are supposed to
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * shut down anyway */
75eb615480afd787fa412f0a529523f568f79b26Lennart Poettering if (unit_stop_pending(UNIT(s))) {
75eb615480afd787fa412f0a529523f568f79b26Lennart Poettering log_debug_unit(UNIT(s)->id,
a9edaeff8481573764288ccf7e433a95b6dc7c03Josh Triplett "Suppressing connection request on %s since unit stop is scheduled.",
a9edaeff8481573764288ccf7e433a95b6dc7c03Josh Triplett UNIT(s)->id);
a9edaeff8481573764288ccf7e433a95b6dc7c03Josh Triplett
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (cfd >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek close_nointr_nofail(cfd);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering else {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering /* Flush all sockets by closing and reopening them */
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk socket_close_fds(s);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk r = socket_watch_fds(s);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r < 0) {
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk log_warning_unit(UNIT(s)->id,
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk "%s failed to watch sockets: %s",
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk UNIT(s)->id, strerror(-r));
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk }
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk }
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk return;
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering }
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering if (cfd < 0) {
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering Iterator i;
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering Unit *u;
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering bool pending = false;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk /* If there's already a start pending don't bother to
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk * do anything */
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERS], i)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (unit_active_or_pending(u)) {
ca2670162464b98f44d3f30a1d8b47b02609784cMichał Bartoszkiewicz pending = true;
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering break;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (!pending) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r < 0)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering goto fail;
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering }
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering socket_set_state(s, SOCKET_RUNNING);
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering } else {
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering char *prefix, *instance = NULL, *name;
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering Service *service;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (s->n_connections >= s->max_connections) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_warning_unit(UNIT(s)->id,
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering "%s: Too many incoming connections (%u)",
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering UNIT(s)->id, s->n_connections);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering close_nointr_nofail(cfd);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = socket_instantiate_service(s);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r < 0)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk goto fail;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk r = instance_from_socket(cfd, s->n_accepted, &instance);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r < 0) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r != -ENOTCONN)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk goto fail;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk /* ENOTCONN is legitimate if TCP RST was received.
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk * This connection is over, but the socket unit lives on. */
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering close_nointr_nofail(cfd);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering return;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering }
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering prefix = unit_name_to_prefix(UNIT(s)->id);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (!prefix) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering free(instance);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = -ENOMEM;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering goto fail;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering }
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering name = unit_name_build(prefix, instance, ".service");
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering free(prefix);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering free(instance);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (!name) {
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt r = -ENOMEM;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering goto fail;
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering }
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner r = unit_add_name(UNIT_DEREF(s->service), name);
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner if (r < 0) {
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner free(name);
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering goto fail;
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering }
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner service = SERVICE(UNIT_DEREF(s->service));
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner unit_ref_unset(&s->service);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt s->n_accepted ++;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering UNIT(service)->no_gc = false;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt unit_choose_id(UNIT(service), name);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt free(name);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = service_set_socket_fd(service, cfd, s);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (r < 0)
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering goto fail;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering cfd = -1;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->n_connections ++;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (r < 0)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering goto fail;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* Notify clients about changed counters */
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering unit_add_to_dbus_queue(UNIT(s));
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering }
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringfail:
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering log_warning_unit(UNIT(s)->id,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering "%s failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering UNIT(s)->id,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering cfd >= 0 ? "template" : "non-template",
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering bus_error(&error, r));
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (cfd >= 0)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering close_nointr_nofail(cfd);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering dbus_error_free(&error);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering}
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic void socket_run_next(Socket *s) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering int r;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering assert(s);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering assert(s->control_command);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering assert(s->control_command->command_next);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering socket_unwatch_control_pid(s);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering s->control_command = s->control_command->command_next;
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering goto fail;
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return;
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poetteringfail:
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering log_warning_unit(UNIT(s)->id,
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering "%s failed to run next task: %s",
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering UNIT(s)->id, strerror(-r));
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (s->state == SOCKET_START_POST)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering else if (s->state == SOCKET_STOP_POST)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering else
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering}
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic int socket_start(Unit *u) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering Socket *s = SOCKET(u);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* We cannot fulfill this request right now, try again later
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering * please! */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (s->state == SOCKET_STOP_PRE ||
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering s->state == SOCKET_STOP_PRE_SIGKILL ||
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering s->state == SOCKET_STOP_PRE_SIGTERM ||
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering s->state == SOCKET_STOP_POST ||
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering s->state == SOCKET_FINAL_SIGTERM ||
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering s->state == SOCKET_FINAL_SIGKILL)
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return -EAGAIN;
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering if (s->state == SOCKET_START_PRE ||
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering s->state == SOCKET_START_POST)
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return 0;
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering /* Cannot run this without the service being around */
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering if (UNIT_DEREF(s->service)) {
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering Service *service;
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering service = SERVICE(UNIT_DEREF(s->service));
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering if (UNIT(service)->load_state != UNIT_LOADED) {
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering log_error_unit(u->id,
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering "Socket service %s not loaded, refusing.",
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering UNIT(service)->id);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return -ENOENT;
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering }
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* If the service is already active we cannot start the
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering * socket */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (service->state != SERVICE_DEAD &&
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering service->state != SERVICE_FAILED &&
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering service->state != SERVICE_AUTO_RESTART) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering log_error_unit(u->id,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering "Socket service %s already active, refusing.",
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering UNIT(service)->id);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return -EBUSY;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering }
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering#ifdef HAVE_SYSV_COMPAT
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (service->is_sysv) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering log_error_unit(u->id,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering "Using SysV services for socket activation is not supported. Refusing.");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return -ENOENT;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering }
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering#endif
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering }
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->result = SOCKET_SUCCESS;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering socket_enter_start_pre(s);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return 0;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering}
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic int socket_stop(Unit *u) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering Socket *s = SOCKET(u);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* Already on it */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (s->state == SOCKET_STOP_PRE ||
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->state == SOCKET_STOP_PRE_SIGTERM ||
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->state == SOCKET_STOP_PRE_SIGKILL ||
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->state == SOCKET_STOP_POST ||
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->state == SOCKET_FINAL_SIGTERM ||
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->state == SOCKET_FINAL_SIGKILL)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return 0;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* If there's already something running we go directly into
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering * kill mode. */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (s->state == SOCKET_START_PRE ||
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->state == SOCKET_START_POST) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return -EAGAIN;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering }
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering socket_enter_stop_pre(s, SOCKET_SUCCESS);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return 0;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering}
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering Socket *s = SOCKET(u);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering SocketPort *p;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering int r;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(u);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering assert(f);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering assert(fds);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
4de2402b603ea2f518f451d06f09e15aeae54fabLennart Poettering unit_serialize_item(u, f, "state", socket_state_to_string(s->state));
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering unit_serialize_item(u, f, "result", socket_result_to_string(s->result));
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering if (s->control_pid > 0)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (s->control_command_id >= 0)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id));
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering LIST_FOREACH(port, p, s->ports) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int copy;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (p->fd < 0)
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek continue;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if ((copy = fdset_put_dup(fds, p->fd)) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return copy;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (p->type == SOCKET_SOCKET) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char *t;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = socket_address_print(&p->address, &t);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering if (r < 0)
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return r;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (socket_address_family(&p->address) == AF_NETLINK)
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek free(t);
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen } else if (p->type == SOCKET_SPECIAL)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path);
e150e82097211f09b911c7784a89ef9efed713caMichał Bartoszkiewicz else if (p->type == SOCKET_MQUEUE)
e150e82097211f09b911c7784a89ef9efed713caMichał Bartoszkiewicz unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(p->type == SOCKET_FIFO);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering exec_context_serialize(&s->exec_context, UNIT(s), f);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
d288f79fb4a2fe4a93cf99f74dacd2cebd3f2440Zbigniew Jędrzejewski-Szmek Socket *s = SOCKET(u);
b1389b0d0805392570085acc7cb10eafcf885405Zbigniew Jędrzejewski-Szmek
b1389b0d0805392570085acc7cb10eafcf885405Zbigniew Jędrzejewski-Szmek assert(u);
d288f79fb4a2fe4a93cf99f74dacd2cebd3f2440Zbigniew Jędrzejewski-Szmek assert(key);
d288f79fb4a2fe4a93cf99f74dacd2cebd3f2440Zbigniew Jędrzejewski-Szmek assert(value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(fds);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (streq(key, "state")) {
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt SocketState state;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek state = socket_state_from_string(value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (state < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug_unit(u->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "Failed to parse state value %s", value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->deserialized_state = state;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering } else if (streq(key, "result")) {
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt SocketResult f;
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek f = socket_result_from_string(value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (f < 0)
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt log_debug_unit(u->id,
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt "Failed to parse result value %s", value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else if (f != SOCKET_SUCCESS)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->result = f;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (streq(key, "n-accepted")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unsigned k;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (safe_atou(value, &k) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug_unit(u->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "Failed to parse n-accepted value %s", value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->n_accepted += k;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (streq(key, "control-pid")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek pid_t pid;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (parse_pid(value, &pid) < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug_unit(u->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "Failed to parse control-pid value %s", value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->control_pid = pid;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (streq(key, "control-command")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketExecCommand id;
03ee5c38cb0da193dd08733fb4c0c2809cee6a99Lennart Poettering
03ee5c38cb0da193dd08733fb4c0c2809cee6a99Lennart Poettering id = socket_exec_command_from_string(value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (id < 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug_unit(u->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "Failed to parse exec-command value %s", value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->control_command_id = id;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->control_command = s->exec_command[id];
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (streq(key, "fifo")) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int fd, skip = 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering SocketPort *p;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_debug_unit(u->id,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "Failed to parse fifo value %s", value);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering else {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering LIST_FOREACH(port, p, s->ports)
4ec3cd7391e119b597375c547cf4ed50fce9f115Lennart Poettering if (p->type == SOCKET_FIFO &&
4ec3cd7391e119b597375c547cf4ed50fce9f115Lennart Poettering streq_ptr(p->path, value+skip))
13790add4bf648fed816361794d8277a75253410Lennart Poettering break;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (p) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (p->fd >= 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering close_nointr_nofail(p->fd);
4ec3cd7391e119b597375c547cf4ed50fce9f115Lennart Poettering p->fd = fdset_remove(fds, fd);
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
4ec3cd7391e119b597375c547cf4ed50fce9f115Lennart Poettering } else if (streq(key, "special")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int fd, skip = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketPort *p;
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug_unit(u->id,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "Failed to parse special value %s", value);
13790add4bf648fed816361794d8277a75253410Lennart Poettering else {
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering LIST_FOREACH(port, p, s->ports)
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (p->type == SOCKET_SPECIAL &&
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek streq_ptr(p->path, value+skip))
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek break;
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek
37b7affefde5443680d73642a990ce86776e28afZbigniew Jędrzejewski-Szmek if (p) {
37b7affefde5443680d73642a990ce86776e28afZbigniew Jędrzejewski-Szmek if (p->fd >= 0)
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek close_nointr_nofail(p->fd);
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek p->fd = fdset_remove(fds, fd);
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek }
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek }
37b7affefde5443680d73642a990ce86776e28afZbigniew Jędrzejewski-Szmek
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else if (streq(key, "mqueue")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int fd, skip = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketPort *p;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
37b7affefde5443680d73642a990ce86776e28afZbigniew Jędrzejewski-Szmek if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug_unit(u->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "Failed to parse mqueue value %s", value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
37b7affefde5443680d73642a990ce86776e28afZbigniew Jędrzejewski-Szmek LIST_FOREACH(port, p, s->ports)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (p->type == SOCKET_MQUEUE &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek streq_ptr(p->path, value+skip))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek if (p) {
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek if (p->fd >= 0)
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek close_nointr_nofail(p->fd);
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek p->fd = fdset_remove(fds, fd);
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek }
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (streq(key, "socket")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek int fd, type, skip = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketPort *p;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd))
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering log_debug_unit(u->id,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "Failed to parse socket value %s", value);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering else {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek LIST_FOREACH(port, p, s->ports)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (socket_address_is(&p->address, value+skip, type))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (p) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (p->fd >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek close_nointr_nofail(p->fd);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering p->fd = fdset_remove(fds, fd);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering } else if (streq(key, "netlink")) {
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering int fd, skip = 0;
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering SocketPort *p;
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering log_debug_unit(u->id,
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "Failed to parse socket value %s", value);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering else {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering LIST_FOREACH(port, p, s->ports)
804ae586d475d77946debb22c1bc9ee049d4750cLennart Poettering if (socket_address_is_netlink(&p->address, value+skip))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (p) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (p->fd >= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek close_nointr_nofail(p->fd);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek p->fd = fdset_remove(fds, fd);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek }
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (streq(key, "tmp-dir")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char *t;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek t = strdup(value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!t)
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt return log_oom();
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->exec_context.tmp_dir = t;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (streq(key, "var-tmp-dir")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char *t;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek t = strdup(value);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!t)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_oom();
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->exec_context.var_tmp_dir = t;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug_unit(UNIT(s)->id,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "Unknown serialization key '%s'", key);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidtstatic int socket_distribute_fds(Unit *u, FDSet *fds) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Socket *s = SOCKET(u);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek SocketPort *p;
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(u);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering LIST_FOREACH(port, p, s->ports) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering Iterator i;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering int fd;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (p->type != SOCKET_SOCKET)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering continue;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (p->fd >= 0)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering continue;
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering FDSET_FOREACH(fd, fds, i) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (socket_address_matches_fd(&p->address, fd)) {
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering p->fd = fdset_remove(fds, fd);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering s->deserialized_state = SOCKET_LISTENING;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek break;
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering }
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering }
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering }
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering}
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering_pure_ static UnitActiveState socket_active_state(Unit *u) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(u);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return state_translation_table[SOCKET(u)->state];
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek_pure_ static const char *socket_sub_state_to_string(Unit *u) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(u);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering return socket_state_to_string(SOCKET(u)->state);
99d0966e75a984bed4f117c888ecc93e16e7b7b6Lennart Poettering}
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekconst char* socket_port_type_to_string(SocketPort *p) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(p);
3e044c492e3ebe64f4e3175c94f9db8a62557b82Markus Elfring
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek switch (p->type) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering case SOCKET_SOCKET:
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering switch (p->address.type) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering case SOCK_STREAM: return "Stream";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering case SOCK_DGRAM: return "Datagram";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering case SOCK_SEQPACKET: return "SequentialPacket";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering case SOCK_RAW:
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (socket_address_family(&p->address) == AF_NETLINK)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return "Netlink";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering default: return "Invalid";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering }
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering case SOCKET_SPECIAL: return "Special";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering case SOCKET_MQUEUE: return "MessageQueue";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering case SOCKET_FIFO: return "FIFO";
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering default: return NULL;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering }
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering}
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering_pure_ static bool socket_check_gc(Unit *u) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering Socket *s = SOCKET(u);
assert(u);
return s->n_connections > 0;
}
static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
Socket *s = SOCKET(u);
int cfd = -1;
assert(s);
assert(fd >= 0);
if (s->state != SOCKET_LISTENING)
return;
log_debug_unit(u->id, "Incoming traffic on %s", u->id);
if (events != EPOLLIN) {
if (events & EPOLLHUP)
log_error_unit(u->id,
"%s: Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that.",
u->id);
else
log_error_unit(u->id,
"%s: Got unexpected poll event (0x%x) on socket.",
u->id, events);
goto fail;
}
if (w->socket_accept) {
for (;;) {
cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK);
if (cfd < 0) {
if (errno == EINTR)
continue;
log_error_unit(u->id,
"Failed to accept socket: %m");
goto fail;
}
break;
}
socket_apply_socket_options(s, cfd);
}
socket_enter_running(s, cfd);
return;
fail:
socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
}
static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
Socket *s = SOCKET(u);
SocketResult f;
assert(s);
assert(pid >= 0);
if (pid != s->control_pid)
return;
s->control_pid = 0;
if (is_clean_exit(code, status, NULL))
f = SOCKET_SUCCESS;
else if (code == CLD_EXITED)
f = SOCKET_FAILURE_EXIT_CODE;
else if (code == CLD_KILLED)
f = SOCKET_FAILURE_SIGNAL;
else if (code == CLD_DUMPED)
f = SOCKET_FAILURE_CORE_DUMP;
else
assert_not_reached("Unknown 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_full_unit(f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
u->id,
"%s control process exited, code=%s status=%i",
u->id, 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_debug_unit(u->id,
"%s running next command for state %s",
u->id, 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_debug_unit(u->id,
"%s got final SIGCHLD for state %s",
u->id, socket_state_to_string(s->state));
switch (s->state) {
case SOCKET_START_PRE:
if (f == SOCKET_SUCCESS)
socket_enter_start_post(s);
else
socket_enter_signal(s, SOCKET_FINAL_SIGTERM, 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 void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
Socket *s = SOCKET(u);
assert(s);
assert(elapsed == 1);
assert(w == &s->timer_watch);
switch (s->state) {
case SOCKET_START_PRE:
log_warning_unit(u->id,
"%s starting timed out. Terminating.", u->id);
socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_START_POST:
log_warning_unit(u->id,
"%s starting timed out. Stopping.", u->id);
socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_STOP_PRE:
log_warning_unit(u->id,
"%s stopping timed out. Terminating.", u->id);
socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_STOP_PRE_SIGTERM:
if (s->kill_context.send_sigkill) {
log_warning_unit(u->id,
"%s stopping timed out. Killing.", u->id);
socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT);
} else {
log_warning_unit(u->id,
"%s stopping timed out. Skipping SIGKILL. Ignoring.",
u->id);
socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
}
break;
case SOCKET_STOP_PRE_SIGKILL:
log_warning_unit(u->id,
"%s still around after SIGKILL. Ignoring.", u->id);
socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_STOP_POST:
log_warning_unit(u->id,
"%s stopping timed out (2). Terminating.", u->id);
socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
break;
case SOCKET_FINAL_SIGTERM:
if (s->kill_context.send_sigkill) {
log_warning_unit(u->id,
"%s stopping timed out (2). Killing.", u->id);
socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT);
} else {
log_warning_unit(u->id,
"%s stopping timed out (2). Skipping SIGKILL. Ignoring.",
u->id);
socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
}
break;
case SOCKET_FINAL_SIGKILL:
log_warning_unit(u->id,
"%s still around after SIGKILL (2). Entering failed mode.",
u->id);
socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
break;
default:
assert_not_reached("Timeout at wrong time.");
}
}
int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
int *rfds;
unsigned rn_fds, k;
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++;
if (rn_fds <= 0) {
*fds = NULL;
*n_fds = 0;
return 0;
}
if (!(rfds = new(int, rn_fds)))
return -ENOMEM;
k = 0;
LIST_FOREACH(port, p, s->ports)
if (p->fd >= 0)
rfds[k++] = p->fd;
assert(k == rn_fds);
*fds = rfds;
*n_fds = rn_fds;
return 0;
}
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_debug_unit(UNIT(s)->id,
"%s got notified about service death (failed permanently: %s)",
UNIT(s)->id, 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_debug_unit(UNIT(s)->id,
"%s: One connection closed, %u left.", UNIT(s)->id, s->n_connections);
}
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 int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) {
return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
}
static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
[SOCKET_DEAD] = "dead",
[SOCKET_START_PRE] = "start-pre",
[SOCKET_START_POST] = "start-post",
[SOCKET_LISTENING] = "listening",
[SOCKET_RUNNING] = "running",
[SOCKET_STOP_PRE] = "stop-pre",
[SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
[SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
[SOCKET_STOP_POST] = "stop-post",
[SOCKET_FINAL_SIGTERM] = "final-sigterm",
[SOCKET_FINAL_SIGKILL] = "final-sigkill",
[SOCKET_FAILED] = "failed"
};
DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
[SOCKET_EXEC_START_PRE] = "StartPre",
[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),
.sections =
"Unit\0"
"Socket\0"
"Install\0",
.exec_context_offset = offsetof(Socket, exec_context),
.exec_section = "Socket",
.init = socket_init,
.done = socket_done,
.load = socket_load,
.kill = socket_kill,
.coldplug = socket_coldplug,
.dump = socket_dump,
.start = socket_start,
.stop = socket_stop,
.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,
.fd_event = socket_fd_event,
.sigchld_event = socket_sigchld_event,
.timer_event = socket_timer_event,
.reset_failed = socket_reset_failed,
.bus_interface = "org.freedesktop.systemd1.Socket",
.bus_message_handler = bus_socket_message_handler,
.bus_invalidating_properties = bus_socket_invalidating_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_DEPENDENCY] = "Dependency failed for %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.",
},
},
};