Merge pull request #2596 from keszybz/move-activate-to-bin

Move activate to bin, extend --fdnames functionality
This commit is contained in:
Lennart Poettering 2016-02-15 14:08:28 +01:00
commit 4d5d9d0011
8 changed files with 112 additions and 60 deletions

2
.gitignore vendored
View File

@ -49,7 +49,6 @@
/systemctl
/systemd
/systemd-ac-power
/systemd-activate
/systemd-analyze
/systemd-ask-password
/systemd-backlight
@ -109,6 +108,7 @@
/systemd-run
/systemd-shutdown
/systemd-sleep
/systemd-socket-activate
/systemd-socket-proxyd
/systemd-stdio-bridge
/systemd-sysctl

View File

@ -94,7 +94,6 @@ MANPAGES += \
man/shutdown.8 \
man/sysctl.d.5 \
man/systemctl.1 \
man/systemd-activate.8 \
man/systemd-analyze.1 \
man/systemd-ask-password-console.service.8 \
man/systemd-ask-password.1 \
@ -126,6 +125,7 @@ MANPAGES += \
man/systemd-resolve.1 \
man/systemd-run.1 \
man/systemd-sleep.conf.5 \
man/systemd-socket-activate.1 \
man/systemd-socket-proxyd.8 \
man/systemd-suspend.service.8 \
man/systemd-sysctl.service.8 \
@ -2574,7 +2574,6 @@ EXTRA_DIST += \
man/standard-options.xml \
man/sysctl.d.xml \
man/systemctl.xml \
man/systemd-activate.xml \
man/systemd-analyze.xml \
man/systemd-ask-password-console.service.xml \
man/systemd-ask-password.xml \
@ -2628,6 +2627,7 @@ EXTRA_DIST += \
man/systemd-rfkill.service.xml \
man/systemd-run.xml \
man/systemd-sleep.conf.xml \
man/systemd-socket-activate.xml \
man/systemd-socket-proxyd.xml \
man/systemd-suspend.service.xml \
man/systemd-sysctl.service.xml \

View File

@ -3875,13 +3875,13 @@ tests += \
# ------------------------------------------------------------------------------
rootlibexec_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
# ------------------------------------------------------------------------------

6
NEWS
View File

@ -1,5 +1,11 @@
systemd System and Service Manager
CHANGES WITH 230 in spe:
* Testing tool /usr/lib/systemd/systemd-activate is renamed to
systemd-socket-activate and installed into /usr/bin. It is now fully
supported.
CHANGES WITH 229:
* The systemd-resolved DNS resolver service has gained a substantial

View File

@ -21,11 +21,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
<refentry id="systemd-activate"
<refentry id="systemd-socket-activate"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>systemd-activate</title>
<title>systemd-socket-activate</title>
<productname>systemd</productname>
<authorgroup>
@ -39,18 +39,18 @@
</refentryinfo>
<refmeta>
<refentrytitle>systemd-activate</refentrytitle>
<manvolnum>8</manvolnum>
<refentrytitle>systemd-socket-activate</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>systemd-activate</refname>
<refname>systemd-socket-activate</refname>
<refpurpose>Test socket activation of daemons</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>/usr/lib/systemd/systemd-activate</command>
<command>systemd-socket-activate</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain"><replaceable>daemon</replaceable></arg>
<arg choice="opt" rep="repeat">OPTIONS</arg>
@ -60,20 +60,20 @@
<refsect1>
<title>Description</title>
<para><command>systemd-activate</command> may be used to launch a socket-activated service binary from the command
<para><command>systemd-socket-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>.
after options intended for <command>systemd-socket-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
<command>systemd-socket-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
<command>systemd-socket-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>
@ -131,18 +131,20 @@
launched process. If <replaceable>VAR</replaceable> is
followed by <literal>=</literal>, assume that it is a
variablevalue pair. Otherwise, obtain the value from the
environment of <command>systemd-activate</command> itself.
environment of <command>systemd-socket-activate</command> itself.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--fdname=</option><replaceable>NAME</replaceable></term>
<term><option>--fdname=</option><replaceable>NAME</replaceable><optional>:<replaceable>NAME</replaceable>...</optional></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>
<listitem><para>Specify names for the file descriptors passed. 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>.
Multiple entries may be specifies using separate options or by separating names with colons
(<literal>:</literal>) in one option. In case more names are given than descriptors, superflous ones willl be
ignored. In case less names are given than descriptors, the remaining file descriptors will be unnamed.
</para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
@ -180,13 +182,13 @@
<example>
<title>Run an echo server on port 2000</title>
<programlisting>$ /usr/lib/systemd/systemd-activate -l 2000 --inetd -a cat</programlisting>
<programlisting>$ systemd-socket-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>
<programlisting>$ systemd-socket-activate -l 19531 /usr/lib/systemd/systemd-journal-gatewayd</programlisting>
</example>
</refsect1>

View File

@ -27,6 +27,7 @@
#include "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) {
@ -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;
@ -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;
e = strappend("LISTEN_FDNAMES=", arg_fdname);
if (!e)
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);
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;
}
@ -339,14 +344,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);
@ -424,14 +430,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;
arg_fdname = optarg;
names = strv_split(optarg, ":");
if (!names)
return log_oom();
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;

View File

@ -371,7 +371,7 @@ char *strv_join(char **l, const char *separator) {
n = 0;
STRV_FOREACH(s, l) {
if (n != 0)
if (s != l)
n += k;
n += strlen(*s);
}
@ -382,7 +382,7 @@ char *strv_join(char **l, const char *separator) {
e = r;
STRV_FOREACH(s, l) {
if (e != r)
if (s != l)
e = stpcpy(e, separator);
e = stpcpy(e, *s);

View File

@ -70,6 +70,18 @@ static const char* const input_table_none[] = {
NULL,
};
static const char* const input_table_two_empties[] = {
"",
"",
NULL,
};
static const char* const input_table_one_empty[] = {
"",
NULL,
};
static const char* const input_table_quotes[] = {
"\"",
"'",
@ -130,7 +142,7 @@ static void test_strv_find_startswith(void) {
}
static void test_strv_join(void) {
_cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL;
_cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
p = strv_join((char **)input_table_multiple, ", ");
assert_se(p);
@ -151,6 +163,14 @@ static void test_strv_join(void) {
t = strv_join((char **)input_table_none, ", ");
assert_se(t);
assert_se(streq(t, ""));
v = strv_join((char **)input_table_two_empties, ", ");
assert_se(v);
assert_se(streq(v, ", "));
w = strv_join((char **)input_table_one_empty, ", ");
assert_se(w);
assert_se(streq(w, ""));
}
static void test_strv_quote_unquote(const char* const *split, const char *quoted) {
@ -653,6 +673,8 @@ int main(int argc, char *argv[]) {
test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
test_strv_quote_unquote(input_table_one, "\"one\"");
test_strv_quote_unquote(input_table_none, "");
test_strv_quote_unquote(input_table_one_empty, "\"\"");
test_strv_quote_unquote(input_table_two_empties, "\"\" \"\"");
test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
test_strv_quote_unquote(input_table_spaces, SPACES_STRING);