mirror of
https://github.com/systemd/systemd
synced 2026-04-23 07:24:51 +02:00
Compare commits
27 Commits
ad337e55a3
...
af5ee76c56
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af5ee76c56 | ||
|
|
23484e1205 | ||
|
|
2cdd6bef9c | ||
|
|
46801e7647 | ||
|
|
09f5fc66f2 | ||
|
|
20afd9a184 | ||
|
|
4f5160698e | ||
|
|
f60b0813ea | ||
|
|
4f5c24857b | ||
|
|
d29cc4d6e1 | ||
|
|
d3e85c9c81 | ||
|
|
066931818d | ||
|
|
f1c70ed13d | ||
|
|
c3e7fba07c | ||
|
|
1219bd4306 | ||
|
|
4355c04fef | ||
|
|
827f865063 | ||
|
|
29e6f70b8d | ||
|
|
f79856d9e8 | ||
|
|
8d3e0d607e | ||
|
|
d16da79ec0 | ||
|
|
1c2b617703 | ||
|
|
acbb4d7ec4 | ||
|
|
d9ea4a210b | ||
|
|
55c8f9ecb0 | ||
|
|
43b9b2053c | ||
|
|
598a1d7633 |
16
man/system-or-user-ns.xml
Normal file
16
man/system-or-user-ns.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
-->
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
|
||||||
|
<para id="singular">This option is only available for system services, or for services running in per-user
|
||||||
|
instances of the service manager when unprivileged user namespaces are available.</para>
|
||||||
|
|
||||||
|
<para id="plural">These options are only available for system services, or for services running in per-user
|
||||||
|
instances of the service manager when unprivileged user namespaces are available.</para>
|
||||||
|
|
||||||
|
</refsect1>
|
||||||
@ -143,7 +143,9 @@
|
|||||||
<title>Mounting logging sockets into root environment</title>
|
<title>Mounting logging sockets into root environment</title>
|
||||||
|
|
||||||
<programlisting>BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout</programlisting>
|
<programlisting>BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout</programlisting>
|
||||||
</example></listitem>
|
</example>
|
||||||
|
|
||||||
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -480,7 +482,9 @@
|
|||||||
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
|
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
|
||||||
|
|
||||||
<para>Note that usage from user units requires overlayfs support in unprivileged user namespaces,
|
<para>Note that usage from user units requires overlayfs support in unprivileged user namespaces,
|
||||||
which was first introduced in kernel v5.11.</para></listitem>
|
which was first introduced in kernel v5.11.</para>
|
||||||
|
|
||||||
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
@ -625,7 +629,7 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Capabilities</title>
|
<title>Capabilities</title>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="plural"/>
|
<xi:include href="system-or-user-ns.xml" xpointer="plural"/>
|
||||||
|
|
||||||
<variablelist class='unit-directives'>
|
<variablelist class='unit-directives'>
|
||||||
|
|
||||||
@ -1254,7 +1258,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
|||||||
<varname>DynamicUser=</varname> is set. This setting cannot ensure protection in all cases. In
|
<varname>DynamicUser=</varname> is set. This setting cannot ensure protection in all cases. In
|
||||||
general it has the same limitations as <varname>ReadOnlyPaths=</varname>, see below.</para>
|
general it has the same limitations as <varname>ReadOnlyPaths=</varname>, see below.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1508,7 +1512,7 @@ NoExecPaths=/
|
|||||||
ExecPaths=/usr/sbin/my_daemon /usr/lib /usr/lib64
|
ExecPaths=/usr/sbin/my_daemon /usr/lib /usr/lib64
|
||||||
</programlisting></para>
|
</programlisting></para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="plural"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="plural"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1533,7 +1537,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
then the invoked processes by the unit cannot see any files or directories under <filename>/var/</filename> except for
|
then the invoked processes by the unit cannot see any files or directories under <filename>/var/</filename> except for
|
||||||
<filename>/var/lib/systemd</filename> or its contents.</para>
|
<filename>/var/lib/systemd</filename> or its contents.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1561,7 +1565,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
available), and the unit should be written in a way that does not solely rely on this setting for
|
available), and the unit should be written in a way that does not solely rely on this setting for
|
||||||
security.</para>
|
security.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1595,7 +1599,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
namespaces are not available), and the unit should be written in a way that does not solely rely on
|
namespaces are not available), and the unit should be written in a way that does not solely rely on
|
||||||
this setting for security.</para>
|
this setting for security.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/>
|
||||||
|
|
||||||
<para>When access to some but not all devices must be possible, the <varname>DeviceAllow=</varname>
|
<para>When access to some but not all devices must be possible, the <varname>DeviceAllow=</varname>
|
||||||
setting might be used instead. See
|
setting might be used instead. See
|
||||||
@ -1629,7 +1633,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
<varname>JoinsNamespaceOf=</varname> to listen on sockets inside of network namespaces of other
|
<varname>JoinsNamespaceOf=</varname> to listen on sockets inside of network namespaces of other
|
||||||
services.</para>
|
services.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1648,7 +1652,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
<para>When this option is used on a socket unit any sockets bound on behalf of this unit will be
|
<para>When this option is used on a socket unit any sockets bound on behalf of this unit will be
|
||||||
bound within the specified network namespace.</para>
|
bound within the specified network namespace.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1679,7 +1683,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
not available), and the unit should be written in a way that does not solely rely on this setting for
|
not available), and the unit should be written in a way that does not solely rely on this setting for
|
||||||
security.</para>
|
security.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1695,7 +1699,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
<varname>IPCNamespacePath=</varname> configured, as otherwise the network namespace of those
|
<varname>IPCNamespacePath=</varname> configured, as otherwise the network namespace of those
|
||||||
units is reused.</para>
|
units is reused.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1749,7 +1753,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
capability (e.g. services for which <varname>User=</varname> is set),
|
capability (e.g. services for which <varname>User=</varname> is set),
|
||||||
<varname>NoNewPrivileges=yes</varname> is implied.</para>
|
<varname>NoNewPrivileges=yes</varname> is implied.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1766,7 +1770,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
doesn't have the <constant>CAP_SYS_ADMIN</constant> capability (e.g. services for which
|
doesn't have the <constant>CAP_SYS_ADMIN</constant> capability (e.g. services for which
|
||||||
<varname>User=</varname> is set), <varname>NoNewPrivileges=yes</varname> is implied.</para>
|
<varname>User=</varname> is set), <varname>NoNewPrivileges=yes</varname> is implied.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1790,7 +1794,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
inaccessible. If <varname>ProtectKernelTunables=</varname> is set,
|
inaccessible. If <varname>ProtectKernelTunables=</varname> is set,
|
||||||
<varname>MountAPIVFS=yes</varname> is implied.</para>
|
<varname>MountAPIVFS=yes</varname> is implied.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1811,7 +1815,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
but the unit doesn't have the <constant>CAP_SYS_ADMIN</constant> capability (e.g. services for
|
but the unit doesn't have the <constant>CAP_SYS_ADMIN</constant> capability (e.g. services for
|
||||||
which <varname>User=</varname> is set), <varname>NoNewPrivileges=yes</varname> is implied.</para>
|
which <varname>User=</varname> is set), <varname>NoNewPrivileges=yes</varname> is implied.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1830,7 +1834,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
|
|||||||
capability (e.g. services for which <varname>User=</varname> is set),
|
capability (e.g. services for which <varname>User=</varname> is set),
|
||||||
<varname>NoNewPrivileges=yes</varname> is implied.</para>
|
<varname>NoNewPrivileges=yes</varname> is implied.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -2134,7 +2138,7 @@ RestrictNamespaces=~cgroup net</programlisting>
|
|||||||
option. Hence it is primarily useful to explicitly request this behaviour if none of the other settings are
|
option. Hence it is primarily useful to explicitly request this behaviour if none of the other settings are
|
||||||
used.</para>
|
used.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -2164,7 +2168,7 @@ RestrictNamespaces=~cgroup net</programlisting>
|
|||||||
<para>Usually, it is best to leave this setting unmodified, and use higher level file system namespacing
|
<para>Usually, it is best to leave this setting unmodified, and use higher level file system namespacing
|
||||||
options instead, in particular <varname>PrivateMounts=</varname>, see above.</para>
|
options instead, in particular <varname>PrivateMounts=</varname>, see above.</para>
|
||||||
|
|
||||||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
<xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
@ -2714,8 +2718,8 @@ SystemCallErrorNumber=EPERM</programlisting>
|
|||||||
<varname>StandardInput=</varname>, see above. If <replaceable>path</replaceable> refers to a regular file
|
<varname>StandardInput=</varname>, see above. If <replaceable>path</replaceable> refers to a regular file
|
||||||
on the filesystem, it is opened (created if it doesn't exist yet) for writing at the beginning of the file,
|
on the filesystem, it is opened (created if it doesn't exist yet) for writing at the beginning of the file,
|
||||||
but without truncating it.
|
but without truncating it.
|
||||||
If standard input and output are directed to the same file path, it is opened only once, for reading as well
|
If standard input and output are directed to the same file path, it is opened only once — for reading as well
|
||||||
as writing and duplicated. This is particularly useful when the specified path refers to an
|
as writing — and duplicated. This is particularly useful when the specified path refers to an
|
||||||
<constant>AF_UNIX</constant> socket in the file system, as in that case only a
|
<constant>AF_UNIX</constant> socket in the file system, as in that case only a
|
||||||
single stream connection is created for both input and output.</para>
|
single stream connection is created for both input and output.</para>
|
||||||
|
|
||||||
@ -2741,16 +2745,17 @@ SystemCallErrorNumber=EPERM</programlisting>
|
|||||||
<para><option>socket</option> connects standard output to a socket acquired via socket activation. The
|
<para><option>socket</option> connects standard output to a socket acquired via socket activation. The
|
||||||
semantics are similar to the same option of <varname>StandardInput=</varname>, see above.</para>
|
semantics are similar to the same option of <varname>StandardInput=</varname>, see above.</para>
|
||||||
|
|
||||||
<para>The <option>fd:<replaceable>name</replaceable></option> option connects standard output to a specific,
|
<para>The <option>fd:<replaceable>name</replaceable></option> option connects standard output to a
|
||||||
named file descriptor provided by a socket unit. A name may be specified as part of this option, following a
|
specific, named file descriptor provided by a socket unit. A name may be specified as part of this
|
||||||
<literal>:</literal> character (e.g. <literal>fd:foobar</literal>). If no name is specified, the name
|
option, following a <literal>:</literal> character
|
||||||
|
(e.g. <literal>fd:<replaceable>foobar</replaceable></literal>). If no name is specified, the name
|
||||||
<literal>stdout</literal> is implied (i.e. <literal>fd</literal> is equivalent to
|
<literal>stdout</literal> is implied (i.e. <literal>fd</literal> is equivalent to
|
||||||
<literal>fd:stdout</literal>). At least one socket unit defining the specified name must be provided via the
|
<literal>fd:stdout</literal>). At least one socket unit defining the specified name must be provided
|
||||||
<varname>Sockets=</varname> option, and the file descriptor name may differ from the name of its containing
|
via the <varname>Sockets=</varname> option, and the file descriptor name may differ from the name of
|
||||||
socket unit. If multiple matches are found, the first one will be used. See
|
its containing socket unit. If multiple matches are found, the first one will be used. See
|
||||||
<varname>FileDescriptorName=</varname> in
|
<varname>FileDescriptorName=</varname> in
|
||||||
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
|
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
details about named descriptors and their ordering.</para>
|
for more details about named descriptors and their ordering.</para>
|
||||||
|
|
||||||
<para>If the standard output (or error output, see below) of a unit is connected to the journal or
|
<para>If the standard output (or error output, see below) of a unit is connected to the journal or
|
||||||
the kernel log buffer, the unit will implicitly gain a dependency of type <varname>After=</varname>
|
the kernel log buffer, the unit will implicitly gain a dependency of type <varname>After=</varname>
|
||||||
|
|||||||
@ -1975,6 +1975,11 @@
|
|||||||
<entry>Cache directory root</entry>
|
<entry>Cache directory root</entry>
|
||||||
<entry>This is either <filename>/var/cache</filename> (for the system manager) or the path <literal>$XDG_CACHE_HOME</literal> resolves to (for user managers).</entry>
|
<entry>This is either <filename>/var/cache</filename> (for the system manager) or the path <literal>$XDG_CACHE_HOME</literal> resolves to (for user managers).</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><literal>%d</literal></entry>
|
||||||
|
<entry>Credentials directory</entry>
|
||||||
|
<entry>This is the value of the <literal>$CREDENTIALS_DIRECTORY</literal> environment variable if available. See section "Credentials" in <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
|
||||||
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>%E</literal></entry>
|
<entry><literal>%E</literal></entry>
|
||||||
<entry>Configuration directory root</entry>
|
<entry>Configuration directory root</entry>
|
||||||
|
|||||||
@ -32,7 +32,7 @@ _bootctl() {
|
|||||||
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
|
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||||
local -A OPTS=(
|
local -A OPTS=(
|
||||||
[STANDALONE]='-h --help -p --print-esp-path -x --print-boot-path --version --no-variables --no-pager --graceful'
|
[STANDALONE]='-h --help -p --print-esp-path -x --print-boot-path --version --no-variables --no-pager --graceful'
|
||||||
[ARG]='--esp-path --boot-path'
|
[ARG]='--esp-path --boot-path --make-machine-id-directory'
|
||||||
)
|
)
|
||||||
|
|
||||||
if __contains_word "$prev" ${OPTS[ARG]}; then
|
if __contains_word "$prev" ${OPTS[ARG]}; then
|
||||||
@ -45,6 +45,9 @@ _bootctl() {
|
|||||||
fi
|
fi
|
||||||
compopt -o filenames
|
compopt -o filenames
|
||||||
;;
|
;;
|
||||||
|
--make-machine-id-directory)
|
||||||
|
comps="yes no auto"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@ -69,6 +69,7 @@ _arguments \
|
|||||||
'--boot-path=[Path to the $BOOT partition]:path:_directories' \
|
'--boot-path=[Path to the $BOOT partition]:path:_directories' \
|
||||||
{-p,--print-esp-path}'[Print path to the EFI system partition]' \
|
{-p,--print-esp-path}'[Print path to the EFI system partition]' \
|
||||||
{-x,--print-boot-path}'[Print path to the $BOOT partition]' \
|
{-x,--print-boot-path}'[Print path to the $BOOT partition]' \
|
||||||
|
'--make-machine-id-directory=[Control creation and deletion of the top-level machine ID directory.]:options:(yes no auto)' \
|
||||||
'--no-variables[Do not touch EFI variables]' \
|
'--no-variables[Do not touch EFI variables]' \
|
||||||
'--no-pager[Do not pipe output into a pager]' \
|
'--no-pager[Do not pipe output into a pager]' \
|
||||||
'--graceful[Do not fail when locating ESP or writing fails]' \
|
'--graceful[Do not fail when locating ESP or writing fails]' \
|
||||||
|
|||||||
@ -23,7 +23,6 @@ static int parse_env_file_internal(
|
|||||||
size_t n_key = 0, n_value = 0, last_value_whitespace = SIZE_MAX, last_key_whitespace = SIZE_MAX;
|
size_t n_key = 0, n_value = 0, last_value_whitespace = SIZE_MAX, last_key_whitespace = SIZE_MAX;
|
||||||
_cleanup_free_ char *contents = NULL, *key = NULL, *value = NULL;
|
_cleanup_free_ char *contents = NULL, *key = NULL, *value = NULL;
|
||||||
unsigned line = 1;
|
unsigned line = 1;
|
||||||
char *p;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -46,7 +45,7 @@ static int parse_env_file_internal(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
for (p = contents; *p; p++) {
|
for (char *p = contents; *p; p++) {
|
||||||
char c = *p;
|
char c = *p;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|||||||
@ -16,8 +16,8 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
|
|||||||
|
|
||||||
#define typesafe_bsearch_r(k, b, n, func, userdata) \
|
#define typesafe_bsearch_r(k, b, n, func, userdata) \
|
||||||
({ \
|
({ \
|
||||||
const typeof(b[0]) *_k = k; \
|
const typeof((b)[0]) *_k = k; \
|
||||||
int (*_func_)(const typeof(b[0])*, const typeof(b[0])*, typeof(userdata)) = func; \
|
int (*_func_)(const typeof((b)[0])*, const typeof((b)[0])*, typeof(userdata)) = func; \
|
||||||
xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (comparison_userdata_fn_t) _func_, userdata); \
|
xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (comparison_userdata_fn_t) _func_, userdata); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -36,8 +36,8 @@ static inline void* bsearch_safe(const void *key, const void *base,
|
|||||||
|
|
||||||
#define typesafe_bsearch(k, b, n, func) \
|
#define typesafe_bsearch(k, b, n, func) \
|
||||||
({ \
|
({ \
|
||||||
const typeof(b[0]) *_k = k; \
|
const typeof((b)[0]) *_k = k; \
|
||||||
int (*_func_)(const typeof(b[0])*, const typeof(b[0])*) = func; \
|
int (*_func_)(const typeof((b)[0])*, const typeof((b)[0])*) = func; \
|
||||||
bsearch_safe((const void*) _k, (b), (n), sizeof((b)[0]), (comparison_fn_t) _func_); \
|
bsearch_safe((const void*) _k, (b), (n), sizeof((b)[0]), (comparison_fn_t) _func_); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ static inline void _qsort_safe(void *base, size_t nmemb, size_t size, comparison
|
|||||||
* is the prototype for the comparison function */
|
* is the prototype for the comparison function */
|
||||||
#define typesafe_qsort(p, n, func) \
|
#define typesafe_qsort(p, n, func) \
|
||||||
({ \
|
({ \
|
||||||
int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func; \
|
int (*_func_)(const typeof((p)[0])*, const typeof((p)[0])*) = func; \
|
||||||
_qsort_safe((p), (n), sizeof((p)[0]), (comparison_fn_t) _func_); \
|
_qsort_safe((p), (n), sizeof((p)[0]), (comparison_fn_t) _func_); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, compariso
|
|||||||
|
|
||||||
#define typesafe_qsort_r(p, n, func, userdata) \
|
#define typesafe_qsort_r(p, n, func, userdata) \
|
||||||
({ \
|
({ \
|
||||||
int (*_func_)(const typeof(p[0])*, const typeof(p[0])*, typeof(userdata)) = func; \
|
int (*_func_)(const typeof((p)[0])*, const typeof((p)[0])*, typeof(userdata)) = func; \
|
||||||
qsort_r_safe((p), (n), sizeof((p)[0]), (comparison_userdata_fn_t) _func_, userdata); \
|
qsort_r_safe((p), (n), sizeof((p)[0]), (comparison_userdata_fn_t) _func_, userdata); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -610,7 +610,7 @@ bool strv_is_uniq(char * const *l) {
|
|||||||
char * const *i;
|
char * const *i;
|
||||||
|
|
||||||
STRV_FOREACH(i, l)
|
STRV_FOREACH(i, l)
|
||||||
if (strv_find(i+1, *i))
|
if (strv_contains(i+1, *i))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -899,10 +899,10 @@ static int install_binaries(const char *esp_path, bool force) {
|
|||||||
|
|
||||||
/* skip the .efi file, if there's a .signed version of it */
|
/* skip the .efi file, if there's a .signed version of it */
|
||||||
if (endswith_no_case(de->d_name, ".efi")) {
|
if (endswith_no_case(de->d_name, ".efi")) {
|
||||||
_cleanup_free_ const char *s = strjoin(BOOTLIBDIR, "/", de->d_name, ".signed");
|
_cleanup_free_ const char *s = strjoin(de->d_name, ".signed");
|
||||||
if (!s)
|
if (!s)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
if (access(s, F_OK) >= 0)
|
if (faccessat(dirfd(d), s, F_OK, 0) >= 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1932,6 +1932,8 @@ static int verb_install(int argc, char *argv[], void *userdata) {
|
|||||||
bool install, graceful;
|
bool install, graceful;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
/* Invoked for both "update" and "install" */
|
||||||
|
|
||||||
install = streq(argv[0], "install");
|
install = streq(argv[0], "install");
|
||||||
graceful = !install && arg_graceful; /* support graceful mode for updates */
|
graceful = !install && arg_graceful; /* support graceful mode for updates */
|
||||||
|
|
||||||
@ -2044,7 +2046,7 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
|
|||||||
|
|
||||||
q = remove_entry_directory(arg_esp_path);
|
q = remove_entry_directory(arg_esp_path);
|
||||||
if (q < 0 && r >= 0)
|
if (q < 0 && r >= 0)
|
||||||
r = 1;
|
r = q;
|
||||||
|
|
||||||
if (arg_xbootldr_path) {
|
if (arg_xbootldr_path) {
|
||||||
/* Remove the latter two also in the XBOOTLDR partition if it exists */
|
/* Remove the latter two also in the XBOOTLDR partition if it exists */
|
||||||
|
|||||||
@ -3415,6 +3415,9 @@ static bool insist_on_sandboxing(
|
|||||||
if (context->dynamic_user)
|
if (context->dynamic_user)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (context->n_extension_images > 0 || !strv_isempty(context->extension_directories))
|
||||||
|
return true;
|
||||||
|
|
||||||
/* If there are any bind mounts set that don't map back onto themselves, fs namespacing becomes
|
/* If there are any bind mounts set that don't map back onto themselves, fs namespacing becomes
|
||||||
* essential. */
|
* essential. */
|
||||||
for (size_t i = 0; i < n_bind_mounts; i++)
|
for (size_t i = 0; i < n_bind_mounts; i++)
|
||||||
|
|||||||
@ -4251,7 +4251,7 @@ static void service_notify_message(
|
|||||||
/* Process FD store messages. Either FDSTOREREMOVE=1 for removal, or FDSTORE=1 for addition. In both cases,
|
/* Process FD store messages. Either FDSTOREREMOVE=1 for removal, or FDSTORE=1 for addition. In both cases,
|
||||||
* process FDNAME= for picking the file descriptor name to use. Note that FDNAME= is required when removing
|
* process FDNAME= for picking the file descriptor name to use. Note that FDNAME= is required when removing
|
||||||
* fds, but optional when pushing in new fds, for compatibility reasons. */
|
* fds, but optional when pushing in new fds, for compatibility reasons. */
|
||||||
if (strv_find(tags, "FDSTOREREMOVE=1")) {
|
if (strv_contains(tags, "FDSTOREREMOVE=1")) {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
name = strv_find_startswith(tags, "FDNAME=");
|
name = strv_find_startswith(tags, "FDNAME=");
|
||||||
@ -4260,7 +4260,7 @@ static void service_notify_message(
|
|||||||
else
|
else
|
||||||
service_remove_fd_store(s, name);
|
service_remove_fd_store(s, name);
|
||||||
|
|
||||||
} else if (strv_find(tags, "FDSTORE=1")) {
|
} else if (strv_contains(tags, "FDSTORE=1")) {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
name = strv_find_startswith(tags, "FDNAME=");
|
name = strv_find_startswith(tags, "FDNAME=");
|
||||||
|
|||||||
@ -138,7 +138,7 @@ static int specifier_cgroup_slice(char specifier, const void *data, const char *
|
|||||||
|
|
||||||
static int specifier_special_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
static int specifier_special_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = ASSERT_PTR(userdata);
|
const Unit *u = ASSERT_PTR(userdata);
|
||||||
char *n = NULL;
|
char *n;
|
||||||
|
|
||||||
n = strdup(u->manager->prefix[PTR_TO_UINT(data)]);
|
n = strdup(u->manager->prefix[PTR_TO_UINT(data)]);
|
||||||
if (!n)
|
if (!n)
|
||||||
@ -148,6 +148,20 @@ static int specifier_special_directory(char specifier, const void *data, const c
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int specifier_credentials_dir(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
|
const Unit *u = ASSERT_PTR(userdata);
|
||||||
|
char *d;
|
||||||
|
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
d = strjoin(u->manager->prefix[EXEC_DIRECTORY_RUNTIME], "/credentials/", u->id);
|
||||||
|
if (!d)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
*ret = d;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int unit_name_printf(const Unit *u, const char* format, char **ret) {
|
int unit_name_printf(const Unit *u, const char* format, char **ret) {
|
||||||
/*
|
/*
|
||||||
* This will use the passed string as format string and replace the following specifiers (which should all be
|
* This will use the passed string as format string and replace the following specifiers (which should all be
|
||||||
@ -191,6 +205,7 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length,
|
|||||||
* %R: the root of this systemd's instance tree (deprecated)
|
* %R: the root of this systemd's instance tree (deprecated)
|
||||||
*
|
*
|
||||||
* %C: the cache directory root (e.g. /var/cache or $XDG_CACHE_HOME)
|
* %C: the cache directory root (e.g. /var/cache or $XDG_CACHE_HOME)
|
||||||
|
* %d: the credentials directory ($CREDENTIALS_DIRECTORY)
|
||||||
* %E: the configuration directory root (e.g. /etc or $XDG_CONFIG_HOME)
|
* %E: the configuration directory root (e.g. /etc or $XDG_CONFIG_HOME)
|
||||||
* %L: the log directory root (e.g. /var/log or $XDG_CONFIG_HOME/log)
|
* %L: the log directory root (e.g. /var/log or $XDG_CONFIG_HOME/log)
|
||||||
* %S: the state directory root (e.g. /var/lib or $XDG_CONFIG_HOME)
|
* %S: the state directory root (e.g. /var/lib or $XDG_CONFIG_HOME)
|
||||||
@ -227,6 +242,7 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length,
|
|||||||
{ 'R', specifier_cgroup_root, NULL },
|
{ 'R', specifier_cgroup_root, NULL },
|
||||||
|
|
||||||
{ 'C', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_CACHE) },
|
{ 'C', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_CACHE) },
|
||||||
|
{ 'd', specifier_credentials_dir, NULL },
|
||||||
{ 'E', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_CONFIGURATION) },
|
{ 'E', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_CONFIGURATION) },
|
||||||
{ 'L', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_LOGS) },
|
{ 'L', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_LOGS) },
|
||||||
{ 'S', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_STATE) },
|
{ 'S', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_STATE) },
|
||||||
|
|||||||
@ -114,7 +114,7 @@ int identity_add_token_pin(JsonVariant **v, const char *pin) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to convert PIN array: %m");
|
return log_error_errno(r, "Failed to convert PIN array: %m");
|
||||||
|
|
||||||
if (strv_find(pins, pin))
|
if (strv_contains(pins, pin))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = strv_extend(&pins, pin);
|
r = strv_extend(&pins, pin);
|
||||||
|
|||||||
@ -85,6 +85,7 @@ else
|
|||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# These two settings are settable in install.conf
|
||||||
layout=
|
layout=
|
||||||
initrd_generator=
|
initrd_generator=
|
||||||
|
|
||||||
@ -183,7 +184,6 @@ export KERNEL_INSTALL_STAGING_AREA
|
|||||||
[ "$layout" = "bls" ]
|
[ "$layout" = "bls" ]
|
||||||
MAKE_ENTRY_DIR_ABS=$?
|
MAKE_ENTRY_DIR_ABS=$?
|
||||||
|
|
||||||
|
|
||||||
ret=0
|
ret=0
|
||||||
|
|
||||||
PLUGINS="$(
|
PLUGINS="$(
|
||||||
|
|||||||
@ -249,18 +249,15 @@ static int device_compare(sd_device * const *_a, sd_device * const *_b) {
|
|||||||
|
|
||||||
prefix_len = sound_a - devpath_a;
|
prefix_len = sound_a - devpath_a;
|
||||||
|
|
||||||
if (strncmp(devpath_a, devpath_b, prefix_len) == 0) {
|
if (strneq(devpath_a, devpath_b, prefix_len)) {
|
||||||
const char *sound_b;
|
const char *sound_b;
|
||||||
|
|
||||||
sound_b = devpath_b + prefix_len;
|
sound_b = devpath_b + prefix_len;
|
||||||
|
|
||||||
if (startswith(sound_a, "/controlC") &&
|
r = CMP(!!startswith(sound_a, "/controlC"),
|
||||||
!startswith(sound_b, "/contolC"))
|
!!startswith(sound_b, "/controlC"));
|
||||||
return 1;
|
if (r != 0)
|
||||||
|
return r;
|
||||||
if (!startswith(sound_a, "/controlC") &&
|
|
||||||
startswith(sound_b, "/controlC"))
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1029,18 +1029,9 @@ int device_update_db(sd_device *device) {
|
|||||||
* set 'sticky' bit to indicate that we should not clean the
|
* set 'sticky' bit to indicate that we should not clean the
|
||||||
* database when we transition from initramfs to the real root
|
* database when we transition from initramfs to the real root
|
||||||
*/
|
*/
|
||||||
if (device->db_persist) {
|
if (fchmod(fileno(f), device->db_persist ? 01644 : 0644) < 0) {
|
||||||
r = fchmod(fileno(f), 01644);
|
r = -errno;
|
||||||
if (r < 0) {
|
goto fail;
|
||||||
r = -errno;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r = fchmod(fileno(f), 0644);
|
|
||||||
if (r < 0) {
|
|
||||||
r = -errno;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_info) {
|
if (has_info) {
|
||||||
@ -1077,8 +1068,7 @@ int device_update_db(sd_device *device) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
r = rename(path_tmp, path);
|
if (rename(path_tmp, path) < 0) {
|
||||||
if (r < 0) {
|
|
||||||
r = -errno;
|
r = -errno;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4239,7 +4239,7 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r
|
|||||||
if (!tags)
|
if (!tags)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
if (strv_find(tags, "READY=1")) {
|
if (strv_contains(tags, "READY=1")) {
|
||||||
r = sd_notify(false, "READY=1\n");
|
r = sd_notify(false, "READY=1\n");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to send readiness notification, ignoring: %m");
|
log_warning_errno(r, "Failed to send readiness notification, ignoring: %m");
|
||||||
|
|||||||
@ -355,7 +355,7 @@ int bus_message_print_all_properties(
|
|||||||
if (!name_with_equal)
|
if (!name_with_equal)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
if (!filter || strv_find(filter, name) ||
|
if (!filter || strv_contains(filter, name) ||
|
||||||
(expected_value = strv_find_startswith(filter, name_with_equal))) {
|
(expected_value = strv_find_startswith(filter, name_with_equal))) {
|
||||||
r = sd_bus_message_peek_type(m, NULL, &contents);
|
r = sd_bus_message_peek_type(m, NULL, &contents);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|||||||
@ -97,7 +97,7 @@ static int specifier_last_component(char specifier, const void *data, const char
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, const char *root, char **ret) {
|
int install_name_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret) {
|
||||||
/* This is similar to unit_name_printf() */
|
/* This is similar to unit_name_printf() */
|
||||||
|
|
||||||
const Specifier table[] = {
|
const Specifier table[] = {
|
||||||
@ -117,5 +117,5 @@ int install_full_printf_internal(const UnitFileInstallInfo *i, const char *forma
|
|||||||
assert(format);
|
assert(format);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
return specifier_printf(format, max_length, table, root, i, ret);
|
return specifier_printf(format, UNIT_NAME_MAX, table, root, i, ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,11 +4,4 @@
|
|||||||
#include "install.h"
|
#include "install.h"
|
||||||
#include "unit-name.h"
|
#include "unit-name.h"
|
||||||
|
|
||||||
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, const char *root, char **ret);
|
int install_name_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret);
|
||||||
|
|
||||||
static inline int install_name_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret) {
|
|
||||||
return install_full_printf_internal(i, format, UNIT_NAME_MAX, root, ret);
|
|
||||||
}
|
|
||||||
static inline int install_path_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret) {
|
|
||||||
return install_full_printf_internal(i, format, PATH_MAX-1, root, ret);
|
|
||||||
}
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,7 @@ static int normalize_filenames(char **names) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int normalize_names(char **names, bool warn_if_path) {
|
static int normalize_names(char **names) {
|
||||||
char **u;
|
char **u;
|
||||||
bool was_path = false;
|
bool was_path = false;
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ static int normalize_names(char **names, bool warn_if_path) {
|
|||||||
was_path = true;
|
was_path = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (warn_if_path && was_path)
|
if (was_path)
|
||||||
log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
|
log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -92,7 +92,7 @@ int verb_enable(int argc, char *argv[], void *userdata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (streq(verb, "disable")) {
|
if (streq(verb, "disable")) {
|
||||||
r = normalize_names(names, true);
|
r = normalize_names(names);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -117,9 +117,9 @@ int verb_enable(int argc, char *argv[], void *userdata) {
|
|||||||
carries_install_info = r;
|
carries_install_info = r;
|
||||||
} else if (streq(verb, "link"))
|
} else if (streq(verb, "link"))
|
||||||
r = unit_file_link(arg_scope, flags, arg_root, names, &changes, &n_changes);
|
r = unit_file_link(arg_scope, flags, arg_root, names, &changes, &n_changes);
|
||||||
else if (streq(verb, "preset")) {
|
else if (streq(verb, "preset"))
|
||||||
r = unit_file_preset(arg_scope, flags, arg_root, names, arg_preset_mode, &changes, &n_changes);
|
r = unit_file_preset(arg_scope, flags, arg_root, names, arg_preset_mode, &changes, &n_changes);
|
||||||
} else if (streq(verb, "mask"))
|
else if (streq(verb, "mask"))
|
||||||
r = unit_file_mask(arg_scope, flags, arg_root, names, &changes, &n_changes);
|
r = unit_file_mask(arg_scope, flags, arg_root, names, &changes, &n_changes);
|
||||||
else if (streq(verb, "unmask"))
|
else if (streq(verb, "unmask"))
|
||||||
r = unit_file_unmask(arg_scope, flags, arg_root, names, &changes, &n_changes);
|
r = unit_file_unmask(arg_scope, flags, arg_root, names, &changes, &n_changes);
|
||||||
|
|||||||
@ -38,12 +38,12 @@ static bool output_show_unit_file(const UnitFileList *u, char **states, char **p
|
|||||||
if (!dot)
|
if (!dot)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!strv_find(arg_types, dot+1))
|
if (!strv_contains(arg_types, dot+1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strv_isempty(states) &&
|
if (!strv_isempty(states) &&
|
||||||
!strv_find(states, unit_file_state_to_string(u->state)))
|
!strv_contains(states, unit_file_state_to_string(u->state)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -783,7 +783,7 @@ bool output_show_unit(const UnitInfo *u, char **patterns) {
|
|||||||
if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
|
if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (arg_types && !strv_find(arg_types, unit_type_suffix(u->id)))
|
if (arg_types && !strv_contains(arg_types, unit_type_suffix(u->id)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (arg_all)
|
if (arg_all)
|
||||||
@ -873,18 +873,15 @@ int mangle_names(const char *operation, char **original_names, char ***ret_mangl
|
|||||||
|
|
||||||
/* When enabling units qualified path names are OK, too, hence allow them explicitly. */
|
/* When enabling units qualified path names are OK, too, hence allow them explicitly. */
|
||||||
|
|
||||||
if (is_path(*name)) {
|
if (is_path(*name))
|
||||||
*i = strdup(*name);
|
r = path_make_absolute_cwd(*name, i);
|
||||||
if (!*i)
|
else
|
||||||
return log_oom();
|
|
||||||
} else {
|
|
||||||
r = unit_name_mangle_with_suffix(*name, operation,
|
r = unit_name_mangle_with_suffix(*name, operation,
|
||||||
arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN,
|
arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN,
|
||||||
".service", i);
|
".service", i);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
*i = NULL;
|
*i = NULL;
|
||||||
return log_error_errno(r, "Failed to mangle unit name: %m");
|
return log_error_errno(r, "Failed to mangle unit name or path '%s': %m", *name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|||||||
@ -319,7 +319,7 @@ static int putgrent_with_members(const struct group *gr, FILE *group) {
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
STRV_FOREACH(i, a) {
|
STRV_FOREACH(i, a) {
|
||||||
if (strv_find(l, *i))
|
if (strv_contains(l, *i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strv_extend(&l, *i) < 0)
|
if (strv_extend(&l, *i) < 0)
|
||||||
@ -364,7 +364,7 @@ static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) {
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
STRV_FOREACH(i, a) {
|
STRV_FOREACH(i, a) {
|
||||||
if (strv_find(l, *i))
|
if (strv_contains(l, *i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strv_extend(&l, *i) < 0)
|
if (strv_extend(&l, *i) < 0)
|
||||||
|
|||||||
@ -1086,6 +1086,7 @@ static void test_exec_specifier(Manager *m) {
|
|||||||
test(m, "exec-specifier.service", 0, CLD_EXITED);
|
test(m, "exec-specifier.service", 0, CLD_EXITED);
|
||||||
test(m, "exec-specifier@foo-bar.service", 0, CLD_EXITED);
|
test(m, "exec-specifier@foo-bar.service", 0, CLD_EXITED);
|
||||||
test(m, "exec-specifier-interpolation.service", 0, CLD_EXITED);
|
test(m, "exec-specifier-interpolation.service", 0, CLD_EXITED);
|
||||||
|
test(m, "exec-specifier-credentials-dir.service", 0, CLD_EXITED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_exec_standardinput(Manager *m) {
|
static void test_exec_standardinput(Manager *m) {
|
||||||
|
|||||||
12
test/test-execute/exec-specifier-credentials-dir.service
Normal file
12
test/test-execute/exec-specifier-credentials-dir.service
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
[Unit]
|
||||||
|
Description=Test for specifiers
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
Environment=TOP_SECRET=%d/very_top_secret
|
||||||
|
# Test if the specifier is resolved correctly both before and after LoadCredential=
|
||||||
|
ExecStart=test %d/very_top_secret = "${CREDENTIALS_DIRECTORY}/very_top_secret"
|
||||||
|
LoadCredential=very_top_secret
|
||||||
|
ExecStart=test %d/very_top_secret = "${CREDENTIALS_DIRECTORY}/very_top_secret"
|
||||||
|
ExecStart=sh -c 'test %d/very_top_secret = "$TOP_SECRET"'
|
||||||
@ -20,6 +20,7 @@ ExecStart=test %L = /var/log
|
|||||||
ExecStart=test %E = /etc
|
ExecStart=test %E = /etc
|
||||||
ExecStart=test %T = /tmp
|
ExecStart=test %T = /tmp
|
||||||
ExecStart=test %V = /var/tmp
|
ExecStart=test %V = /var/tmp
|
||||||
|
ExecStart=test %d = %t/credentials/%n
|
||||||
ExecStart=sh -c 'test %u = $$(id -un)'
|
ExecStart=sh -c 'test %u = $$(id -un)'
|
||||||
ExecStart=sh -c 'test %U = $$(id -u)'
|
ExecStart=sh -c 'test %U = $$(id -u)'
|
||||||
ExecStart=sh -c 'test %g = $$(id -gn)'
|
ExecStart=sh -c 'test %g = $$(id -gn)'
|
||||||
|
|||||||
@ -74,6 +74,53 @@ runas testuser systemd-run --wait --user --unit=test-bind-mount \
|
|||||||
-p PrivateUsers=yes -p BindPaths=/dev/null:/etc/os-release \
|
-p PrivateUsers=yes -p BindPaths=/dev/null:/etc/os-release \
|
||||||
test ! -s /etc/os-release
|
test ! -s /etc/os-release
|
||||||
|
|
||||||
|
runas testuser systemd-run --wait --user --unit=test-read-write \
|
||||||
|
-p PrivateUsers=yes -p ReadOnlyPaths=/ \
|
||||||
|
-p ReadWritePaths="/var /run /tmp" \
|
||||||
|
-p NoExecPaths=/ -p ExecPaths=/usr \
|
||||||
|
test ! -w /etc/os-release
|
||||||
|
|
||||||
|
runas testuser systemd-run --wait --user --unit=test-caps \
|
||||||
|
-p PrivateUsers=yes -p AmbientCapabilities=CAP_SYS_ADMIN \
|
||||||
|
-p CapabilityBoundingSet=CAP_SYS_ADMIN \
|
||||||
|
test -s /etc/os-release
|
||||||
|
|
||||||
|
runas testuser systemd-run --wait --user --unit=test-devices \
|
||||||
|
-p PrivateUsers=yes -p PrivateDevices=yes -p PrivateIPC=yes \
|
||||||
|
sh -c "ls -1 /dev/ | wc -l | grep -q -F 18"
|
||||||
|
|
||||||
|
# Same check as test/test-execute/exec-privatenetwork-yes.service
|
||||||
|
runas testuser systemd-run --wait --user --unit=test-network \
|
||||||
|
-p PrivateUsers=yes -p PrivateNetwork=yes \
|
||||||
|
/bin/sh -x -c '! ip link | grep -E "^[0-9]+: " | grep -Ev ": (lo|(erspan|gre|gretap|ip_vti|ip6_vti|ip6gre|ip6tnl|sit|tunl)0@.*):"'
|
||||||
|
|
||||||
|
runas testuser systemd-run --wait --user --unit=test-hostname \
|
||||||
|
-p PrivateUsers=yes -p ProtectHostname=yes \
|
||||||
|
hostnamectl hostname foo \
|
||||||
|
&& { echo 'unexpected success'; exit 1; }
|
||||||
|
|
||||||
|
runas testuser systemd-run --wait --user --unit=test-clock \
|
||||||
|
-p PrivateUsers=yes -p ProtectClock=yes \
|
||||||
|
timedatectl set-time "2012-10-30 18:17:16" \
|
||||||
|
&& { echo 'unexpected success'; exit 1; }
|
||||||
|
|
||||||
|
runas testuser systemd-run --wait --user --unit=test-kernel-tunable \
|
||||||
|
-p PrivateUsers=yes -p ProtectKernelTunables=yes \
|
||||||
|
sh -c "echo 0 > /proc/sys/user/max_user_namespaces" \
|
||||||
|
&& { echo 'unexpected success'; exit 1; }
|
||||||
|
|
||||||
|
runas testuser systemd-run --wait --user --unit=test-kernel-mod \
|
||||||
|
-p PrivateUsers=yes -p ProtectKernelModules=yes \
|
||||||
|
sh -c "modprobe -r overlay && modprobe overlay" \
|
||||||
|
&& { echo 'unexpected success'; exit 1; }
|
||||||
|
|
||||||
|
if sysctl kernel.dmesg_restrict=0; then
|
||||||
|
runas testuser systemd-run --wait --user --unit=test-kernel-log \
|
||||||
|
-p PrivateUsers=yes -p ProtectKernelLogs=yes -p LogNamespace=yes \
|
||||||
|
dmesg \
|
||||||
|
&& { echo 'unexpected success'; exit 1; }
|
||||||
|
fi
|
||||||
|
|
||||||
unsquashfs -no-xattrs -d /tmp/img /usr/share/minimal_0.raw
|
unsquashfs -no-xattrs -d /tmp/img /usr/share/minimal_0.raw
|
||||||
runas testuser systemd-run --wait --user --unit=test-root-dir \
|
runas testuser systemd-run --wait --user --unit=test-root-dir \
|
||||||
-p PrivateUsers=yes -p RootDirectory=/tmp/img \
|
-p PrivateUsers=yes -p RootDirectory=/tmp/img \
|
||||||
@ -82,8 +129,9 @@ runas testuser systemd-run --wait --user --unit=test-root-dir \
|
|||||||
mkdir /tmp/img_bind
|
mkdir /tmp/img_bind
|
||||||
mount --bind /tmp/img /tmp/img_bind
|
mount --bind /tmp/img /tmp/img_bind
|
||||||
runas testuser systemd-run --wait --user --unit=test-root-dir-bind \
|
runas testuser systemd-run --wait --user --unit=test-root-dir-bind \
|
||||||
-p PrivateUsers=yes -p RootDirectory=/tmp/img_bind \
|
-p PrivateUsers=yes -p RootDirectory=/tmp/img_bind -p MountFlags=private \
|
||||||
grep MARKER=1 /etc/os-release
|
grep MARKER=1 /etc/os-release
|
||||||
|
umount /tmp/img_bind
|
||||||
|
|
||||||
# Unprivileged overlayfs was added to Linux 5.11, so try to detect it first
|
# Unprivileged overlayfs was added to Linux 5.11, so try to detect it first
|
||||||
mkdir -p /tmp/a /tmp/b /tmp/c
|
mkdir -p /tmp/a /tmp/b /tmp/c
|
||||||
@ -96,8 +144,6 @@ if unshare --mount --user --map-root-user mount -t overlay overlay /tmp/c -o low
|
|||||||
grep PORTABLE_PREFIXES=app1 /usr/lib/extension-release.d/extension-release.app2
|
grep PORTABLE_PREFIXES=app1 /usr/lib/extension-release.d/extension-release.app2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
umount /tmp/img_bind
|
|
||||||
|
|
||||||
systemd-analyze log-level info
|
systemd-analyze log-level info
|
||||||
|
|
||||||
echo OK >/testok
|
echo OK >/testok
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user