diff options
Diffstat (limited to 'src/systemd-activate')
-rw-r--r-- | src/systemd-activate/Makefile | 8 | ||||
-rw-r--r-- | src/systemd-activate/activate.c | 118 | ||||
-rw-r--r-- | src/systemd-activate/systemd-activate.xml | 204 |
3 files changed, 80 insertions, 250 deletions
diff --git a/src/systemd-activate/Makefile b/src/systemd-activate/Makefile index 058e10809e..5e2299f00e 100644 --- a/src/systemd-activate/Makefile +++ b/src/systemd-activate/Makefile @@ -24,13 +24,13 @@ include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk include $(topsrcdir)/build-aux/Makefile.head.mk -libexec_PROGRAMS += \ - systemd-activate +bin_PROGRAMS += \ + systemd-socket-activate -systemd_activate_SOURCES = \ +systemd_socket_activate_SOURCES = \ src/activate/activate.c -systemd_activate_LDADD = \ +systemd_socket_activate_LDADD = \ libshared.la include $(topsrcdir)/build-aux/Makefile.tail.mk diff --git a/src/systemd-activate/activate.c b/src/systemd-activate/activate.c index 94f99028e5..89cc1ee813 100644 --- a/src/systemd-activate/activate.c +++ b/src/systemd-activate/activate.c @@ -27,6 +27,7 @@ #include <systemd/sd-daemon.h> #include "alloc-util.h" +#include "escape.h" #include "fd-util.h" #include "log.h" #include "macro.h" @@ -40,7 +41,7 @@ static bool arg_accept = false; static int arg_socket_type = SOCK_STREAM; static char** arg_args = NULL; static char** arg_setenv = NULL; -static const char *arg_fdname = NULL; +static char **arg_fdnames = NULL; static bool arg_inetd = false; static int add_epoll(int epoll_fd, int fd) { @@ -76,7 +77,7 @@ static int open_sockets(int *epoll_fd, bool accept) { if (r < 0) return r; - count ++; + count++; } } @@ -104,7 +105,7 @@ static int open_sockets(int *epoll_fd, bool accept) { } assert(fd == SD_LISTEN_FDS_START + count); - count ++; + count++; } if (arg_listen) @@ -134,7 +135,6 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd, _cleanup_free_ char *joined = NULL; unsigned n_env = 0, length; const char *tocopy; - unsigned i; char **s; int r; @@ -176,7 +176,7 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd, if (!envp[n_env]) return log_oom(); - n_env ++; + n_env++; } } @@ -191,7 +191,7 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd, if (!envp[n_env]) return log_oom(); - n_env ++; + n_env++; } if (arg_inetd) { @@ -224,25 +224,30 @@ static int exec_process(const char* name, char **argv, char **env, int start_fd, if (asprintf((char**)(envp + n_env++), "LISTEN_PID=" PID_FMT, getpid()) < 0) return log_oom(); - if (arg_fdname) { + if (arg_fdnames) { + _cleanup_free_ char *names = NULL; + size_t len; char *e; + int i; + + len = strv_length(arg_fdnames); + if (len == 1) + for (i = 1; i < n_fds; i++) { + r = strv_extend(&arg_fdnames, arg_fdnames[0]); + if (r < 0) + return log_error_errno(r, "Failed to extend strv: %m"); + } + else if (len != (unsigned) n_fds) + log_warning("The number of fd names is different than number of fds: %zu vs %d", + len, n_fds); - e = strappend("LISTEN_FDNAMES=", arg_fdname); - if (!e) + names = strv_join(arg_fdnames, ":"); + if (!names) return log_oom(); - for (i = 1; i < (unsigned) n_fds; i++) { - char *c; - - c = strjoin(e, ":", arg_fdname, NULL); - if (!c) { - free(e); - return log_oom(); - } - - free(e); - e = c; - } + e = strappend("LISTEN_FDNAMES=", names); + if (!e) + return log_oom(); envp[n_env++] = e; } @@ -311,19 +316,31 @@ static int do_accept(const char* name, char **argv, char **envp, int fd) { } /* SIGCHLD handler. */ -static void sigchld_hdl(int sig, siginfo_t *t, void *data) { +static void sigchld_hdl(int sig) { PROTECT_ERRNO; - log_info("Child %d died with code %d", t->si_pid, t->si_status); + for (;;) { + siginfo_t si; + int r; + + si.si_pid = 0; + r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG); + if (r < 0) { + if (errno != ECHILD) + log_error_errno(errno, "Failed to reap children: %m"); + return; + } + if (si.si_pid == 0) + return; - /* Wait for a dead child. */ - (void) waitpid(t->si_pid, NULL, 0); + log_info("Child %d died with code %d", si.si_pid, si.si_status); + } } static int install_chld_handler(void) { static const struct sigaction act = { - .sa_flags = SA_SIGINFO, - .sa_sigaction = sigchld_hdl, + .sa_flags = SA_NOCLDSTOP, + .sa_handler = sigchld_hdl, }; int r; @@ -339,14 +356,15 @@ static void help(void) { printf("%s [OPTIONS...]\n\n" "Listen on sockets and launch child on connection.\n\n" "Options:\n" - " -h --help Show this help and exit\n" - " --version Print version string and exit\n" - " -l --listen=ADDR Listen for raw connections at ADDR\n" - " -d --datagram Listen on datagram instead of stream socket\n" - " --seqpacket Listen on SOCK_SEQPACKET instead of stream socket\n" - " -a --accept Spawn separate child for each connection\n" - " -E --setenv=NAME[=VALUE] Pass an environment variable to children\n" - " --inetd Enable inetd file descriptor passing protocol\n" + " -h --help Show this help and exit\n" + " --version Print version string and exit\n" + " -l --listen=ADDR Listen for raw connections at ADDR\n" + " -d --datagram Listen on datagram instead of stream socket\n" + " --seqpacket Listen on SOCK_SEQPACKET instead of stream socket\n" + " -a --accept Spawn separate child for each connection\n" + " -E --setenv=NAME[=VALUE] Pass an environment variable to children\n" + " --fdname=NAME[:NAME...] Specify names for file descriptors\n" + " --inetd Enable inetd file descriptor passing protocol\n" "\n" "Note: file descriptors from sd_listen_fds() will be passed through.\n" , program_invocation_short_name); @@ -379,7 +397,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "+hl:aEd", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "+hl:aE:d", options, NULL)) >= 0) switch(c) { case 'h': help(); @@ -424,14 +442,30 @@ static int parse_argv(int argc, char *argv[]) { break; - case ARG_FDNAME: - if (!fdname_is_valid(optarg)) { - log_error("File descriptor name %s is not valid, refusing.", optarg); - return -EINVAL; - } + case ARG_FDNAME: { + _cleanup_strv_free_ char **names; + char **s; + + names = strv_split(optarg, ":"); + if (!names) + return log_oom(); - arg_fdname = optarg; + STRV_FOREACH(s, names) + if (!fdname_is_valid(*s)) { + _cleanup_free_ char *esc; + + esc = cescape(*s); + log_warning("File descriptor name \"%s\" is not valid.", esc); + } + + /* Empty optargs means one empty name */ + r = strv_extend_strv(&arg_fdnames, + strv_isempty(names) ? STRV_MAKE("") : names, + false); + if (r < 0) + return log_error_errno(r, "strv_extend_strv: %m"); break; + } case ARG_INETD: arg_inetd = true; diff --git a/src/systemd-activate/systemd-activate.xml b/src/systemd-activate/systemd-activate.xml deleted file mode 100644 index 995e6eecce..0000000000 --- a/src/systemd-activate/systemd-activate.xml +++ /dev/null @@ -1,204 +0,0 @@ -<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*--> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" -"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> - -<!-- - This file is part of systemd. - - Copyright 2013 Zbigniew Jędrzejewski-Szmek - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. ---> - -<refentry id="systemd-activate" - xmlns:xi="http://www.w3.org/2001/XInclude"> - - <refentryinfo> - <title>systemd-activate</title> - <productname>systemd</productname> - - <authorgroup> - <author> - <contrib>Developer</contrib> - <firstname>Zbigniew</firstname> - <surname>Jędrzejewski-Szmek</surname> - <email>zbyszek@in.waw.pl</email> - </author> - </authorgroup> - </refentryinfo> - - <refmeta> - <refentrytitle>systemd-activate</refentrytitle> - <manvolnum>8</manvolnum> - </refmeta> - - <refnamediv> - <refname>systemd-activate</refname> - <refpurpose>Test socket activation of daemons</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis> - <command>/usr/lib/systemd/systemd-activate</command> - <arg choice="opt" rep="repeat">OPTIONS</arg> - <arg choice="plain"><replaceable>daemon</replaceable></arg> - <arg choice="opt" rep="repeat">OPTIONS</arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1> - <title>Description</title> - - <para><command>systemd-activate</command> may be used to launch a socket-activated service binary from the command - line for testing purposes. It may also be used to launch individual instances of the service binary per connection. - </para> - - <para>The daemon to launch and its options should be specified - after options intended for <command>systemd-activate</command>. - </para> - - <para>If the <option>--inetd</option> option is given, the socket file descriptor will be used as the standard - input and output of the launched process. Otherwise, standard input and output will be inherited, and sockets will - be passed through file descriptors 3 and higher. Sockets passed through <varname>$LISTEN_FDS</varname> to - <command>systemd-activate</command> will be passed through to the daemon, in the original positions. Other sockets - specified with <option>--listen=</option> will use consecutive descriptors. By default, - <command>systemd-activate</command> listens on a stream socket, use <option>--datagram</option> and - <option>--seqpacket</option> to listen on datagram or sequential packet sockets instead (see below). - </para> - </refsect1> - - <refsect1> - <title>Options</title> - <variablelist> - <varlistentry> - <term><option>-l <replaceable>address</replaceable></option></term> - <term><option>--listen=<replaceable>address</replaceable></option></term> - - <listitem><para>Listen on this <replaceable>address</replaceable>. - Takes a string like <literal>2000</literal> or - <literal>127.0.0.1:2001</literal>.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><option>-a</option></term> - <term><option>--accept</option></term> - - <listitem><para>Launch an instance of the service binary for each connection and pass the connection - socket.</para></listitem> - </varlistentry> - - <varlistentry> - <term><option>-d</option></term> - <term><option>--datagram</option></term> - - <listitem><para>Listen on a datagram socket (<constant>SOCK_DGRAM</constant>), instead of a stream socket - (<constant>SOCK_STREAM</constant>). May not be combined with <option>--seqpacket</option>.</para></listitem> - </varlistentry> - - <varlistentry> - <term><option>--seqpacket</option></term> - - <listitem><para>Listen on a sequential packet socket (<constant>SOCK_SEQPACKET</constant>), instead of a stream - socket (<constant>SOCK_STREAM</constant>). May not be combined with - <option>--datagram</option>.</para></listitem> - </varlistentry> - - <varlistentry> - <term><option>--inetd</option></term> - - <listitem><para>Use the inetd protocol for passing file descriptors, i.e. as standard input and standard - output, instead of the new-style protocol for passing file descriptors using <varname>$LISTEN_FDS</varname> - (see above).</para></listitem> - </varlistentry> - - <varlistentry> - <term><option>-E <replaceable>VAR</replaceable><optional>=<replaceable>VALUE</replaceable></optional></option></term> - <term><option>--setenv=<replaceable>VAR</replaceable><optional>=<replaceable>VALUE</replaceable></optional></option></term> - - <listitem><para>Add this variable to the environment of the - launched process. If <replaceable>VAR</replaceable> is - followed by <literal>=</literal>, assume that it is a - variable–value pair. Otherwise, obtain the value from the - environment of <command>systemd-activate</command> itself. - </para></listitem> - </varlistentry> - - <varlistentry> - <term><option>--fdname=</option><replaceable>NAME</replaceable></term> - - <listitem><para>Specify a name for the activation file - descriptors. This is equivalent to setting - <varname>FileDescriptorName=</varname> in socket unit files, and - enables use of - <citerefentry><refentrytitle>sd_listen_fds_with_names</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem> - </varlistentry> - - <xi:include href="standard-options.xml" xpointer="help" /> - <xi:include href="standard-options.xml" xpointer="version" /> - </variablelist> - </refsect1> - - <refsect1> - <title>Environment variables</title> - <variablelist class='environment-variables'> - <varlistentry> - <term><varname>$LISTEN_FDS</varname></term> - <term><varname>$LISTEN_PID</varname></term> - <term><varname>$LISTEN_FDNAMES</varname></term> - - <listitem><para>See - <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem> - </varlistentry> - - <varlistentry> - <term><varname>$SYSTEMD_LOG_TARGET</varname></term> - <term><varname>$SYSTEMD_LOG_LEVEL</varname></term> - <term><varname>$SYSTEMD_LOG_COLOR</varname></term> - <term><varname>$SYSTEMD_LOG_LOCATION</varname></term> - - <listitem><para>Same as in - <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para></listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1> - <title>Examples</title> - - <example> - <title>Run an echo server on port 2000</title> - - <programlisting>$ /usr/lib/systemd/systemd-activate -l 2000 --inetd -a cat</programlisting> - </example> - - <example> - <title>Run a socket-activated instance of <citerefentry><refentrytitle>systemd-journal-gatewayd</refentrytitle><manvolnum>8</manvolnum></citerefentry></title> - - <programlisting>$ /usr/lib/systemd/systemd-activate -l 19531 /usr/lib/systemd/systemd-journal-gatewayd</programlisting> - </example> - </refsect1> - - <refsect1> - <title>See Also</title> - <para> - <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, - <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>, - <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>, - <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>, - <citerefentry><refentrytitle>sd_listen_fds_with_names</refentrytitle><manvolnum>3</manvolnum></citerefentry>, - <citerefentry project='man-pages'><refentrytitle>cat</refentrytitle><manvolnum>1</manvolnum></citerefentry> - </para> - </refsect1> -</refentry> |