1
0
mirror of https://github.com/systemd/systemd synced 2026-04-23 07:24:51 +02:00

Compare commits

..

27 Commits

Author SHA1 Message Date
Lennart Poettering
af5ee76c56
Merge pull request #22784 from poettering/bootctl-fixlets
Trivial bootctl/kernel-install fixlets
2022-03-18 11:53:08 +01:00
Zbigniew Jędrzejewski-Szmek
23484e1205 systemctl: fix operations on relative paths
We should treat ./some.service and $PWD/some.service as equivalent. But we'd
try to send the relative paths over dbus, which can't work well:

$ sudo systemctl enable ./test2.service
Failed to look up unit file state: Invalid argument
$ sudo systemctl enable $PWD/test2.service
Created symlink /etc/systemd/system/multi-user.target.wants/test2.service → /home/zbyszek/src/systemd/test2.service.
Created symlink /etc/systemd/system/test2.service → /home/zbyszek/src/systemd/test2.service.

Now both are equivalent.
2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
2cdd6bef9c shared/install-printf: drop now-unused install_path_printf() 2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
46801e7647 shared/install: do not print aliases longer than UNIT_NAME_MAX
065364920281e1cf59cab989e17aff21790505c4 did the conversion to install_path_printf().
But IIUC, here we are just looking at a unit file name, not the full
path.
2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
09f5fc66f2 basic/env-file: inline one variable declaration 2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
20afd9a184 systemctl: remove unused parameter 2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
4f5160698e systemctl: drop left-over parens 2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
f60b0813ea man/systemd.exec: tweak markup a bit 2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
4f5c24857b shared/install: adjust comment formatting 2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
d29cc4d6e1 tree-wide: use strv_contains() in more places 2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
d3e85c9c81 shared/install: drop unnecessary casts
The compiler coerces to bool for us, no need to do it explicitly.
2022-03-18 10:22:20 +01:00
Zbigniew Jędrzejewski-Szmek
066931818d shared/install: drop unnecessary parentheses 2022-03-18 10:22:20 +01:00
Nishal Kulkarni
f1c70ed13d shell-completion: Add completion in bootctl
Added new completion for `--make-machine-id-directory`
provideds 3 options(yes no auto)

Closes: #22308
2022-03-18 09:19:56 +00:00
Zbigniew Jędrzejewski-Szmek
c3e7fba07c shared/install: consistently use 'lp' as the name for the LookupPaths instance
Most of the codebase does this. Here we were using 'p' or 'paths'
instead. Those names are very generic and not good for a "global-like"
object like the LookupPaths instance. And we also have 'path' variable,
and it's confusing to have 'path' and 'paths' in the same function that
are unrelated.

Also pass down LookupPaths* lower in the call stack, in preparation for
future changes.
2022-03-18 10:11:37 +01:00
Luca Boccassi
1219bd4306 Add tests and documentation for all remaining sandboxing in user manager 2022-03-18 10:09:56 +01:00
Luca Boccassi
4355c04fef core: insist on sandboxing if ExtensionImages/Directories are configured
Same as other image mounting in the namespace
2022-03-18 10:02:47 +01:00
Yu Watanabe
827f865063 sd-device: shorten code a bit 2022-03-18 09:57:24 +01:00
Yu Watanabe
29e6f70b8d sd-device-enumerator: fix typo: contolC -> controlC
Also shorten code a bit.
2022-03-18 09:43:09 +01:00
Yu Watanabe
f79856d9e8 sort-util: add missing parens
With this, we can call e.g.
```
typesafe_qsort(buf + m, n - m, comp);
```
2022-03-18 09:42:38 +01:00
Lennart Poettering
8d3e0d607e bootctl: add comment, explaining when verb_install() is called 2022-03-18 09:30:29 +01:00
Lennart Poettering
d16da79ec0 bootctl: use faccessat() more 2022-03-18 09:30:25 +01:00
Lennart Poettering
1c2b617703 bootctl: fix typo 2022-03-18 09:30:21 +01:00
Lennart Poettering
acbb4d7ec4 kernel-install: drop spurious double empty line 2022-03-18 09:30:17 +01:00
Lennart Poettering
d9ea4a210b kernel-install: make clear which variables are supposed to be placed in install.conf in a comment 2022-03-18 09:29:47 +01:00
Lennart Poettering
55c8f9ecb0
Merge pull request #22754 from mrc0mmand/creds_dir_specifier
core: add %d specifier for the $CREDENTIALS_DIRECTORY
2022-03-18 09:23:01 +01:00
Frantisek Sumsal
43b9b2053c core: add %d specifier for the $CREDENTIALS_DIRECTORY
Resolves: #22549
2022-03-17 17:45:01 +01:00
Frantisek Sumsal
598a1d7633 core: drop an unnecessary initialization 2022-03-17 14:39:51 +01:00
29 changed files with 413 additions and 335 deletions

16
man/system-or-user-ns.xml Normal file
View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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]' \

View File

@ -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) {

View File

@ -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); \
}) })

View File

@ -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;

View File

@ -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 */

View File

@ -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++)

View File

@ -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=");

View File

@ -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) },

View File

@ -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);

View File

@ -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="$(

View File

@ -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;
} }
} }
} }

View File

@ -1029,19 +1029,10 @@ 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);
if (r < 0) {
r = -errno; r = -errno;
goto fail; goto fail;
} }
} else {
r = fchmod(fileno(f), 0644);
if (r < 0) {
r = -errno;
goto fail;
}
}
if (has_info) { if (has_info) {
const char *property, *value, *tag; const char *property, *value, *tag;
@ -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;
} }

View File

@ -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");

View File

@ -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)

View File

@ -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);
} }

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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++;

View File

@ -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)

View File

@ -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) {

View 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"'

View File

@ -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)'

View File

@ -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