mirror of
https://github.com/systemd/systemd.git
synced 2025-01-03 05:18:09 +03:00
Merge pull request #31789 from jsitnicki/socket-pass-fds-to-exec
Pass socket FDs to all ExecXYZ= commands in socket unit but ExecStartPre=
This commit is contained in:
commit
93998559f8
@ -4821,6 +4821,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
|||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly b PassCredentials = ...;
|
readonly b PassCredentials = ...;
|
||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
|
readonly b PassFileDescriptorsToExec = ...;
|
||||||
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly b PassSecurity = ...;
|
readonly b PassSecurity = ...;
|
||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly b PassPacketInfo = ...;
|
readonly b PassPacketInfo = ...;
|
||||||
@ -5488,6 +5490,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
|||||||
|
|
||||||
<!--property PassCredentials is not documented!-->
|
<!--property PassCredentials is not documented!-->
|
||||||
|
|
||||||
|
<!--property PassFileDescriptorsToExec is not documented!-->
|
||||||
|
|
||||||
<!--property PassSecurity is not documented!-->
|
<!--property PassSecurity is not documented!-->
|
||||||
|
|
||||||
<!--property PassPacketInfo is not documented!-->
|
<!--property PassPacketInfo is not documented!-->
|
||||||
@ -6100,6 +6104,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
|||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="PassCredentials"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="PassCredentials"/>
|
||||||
|
|
||||||
|
<variablelist class="dbus-property" generated="True" extra-ref="PassFileDescriptorsToExec"/>
|
||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="PassSecurity"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="PassSecurity"/>
|
||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="PassPacketInfo"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="PassPacketInfo"/>
|
||||||
@ -12061,8 +12067,9 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
|||||||
<varname>MemoryZSwapCurrent</varname> were added in version 255.</para>
|
<varname>MemoryZSwapCurrent</varname> were added in version 255.</para>
|
||||||
<para><varname>EffectiveMemoryHigh</varname>,
|
<para><varname>EffectiveMemoryHigh</varname>,
|
||||||
<varname>EffectiveMemoryMax</varname>,
|
<varname>EffectiveMemoryMax</varname>,
|
||||||
<varname>EffectiveTasksMax</varname>, and
|
<varname>EffectiveTasksMax</varname>,
|
||||||
<varname>MemoryZSwapWriteback</varname> were added in version 256.</para>
|
<varname>MemoryZSwapWriteback</varname>, and
|
||||||
|
<varname>PassFileDescriptorsToExec</varname> were added in version 256.</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
<refsect2>
|
<refsect2>
|
||||||
<title>Mount Unit Objects</title>
|
<title>Mount Unit Objects</title>
|
||||||
|
@ -922,6 +922,20 @@
|
|||||||
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>PassFileDescriptorsToExec=</varname></term>
|
||||||
|
|
||||||
|
<listitem><para>Takes a boolean argument. Defaults to off. If enabled, file descriptors created by
|
||||||
|
the socket unit are passed to <varname>ExecStartPost=</varname>, <varname>ExecStopPre=</varname>, and
|
||||||
|
<varname>ExecStopPost=</varname> commands from the socket unit. The passed file descriptors can be
|
||||||
|
accessed with
|
||||||
|
<citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry> as
|
||||||
|
if the commands were invoked from the associated service units. Note that
|
||||||
|
<varname>ExecStartPre=</varname> command cannot access socket file descriptors.</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
<xi:include href="systemd.service.xml" xpointer="shared-unit-options" />
|
<xi:include href="systemd.service.xml" xpointer="shared-unit-options" />
|
||||||
|
@ -86,6 +86,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
|
|||||||
SD_BUS_PROPERTY("Transparent", "b", bus_property_get_bool, offsetof(Socket, transparent), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Transparent", "b", bus_property_get_bool, offsetof(Socket, transparent), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("Broadcast", "b", bus_property_get_bool, offsetof(Socket, broadcast), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Broadcast", "b", bus_property_get_bool, offsetof(Socket, broadcast), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("PassCredentials", "b", bus_property_get_bool, offsetof(Socket, pass_cred), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("PassCredentials", "b", bus_property_get_bool, offsetof(Socket, pass_cred), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("PassFileDescriptorsToExec", "b", bus_property_get_bool, offsetof(Socket, pass_fds_to_exec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("PassPacketInfo", "b", bus_property_get_bool, offsetof(Socket, pass_pktinfo), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("PassPacketInfo", "b", bus_property_get_bool, offsetof(Socket, pass_pktinfo), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("Timestamping", "s", property_get_timestamping, offsetof(Socket, timestamping), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Timestamping", "s", property_get_timestamping, offsetof(Socket, timestamping), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
@ -190,6 +191,9 @@ static int bus_socket_set_transient_property(
|
|||||||
if (streq(name, "PassCredentials"))
|
if (streq(name, "PassCredentials"))
|
||||||
return bus_set_transient_bool(u, name, &s->pass_cred, message, flags, error);
|
return bus_set_transient_bool(u, name, &s->pass_cred, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "PassFileDescriptorsToExec"))
|
||||||
|
return bus_set_transient_bool(u, name, &s->pass_fds_to_exec, message, flags, error);
|
||||||
|
|
||||||
if (streq(name, "PassSecurity"))
|
if (streq(name, "PassSecurity"))
|
||||||
return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error);
|
return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error);
|
||||||
|
|
||||||
|
@ -500,6 +500,7 @@ Socket.FreeBind, config_parse_bool,
|
|||||||
Socket.Transparent, config_parse_bool, 0, offsetof(Socket, transparent)
|
Socket.Transparent, config_parse_bool, 0, offsetof(Socket, transparent)
|
||||||
Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast)
|
Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast)
|
||||||
Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred)
|
Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred)
|
||||||
|
Socket.PassFileDescriptorsToExec, config_parse_bool, 0, offsetof(Socket, pass_fds_to_exec)
|
||||||
Socket.PassSecurity, config_parse_bool, 0, offsetof(Socket, pass_sec)
|
Socket.PassSecurity, config_parse_bool, 0, offsetof(Socket, pass_sec)
|
||||||
Socket.PassPacketInfo, config_parse_bool, 0, offsetof(Socket, pass_pktinfo)
|
Socket.PassPacketInfo, config_parse_bool, 0, offsetof(Socket, pass_pktinfo)
|
||||||
Socket.Timestamping, config_parse_socket_timestamping, 0, offsetof(Socket, timestamping)
|
Socket.Timestamping, config_parse_socket_timestamping, 0, offsetof(Socket, timestamping)
|
||||||
|
@ -590,6 +590,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
|
|||||||
"%sTransparent: %s\n"
|
"%sTransparent: %s\n"
|
||||||
"%sBroadcast: %s\n"
|
"%sBroadcast: %s\n"
|
||||||
"%sPassCredentials: %s\n"
|
"%sPassCredentials: %s\n"
|
||||||
|
"%sPassFileDescriptorsToExec: %s\n"
|
||||||
"%sPassSecurity: %s\n"
|
"%sPassSecurity: %s\n"
|
||||||
"%sPassPacketInfo: %s\n"
|
"%sPassPacketInfo: %s\n"
|
||||||
"%sTCPCongestion: %s\n"
|
"%sTCPCongestion: %s\n"
|
||||||
@ -610,6 +611,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
|
|||||||
prefix, yes_no(s->transparent),
|
prefix, yes_no(s->transparent),
|
||||||
prefix, yes_no(s->broadcast),
|
prefix, yes_no(s->broadcast),
|
||||||
prefix, yes_no(s->pass_cred),
|
prefix, yes_no(s->pass_cred),
|
||||||
|
prefix, yes_no(s->pass_fds_to_exec),
|
||||||
prefix, yes_no(s->pass_sec),
|
prefix, yes_no(s->pass_sec),
|
||||||
prefix, yes_no(s->pass_pktinfo),
|
prefix, yes_no(s->pass_pktinfo),
|
||||||
prefix, strna(s->tcp_congestion),
|
prefix, strna(s->tcp_congestion),
|
||||||
@ -1921,6 +1923,26 @@ static int socket_spawn(Socket *s, ExecCommand *c, PidRef *ret_pid) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
/* Note that ExecStartPre= command doesn't inherit any FDs. It runs before we open listen FDs. */
|
||||||
|
if (s->pass_fds_to_exec) {
|
||||||
|
_cleanup_strv_free_ char **fd_names = NULL;
|
||||||
|
_cleanup_free_ int *fds = NULL;
|
||||||
|
int n_fds;
|
||||||
|
|
||||||
|
n_fds = socket_collect_fds(s, &fds);
|
||||||
|
if (n_fds < 0)
|
||||||
|
return n_fds;
|
||||||
|
|
||||||
|
r = strv_extend_n(&fd_names, socket_fdname(s), n_fds);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
exec_params.flags |= EXEC_PASS_FDS;
|
||||||
|
exec_params.fds = TAKE_PTR(fds);
|
||||||
|
exec_params.fd_names = TAKE_PTR(fd_names);
|
||||||
|
exec_params.n_socket_fds = n_fds;
|
||||||
|
}
|
||||||
|
|
||||||
r = exec_spawn(UNIT(s),
|
r = exec_spawn(UNIT(s),
|
||||||
c,
|
c,
|
||||||
&s->exec_context,
|
&s->exec_context,
|
||||||
|
@ -129,6 +129,7 @@ struct Socket {
|
|||||||
bool transparent;
|
bool transparent;
|
||||||
bool broadcast;
|
bool broadcast;
|
||||||
bool pass_cred;
|
bool pass_cred;
|
||||||
|
bool pass_fds_to_exec;
|
||||||
bool pass_sec;
|
bool pass_sec;
|
||||||
bool pass_pktinfo;
|
bool pass_pktinfo;
|
||||||
SocketTimestamping timestamping;
|
SocketTimestamping timestamping;
|
||||||
|
@ -2450,6 +2450,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
|
|||||||
"Transparent",
|
"Transparent",
|
||||||
"Broadcast",
|
"Broadcast",
|
||||||
"PassCredentials",
|
"PassCredentials",
|
||||||
|
"PassFileDescriptorsToExec",
|
||||||
"PassSecurity",
|
"PassSecurity",
|
||||||
"PassPacketInfo",
|
"PassPacketInfo",
|
||||||
"ReusePort",
|
"ReusePort",
|
||||||
|
@ -185,6 +185,7 @@ PAMName=
|
|||||||
PIDFile=
|
PIDFile=
|
||||||
PartOf=
|
PartOf=
|
||||||
PassCredentials=
|
PassCredentials=
|
||||||
|
PassFileDescriptorsToExec=
|
||||||
PassSecurity=
|
PassSecurity=
|
||||||
PassPacketInfo=
|
PassPacketInfo=
|
||||||
PathChanged=
|
PathChanged=
|
||||||
|
35
test/testsuite-07.units/pass-fds-to-exec-no.socket
Normal file
35
test/testsuite-07.units/pass-fds-to-exec-no.socket
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
[Unit]
|
||||||
|
Description=Test if ExecXYZ= commands don't inherit listen FDs when PassFileDescriptorsToExec= is unset
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
# With Accept= set we don't need a corresponding service unit
|
||||||
|
Accept=yes
|
||||||
|
FileDescriptorName=foo
|
||||||
|
ListenStream=127.0.0.1:1234
|
||||||
|
ListenStream=[::1]:1234
|
||||||
|
PassFileDescriptorsToExec=no
|
||||||
|
ExecStartPre=\
|
||||||
|
test ExecStartPre -a \
|
||||||
|
-z ${LISTEN_FDS} -a \
|
||||||
|
-z ${LISTEN_FDNAMES} -a \
|
||||||
|
! -e /dev/fd/3 -a \
|
||||||
|
! -e /dev/fd/4
|
||||||
|
ExecStartPost=\
|
||||||
|
test ExecStartPost -a \
|
||||||
|
-z ${LISTEN_FDS} -a \
|
||||||
|
-z ${LISTEN_FDNAMES} -a \
|
||||||
|
! -e /dev/fd/3 -a \
|
||||||
|
! -e /dev/fd/4
|
||||||
|
ExecStopPre=\
|
||||||
|
test ExecStopPre -a \
|
||||||
|
-z ${LISTEN_FDS} -a \
|
||||||
|
-z ${LISTEN_FDNAMES} -a \
|
||||||
|
! -e /dev/fd/3 -a \
|
||||||
|
! -e /dev/fd/4
|
||||||
|
ExecStopPost=\
|
||||||
|
test ExecStopPost -a \
|
||||||
|
-z ${LISTEN_FDS} -a \
|
||||||
|
-z ${LISTEN_FDNAMES} -a \
|
||||||
|
! -e /dev/fd/3 -a \
|
||||||
|
! -e /dev/fd/4
|
36
test/testsuite-07.units/pass-fds-to-exec-yes.socket
Normal file
36
test/testsuite-07.units/pass-fds-to-exec-yes.socket
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
[Unit]
|
||||||
|
Description=Test if ExecXYZ= commands inherit listen FDs when PassFileDescriptorsToExec= is set
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
# With Accept= set we don't need a corresponding service unit
|
||||||
|
Accept=yes
|
||||||
|
FileDescriptorName=foo
|
||||||
|
ListenStream=127.0.0.1:1234
|
||||||
|
ListenStream=[::1]:1234
|
||||||
|
PassFileDescriptorsToExec=yes
|
||||||
|
# ExecStartPre runs before we create sockets. Nothing to pass.
|
||||||
|
ExecStartPre=\
|
||||||
|
test ExecStartPre -a \
|
||||||
|
-z ${LISTEN_FDS} -a \
|
||||||
|
-z ${LISTEN_FDNAMES} -a \
|
||||||
|
! -e /dev/fd/3 -a \
|
||||||
|
! -e /dev/fd/4
|
||||||
|
ExecStartPost=\
|
||||||
|
test ExecStartPost -a \
|
||||||
|
${LISTEN_FDS} = 2 -a \
|
||||||
|
${LISTEN_FDNAMES} = foo:foo -a \
|
||||||
|
-S /dev/fd/3 -a \
|
||||||
|
-S /dev/fd/4
|
||||||
|
ExecStopPre=\
|
||||||
|
test "ExecStopPre" -a \
|
||||||
|
${LISTEN_FDS} = 2 -a \
|
||||||
|
${LISTEN_FDNAMES} = foo:foo -a \
|
||||||
|
-S /dev/fd/3 -a \
|
||||||
|
-S /dev/fd/4
|
||||||
|
ExecStopPost=\
|
||||||
|
test "ExecStopPost" -a \
|
||||||
|
${LISTEN_FDS} = 2 -a \
|
||||||
|
${LISTEN_FDNAMES} = foo:foo -a \
|
||||||
|
-S /dev/fd/3 -a \
|
||||||
|
-S /dev/fd/4
|
11
test/units/testsuite-07.socket-pass-fds.sh
Executable file
11
test/units/testsuite-07.socket-pass-fds.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# Test PassFileDescriptorsToExec= option in socket units
|
||||||
|
|
||||||
|
for u in pass-fds-to-exec-{no,yes}.socket; do
|
||||||
|
systemctl start "$u"
|
||||||
|
systemctl stop "$u"
|
||||||
|
done
|
Loading…
Reference in New Issue
Block a user