]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #27670 from poettering/switch-root-umount-all
authorLennart Poettering <lennart@poettering.net>
Fri, 19 May 2023 12:03:23 +0000 (05:03 -0700)
committerGitHub <noreply@github.com>
Fri, 19 May 2023 12:03:23 +0000 (05:03 -0700)
umount all mounts during MS_MOVE switch root

67 files changed:
README
hwdb.d/60-keyboard.hwdb
hwdb.d/meson.build
man/loader.conf.xml
man/meson.build
man/nss-resolve.xml
man/org.freedesktop.systemd1.xml
man/repart.d.xml
man/systemd-boot-random-seed.service.xml
man/systemd-boot.xml
man/systemd-dissect.xml
man/systemd-notify.xml
man/systemd-nspawn.xml
man/systemd-pcrphase.service.xml
man/systemd-repart.xml
man/systemd-sleep.conf.xml
man/systemd.exec.xml
man/systemd.net-naming-scheme.xml
man/systemd.path.xml
man/systemd.service.xml
man/systemd.system-credentials.xml
man/systemd.timer.xml
man/systemd.unit.xml
man/sysupdate.d.xml
man/tmpfiles.d.xml
man/ukify.xml
meson.build
mkosi.presets/00-base/mkosi.extra/usr/lib/systemd/system-preset/00-mkosi.preset
src/busctl/busctl.c
src/core/dbus-service.c
src/core/device.c
src/core/load-fragment-gperf.gperf.in
src/core/service.c
src/core/service.h
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-event/sd-event.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn-network.c
src/nspawn/nspawn-oci.c
src/nss-resolve/nss-resolve.c
src/oom/oomd.c
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-dns-transaction.h
src/shared/bus-unit-util.c
test/TEST-13-NSPAWN/test.sh
test/TEST-74-AUX-UTILS/test.sh
test/create-busybox-container [deleted file]
test/fuzz/fuzz-manager-serialize/activation-details-path [moved from test/fuzz/fuzz-manager-serialize/clusterfuzz-testcase-minimized-fuzz-manager-serialize-5609602292252672 with 100% similarity]
test/fuzz/fuzz-manager-serialize/activation-details-service [moved from test/fuzz/fuzz-manager-serialize/clusterfuzz-testcase-minimized-fuzz-manager-serialize-6207619447259136.fuzz with 100% similarity]
test/fuzz/fuzz-manager-serialize/empty-attachment-path [moved from test/fuzz/fuzz-manager-serialize/crash-fc5f5254c946097a774cccec5427289b748e6f2a with 100% similarity]
test/fuzz/fuzz-manager-serialize/invalid-varlink-sock [moved from test/fuzz/fuzz-manager-serialize/crash-4a3d5bed0213b88d06d6f20e7af44a02daf28961 with 100% similarity]
test/fuzz/fuzz-manager-serialize/netns-invalid-socket [moved from test/fuzz/fuzz-manager-serialize/clusterfuzz-testcase-minimized-fuzz-manager-serialize-4847017160212480.fuzz with 100% similarity]
test/fuzz/fuzz-manager-serialize/service-accept-socket [moved from test/fuzz/fuzz-manager-serialize/crash-9eec6b7ef6fd5c9568189f9259e6ce0546752085 with 100% similarity]
test/fuzz/fuzz-manager-serialize/socket-int-max [moved from test/fuzz/fuzz-manager-serialize/clusterfuzz-testcase-minimized-fuzz-manager-serialize-6018678331408384 with 100% similarity]
test/fuzz/fuzz-network-parser/dhcpv4-client-settings [moved from test/fuzz/fuzz-network-parser/dhcp-client-ipv4-dhcp-settings with 100% similarity]
test/fuzz/fuzz-network-parser/dhcpv6-client-rapid-commit [moved from test/fuzz/fuzz-network-parser/dhcp-client-ipv6-rapid-commit with 100% similarity]
test/fuzz/fuzz-network-parser/ipv6-address-label-section [moved from test/fuzz/fuzz-network-parser/25-ipv6-address-label-section with 100% similarity]
test/fuzz/fuzz-systemctl-parse-argv/missing-strv-free [moved from test/fuzz/fuzz-systemctl-parse-argv/missing-strv-free.input with 100% similarity]
test/fuzz/fuzz-unit-file/dm-back\x2dslash.swap [moved from test/fuzz/fuzz-unit-file/dev-mapper-fedora_krowka\x2dswap.swap with 100% similarity]
test/meson.build
test/test-functions
test/units/testsuite-13.machinectl.sh
test/units/testsuite-13.nspawn-oci.sh
test/units/testsuite-13.nspawn.sh
test/units/testsuite-23.runtime-bind-paths.sh
test/units/util.sh
units/systemd-oomd.socket

diff --git a/README b/README
index 8d64ed769c41cdf906f7f9e9f6fddde075bfcf08..a2e0e6c51626861c99c5b6c2782d8391de3c9975 100644 (file)
--- a/README
+++ b/README
@@ -267,7 +267,6 @@ REQUIREMENTS:
         under /usr is strongly encouraged.
 
         Additional packages are necessary to run some tests:
-        - busybox            (used by test/TEST-13-NSPAWN-SMOKE)
         - nc                 (used by test/TEST-12-ISSUE-3171)
         - python             (test-udev which is installed is in python)
         - python-pyparsing
index 60c8e2edf7eecdf501c6acd78ef9ecfcfe5879d5..27113276c47f2c3856ff3b724ab3e59705ad5a7c 100644 (file)
@@ -2055,6 +2055,8 @@ evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivoTecnologiaSA:pn*:pvr
 evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivoTecnologiaSA:pn*:pvr*:rvnPositivoTecnologiaSA:rnK116*
  KEYBOARD_KEY_76=f21                                    # Fn+F1 toggle touchpad
 
+# Positivo (CG15D)
+evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnCG15D*
 # Positivo Motion (N14DP6, N14DP7, N14DP7-V2, N14DP9, N14JP6, N14KP6)
 evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnN14[DJK]P*
  KEYBOARD_KEY_76=f21                                    # Fn+f2 toggle touchpad
index 90b71916b7df5b96cd473b0d94108bd68c32273d..f1bf073949d9362c43c6788b90fc360d776f87db 100644 (file)
@@ -61,7 +61,7 @@ if conf.get('ENABLE_HWDB') == 1
                 parse_hwdb_py = find_program('parse_hwdb.py')
                 test('parse-hwdb',
                      parse_hwdb_py,
-                     suite : 'dist-check',
+                     suite : 'dist',
                      args : [hwdb_files_test,
                              auto_suspend_rules],
                      timeout : 90)
index a0fc278c2acaddbe89f22f51187c45c6749ab9ba..dbbc4b4f5d527f70ae4e857719172d76acff1bb3 100644 (file)
         allows one to ship multiple sets of Secure Boot variables and choose which one to enroll at runtime.
         </para>
 
-        <para>Supported Secure Boot variables are one database for authorized images, one key exchange key
-        (KEK) and one platform key (PK). For more information, refer to the <ulink
-        url="https://uefi.org/specifications">UEFI specification</ulink>, under Secure Boot and Driver
+        <para>Supported Secure Boot variables are one database for authorized images, one for the key
+        exchange key (KEK) and one for the platform key (PK). For more information, refer to the
+        <ulink url="https://uefi.org/specifications">UEFI specification</ulink>, under Secure Boot and Driver
         Signing. Another resource that describe the interplay of the different variables is the
         <ulink url="https://edk2-docs.gitbook.io/understanding-the-uefi-secure-boot-chain/secure_boot_chain_in_uefi/uefi_secure_boot">
         EDK2 documentation</ulink>.</para>
index 23819d03f5ab56e91364e00884bc5c29104150df..e6724a53f4a555482f54f447b886d723f6573e2e 100644 (file)
@@ -226,7 +226,7 @@ update_dbus_docs = custom_target(
 if conf.get('BUILD_MODE_DEVELOPER') == 1
         test('dbus-docs-fresh',
              update_dbus_docs_py,
-             suite : 'dist-check',
+             suite : 'dist',
              args : ['--build-dir', project_build_root, '--test', dbus_docs],
              depends : dbus_programs)
 endif
index b72b1ba64d0487603a3ffce6ca223de44f784853..9954d4082f756d65da93a63b033041db8066ef5e 100644 (file)
@@ -94,7 +94,9 @@
         <term><varname>$SYSTEMD_NSS_RESOLVE_CACHE</varname></term>
 
         <listitem><para>Takes a boolean argument. When false, the cache of previously queried records will
-        not be used by <command>systemd-resolved</command>.</para></listitem>
+        not be used by
+        <citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+        </para></listitem>
       </varlistentry>
     </variablelist>
 
         <term><varname>$SYSTEMD_NSS_RESOLVE_NETWORK</varname></term>
 
         <listitem><para>Takes a boolean argument. When false, answers will be returned without using the
-        network, i.e. either from local sources or the cache in <command>systemd-resolved</command>.
+        network, i.e. either from local sources or the cache in
+        <citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
         </para></listitem>
       </varlistentry>
     </variablelist>
index 09bde73af1f13986ca800bbaed6527e41c34030b..38fd7098aa2e6375964cca50921b551c1505f94b 100644 (file)
@@ -2516,9 +2516,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
       only provided in a best effort fashion: it is not guaranteed to be set, and it is not guaranteed to be
       the only trigger. It is only guaranteed to be a valid trigger that caused the activation job to be
       enqueued and complete successfully. The key value pairs correspond (in lowercase) to the environment
-      variables described in the <literal>Environment Variables Set on Triggered Units</literal> section in
-      <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
-      Note that new key value pair may be added at any time in future versions. Existing entries will not be
+      variables described in the <literal>Environment Variables Set or Propagated by the Service
+      Manager</literal> section in
+      <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>1</manvolnum></citerefentry>. Note
+      that new key value pair may be added at any time in future versions. Existing entries will not be
       removed.</para>
     </refsect2>
 
@@ -2572,7 +2573,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly u RestartSteps = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
-      readonly t RestartUSecMax = ...;
+      readonly t RestartMaxDelayUSec = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t RestartUSecNext = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -3212,7 +3213,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <!--property RestartSteps is not documented!-->
 
-    <!--property RestartUSecMax is not documented!-->
+    <!--property RestartMaxDelayUSec is not documented!-->
 
     <!--property RestartUSecNext is not documented!-->
 
@@ -3786,7 +3787,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="RestartSteps"/>
 
-    <variablelist class="dbus-property" generated="True" extra-ref="RestartUSecMax"/>
+    <variablelist class="dbus-property" generated="True" extra-ref="RestartMaxDelayUSec"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="RestartUSecNext"/>
 
index 4c13ccfb58028b461e21196ea38c53908d6167c0..464bbf076d937871cd843f776550ed4627e22190 100644 (file)
 
         <para>Note that <varname>CopyFiles=</varname> will skip copying files that aren't supported by the
         target filesystem (e.g symlinks, fifos, sockets and devices on vfat). When an unsupported file type
-        is encountered, repart will skip copying this file and write a log message about it.</para>
+        is encountered, <command>systemd-repart</command> will skip copying this file and write a log message
+        about it.</para>
 
         <para>Note that <command>systemd-repart</command> does not change the UIDs/GIDs of any copied files
         and directories. When running <command>systemd-repart</command> as an unprivileged user to build an
 
         <para>Note that when populating XFS filesystems with <command>systemd-repart</command> and loop
         devices are not available, populating XFS filesystems with files containing spaces, tabs or newlines
-        will fail due to limitations of mkfs.xfs's protofile format.</para>
+        will fail due to limitations of <citerefentry
+        project='man-pages'><refentrytitle>mkfs.xfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        protofile format.</para>
 
         <para>This option cannot be combined with <varname>CopyBlocks=</varname>.</para>
 
         <term><varname>SplitName=</varname></term>
 
         <listitem><para>Configures the suffix to append to split artifacts when the <option>--split</option>
-        option of <command>systemd-repart</command> is used. Simple specifier expansion is supported, see
-        below. Defaults to <literal>%t</literal>. To disable split artifact generation for a partition, set
-        <varname>SplitName=</varname> to <literal>-</literal>.</para></listitem>
+        option of
+        <citerefentry><refentrytitle>systemd-repart</refentrytitle><manvolnum>8</manvolnum></citerefentry> is
+        used. Simple specifier expansion is supported, see below. Defaults to <literal>%t</literal>. To
+        disable split artifact generation for a partition, set <varname>SplitName=</varname> to
+        <literal>-</literal>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index ad3477a97ad54385b85d56bd1750fe74884bb2db..87e2e270d02b956d8e838e80331846a26f27659b 100644 (file)
     times. Specifically:</para>
 
     <orderedlist>
-      <listitem><para>In UEFI mode, the <filename>systemd-boot</filename> or
-      <filename>systemd-stub</filename> components load the boot loader random seed off the ESP, hash it with
-      available entropy and the system token, and then update it on disk. A derived seed is passed to the
-      kernel which writes it to its entropy pool.</para></listitem>
+      <listitem><para>In UEFI mode, the
+      <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> or
+      <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+      components load the boot loader random seed from the ESP, hash it with available entropy and the system
+      token, and then update it on disk. A derived seed is passed to the kernel which writes it to its
+      entropy pool.</para></listitem>
 
       <listitem><para>In userspace the <filename>systemd-random-seed.service</filename> service loads the OS
       random seed, writes it to the kernel entropy pool, and then updates it on disk with a new value derived
index a64281b919005dc4b3aa9c465ce706278136f58f..30908e398a3c5975f8a2c025768a6a8786a06206 100644 (file)
   </refsect1>
 
   <refsect1>
-    <title>Using systemd-boot in virtual machines.</title>
+    <title>Using <command>systemd-boot</command> in virtual machines</title>
 
     <para>When using qemu with OVMF (UEFI Firmware for virtual machines) the <option>-kernel</option> switch
     works not only for linux kernels, but for any EFI binary, including sd-boot and unified linux
-    kernels.  Example command line for loading sd-boot on x64:</para>
+    kernels. Example command line for loading <command>systemd-boot</command> on x64:</para>
 
     <para>
       <command>qemu-system-x86_64 <replaceable>[ ... ]</replaceable>
index 06ee0717f825f07a372f570857df03dfb386f80e..0f7928a6c1e2016d035959f86d131864bfee8a8e 100644 (file)
         <term><option>--mtree</option></term>
         <term><option>-l</option></term>
 
-        <listitem><para>Generates a BSD <citerefentry
-        project='die-net'><refentrytitle>mtree</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        <listitem><para>Generates a BSD
+        <citerefentry project='die-net'><refentrytitle>mtree</refentrytitle><manvolnum>8</manvolnum></citerefentry>
         compatible file manifest of the specified disk image. This is useful for comparing disk image
         contents in detail, including inode information and other metadata. While the generated manifest will
         contain detailed inode information, it currently excludes extended attributes, file system
-        capabilities, MAC labels, <citerefentry
-        project='man-pages'><refentrytitle>chattr</refentrytitle><manvolnum>1</manvolnum></citerefentry> file
-        flags, btrfs subvolume information, and various other file metadata. File content information is
-        shown via a SHA256 digest. Additional fields might be added in future. Note that inode information
-        such as link counts, inode numbers and timestamps is excluded from the output on purpose, as it
-        typically complicates reproducibility.</para></listitem>
+        capabilities, MAC labels,
+        <citerefentry project='man-pages'><refentrytitle>chattr</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+        file flags,
+        <citerefentry project='url'><refentrytitle url='https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)'>btrfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+        subvolume information, and various other file metadata. File content information is shown via a
+        SHA256 digest. Additional fields might be added in future. Note that inode information such as link
+        counts, inode numbers and timestamps is excluded from the output on purpose, as it typically
+        complicates reproducibility.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index 1b469fe85c4a9a628130cd3e53ac2202768a874d..8554f39e48286125ad61a9a3d958d623b6ce56f0 100644 (file)
@@ -98,7 +98,7 @@
         cycle. This is equivalent to <command>systemd-notify RELOADING=1</command> (but implicitly also sets
         a <varname>MONOTONIC_USEC=</varname> field as required for <varname>Type=notify-reload</varname>
         services, see
-        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         for details). For details about the semantics of this option see
         <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
       </varlistentry>
index ded8e3cd715ffdd0552108c9efbc0fd8da0e098c..847a11f0e0c165b1b8a139daf267b331a9e702d3 100644 (file)
@@ -1396,13 +1396,15 @@ After=sys-subsystem-net-devices-ens1.device</programlisting>
           <option>0 … y</option> seen from inside of the container is mapped to <option>x + z</option> in the
           <option>x … x + y</option> range on the host. Other host users are mapped to
           <option>nobody</option> inside the container.</para></listitem>
+
           <listitem><para>If <option>idmap</option> is used, any user <option>z</option> in the UID range
           <option>0 … y</option> as seen from inside the container is mapped to the same <option>z</option>
-          in the same <option>0 … y</option> range on the host. All host users outside of that range are
-          mapped to <option>nobody</option> inside the container.</para></listitem>
+          in the same <option>0 … y</option> range on the host. Other host users are mapped to
+          <option>nobody</option> inside the container.</para></listitem>
+
           <listitem><para>If <option>rootidmap</option> is used, the user <option>0</option> seen from inside
-          of the container is mapped to <option>p</option> on the host. All host users outside of that range
-          are mapped to <option>nobody</option> inside the container.</para></listitem>
+          of the container is mapped to <option>p</option> on the host. Other host users are mapped to
+          <option>nobody</option> inside the container.</para></listitem>
         </itemizedlist></para>
 
         <para>Whichever ID mapping option is used, the same mapping will be used for users and groups IDs. If
index 24c7560468ff741691943a86aca52cd63dd6eeea..fad9d8247ae45e8b23bdf4c79a9da87a8b10811c 100644 (file)
       <listitem><para><literal>enter-initrd</literal> — early when the initrd initializes, before activating
       system extension images for the initrd. It acts as a barrier between the time where the kernel
       initializes and where the initrd starts operating and enables system extension images, i.e. code
-      shipped outside of the UKI. (This extension happens when
-      <filename>systemd-pcrphase-initrd.service</filename> is started.)</para></listitem>
+      shipped outside of the UKI. (This extension happens when the
+      <citerefentry><refentrytitle>systemd-pcrphase-initrd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      service is started.)</para></listitem>
 
       <listitem><para><literal>leave-initrd</literal> — when the initrd is about to transition into the host
-      file system. It acts as barrier between initrd code and host OS code. (This extension happens when
-      <filename>systemd-pcrphase-initrd.service</filename> is stopped.)</para></listitem>
+      file system. It acts as barrier between initrd code and host OS code. (This extension happens when the
+      <filename>systemd-pcrphase-initrd.service</filename> service is stopped.)</para></listitem>
 
       <listitem><para><literal>sysinit</literal> — when basic system initialization is complete (which
       includes local file systems having been mounted), and the system begins starting regular system
-      services. (This extension happens when <filename>systemd-pcrphase-sysinit.service</filename> is
-      started.)</para></listitem>
+      services. (This extension happens when the
+      <citerefentry><refentrytitle>systemd-pcrphase-sysinit.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      service is started.)</para></listitem>
 
       <listitem><para><literal>ready</literal> — during later boot-up, after remote file systems have been
       activated (i.e. after <filename>remote-fs.target</filename>), but before users are permitted to log in
       (i.e. before <filename>systemd-user-sessions.service</filename>). It acts as barrier between the time
       where unprivileged regular users are still prohibited to log in and where they are allowed to log in.
-      (This extension happens when <filename>systemd-pcrphase.service</filename> is started.)
+      (This extension happens when the <filename>systemd-pcrphase.service</filename> service is started.)
       </para></listitem>
 
       <listitem><para><literal>shutdown</literal> — when the system shutdown begins. It acts as barrier
       between the time the system is fully up and running and where it is about to shut down. (This extension
-      happens when <filename>systemd-pcrphase.service</filename> is stopped.)</para></listitem>
+      happens when the <filename>systemd-pcrphase.service</filename> service is stopped.)</para></listitem>
 
       <listitem><para><literal>final</literal> — at the end of system shutdown. It acts as barrier between
       the time the service manager still runs and when it transitions into the final shutdown phase where
-      service management is not available anymore. (This extension happens when
-      <filename>systemd-pcrphase-sysinit.service</filename> is stopped.)</para></listitem>
+      service management is not available anymore. (This extension happens when the
+      <citerefentry><refentrytitle>systemd-pcrphase-sysinit.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      service is stopped.)</para></listitem>
     </orderedlist>
 
     <para>During a regular system lifecycle, PCR 11 is extended with the strings
index 98ca1c431a658ebef2909874e8672d156c5d9338..cd5d4631dbf0b96fce914f94320a065b30deb6f3 100644 (file)
         <listitem><para>This option specifies for which partition types <command>systemd-repart</command>
         should defer. All partitions that are deferred using this option are still taken into account when
         calculating the sizes and offsets of other partitions, but aren't actually written to the disk image.
-        The net effect of this option is that if you run <command>systemd-repart</command> again without
-        these options, the missing partitions will be added as if they had not been deferred the first time
+        The net effect of this option is that if you run <command>systemd-repart</command> again without this
+        option, the missing partitions will be added as if they had not been deferred the first time
         <command>systemd-repart</command> was executed.</para></listitem>
       </varlistentry>
 
         <listitem><para>This option allows configuring the sector size of the image produced by
         <command>systemd-repart</command>. It takes a value that is a power of <literal>2</literal> between
         <literal>512</literal> and <literal>4096</literal>. This option is useful when building images for
-        disks that use a different sector size as the disk on which the image is produced.</para></listitem>.
+        disks that use a different sector size as the disk on which the image is produced.</para></listitem>
       </varlistentry>
 
       <xi:include href="standard-options.xml" xpointer="help" />
index f8f1694b57dbacaf47049161bc03936bbcb411b4..bdc4c3c1932456bfa7d434ac73ba31854bc79f65 100644 (file)
         <term><varname>HibernateMode=</varname></term>
         <term><varname>HybridSleepMode=</varname></term>
 
-        <listitem><para>The string to be written to
-        <filename>/sys/power/disk</filename> by,
-        respectively,
+        <listitem><para>The string to be written to <filename>/sys/power/disk</filename> by, respectively,
         <citerefentry><refentrytitle>systemd-suspend.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-        <citerefentry><refentrytitle>systemd-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, or
+        <citerefentry><refentrytitle>systemd-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+        or
         <citerefentry><refentrytitle>systemd-hybrid-sleep.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
-        More than one value can be specified by separating
-        multiple values with whitespace. They will be tried
-        in turn, until one is written without error. If
-        neither succeeds, the operation will be aborted.
-        </para>
-
-        <para><citerefentry><refentrytitle>systemd-suspend-then-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-        uses the value of <varname>SuspendMode=</varname> when suspending and the value of <varname>HibernateMode=</varname> when hibernating.
-        </para></listitem>
+        More than one value can be specified by separating multiple values with whitespace. They will be
+        tried in turn, until one is written without error. If none of the writes succeed, the operation will
+        be aborted.</para>
+
+        <para>The allowed set of values is determined by the kernel and is shown in the file itself (use
+        <command>cat /sys/power/disk</command> to display). See <ulink
+        url="https://www.kernel.org/doc/html/latest/admin-guide/pm/sleep-states.html#basic-sysfs-interfaces-for-system-suspend-and-hibernation">the
+        kernel documentation</ulink> for more details.</para>
+
+        <para>
+        <citerefentry><refentrytitle>systemd-suspend-then-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        uses the value of <varname>SuspendMode=</varname> when suspending and the value of
+        <varname>HibernateMode=</varname> when hibernating.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>HibernateState=</varname></term>
         <term><varname>HybridSleepState=</varname></term>
 
-        <listitem><para>The string to be written to
-        <filename>/sys/power/state</filename> by,
-        respectively,
+        <listitem><para>The string to be written to <filename>/sys/power/state</filename> by, respectively,
         <citerefentry><refentrytitle>systemd-suspend.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-        <citerefentry><refentrytitle>systemd-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, or
+        <citerefentry><refentrytitle>systemd-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+        or
         <citerefentry><refentrytitle>systemd-hybrid-sleep.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
-        More than one value can be specified by separating
-        multiple values with whitespace. They will be tried
-        in turn, until one is written without error. If
-        neither succeeds, the operation will be aborted.
+        More than one value can be specified by separating multiple values with whitespace. They will be
+        tried in turn, until one is written without error. If none of the writes succeed, the operation will
+        be aborted.
         </para>
 
-        <para><citerefentry><refentrytitle>systemd-suspend-then-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-        uses the value of <varname>SuspendState=</varname> when suspending and the value of <varname>HibernateState=</varname> when hibernating.
-        </para></listitem>
+        <para>The allowed set of values is determined by the kernel and is shown in the file itself (use
+        <command>cat /sys/power/state</command> to display). See <ulink
+        url="https://www.kernel.org/doc/html/latest/admin-guide/pm/sleep-states.html#basic-sysfs-interfaces-for-system-suspend-and-hibernation">the
+        kernel documentation</ulink> for more details.</para>
+
+        <para>
+        <citerefentry><refentrytitle>systemd-suspend-then-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        uses the value of <varname>SuspendState=</varname> when suspending and the value of
+        <varname>HibernateState=</varname> when hibernating.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index 795e26e792a854cb59459ada1a33c665714bd71f..c1088a301335229ac931b830194f97be0f865cf7 100644 (file)
@@ -1826,17 +1826,22 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
       <varlistentry>
         <term><varname>ProtectClock=</varname></term>
 
-        <listitem><para>Takes a boolean argument. If set, writes to the hardware clock or system clock will be denied.
-        It is recommended to turn this on for most services that do not need modify the clock. Defaults to off. Enabling
-        this option removes <constant>CAP_SYS_TIME</constant> and <constant>CAP_WAKE_ALARM</constant> from the
-        capability bounding set for this unit, installs a system call filter to block calls that can set the
-        clock, and <varname>DeviceAllow=char-rtc r</varname> is implied. This ensures <filename>/dev/rtc0</filename>,
-        <filename>/dev/rtc1</filename>, etc. are made read-only to the service. See
+        <listitem><para>Takes a boolean argument. If set, writes to the hardware clock or system clock will
+        be denied. Defaults to off. Enabling this option removes <constant>CAP_SYS_TIME</constant> and
+        <constant>CAP_WAKE_ALARM</constant> from the capability bounding set for this unit, installs a system
+        call filter to block calls that can set the clock, and <varname>DeviceAllow=char-rtc r</varname> is
+        implied. Note that the system calls are blocked altogether, the filter does not take into account
+        that some of the calls can be used to read the clock state with some parameter combinations.
+        Effectively, <filename>/dev/rtc0</filename>, <filename>/dev/rtc1</filename>, etc. are made read-only
+        to the service. See
         <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-        for the details about <varname>DeviceAllow=</varname>. If this setting is on, but the unit
-        doesn't have the <constant>CAP_SYS_ADMIN</constant> capability (e.g. services for which
+        for the details about <varname>DeviceAllow=</varname>. If this setting is on, 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>
 
+        <para>It is recommended to turn this on for most services that do not need modify the clock or check
+        its state.</para>
+
         <xi:include href="system-or-user-ns.xml" xpointer="singular"/></listitem>
       </varlistentry>
 
@@ -2957,21 +2962,23 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
         <term><varname>LogRateLimitIntervalSec=</varname></term>
         <term><varname>LogRateLimitBurst=</varname></term>
 
-        <listitem><para>Configures the rate limiting that is applied to log messages generated by this
-        unit. If, in the time interval defined by <varname>LogRateLimitIntervalSec=</varname>, more messages
-        than specified in <varname>LogRateLimitBurst=</varname> are logged by a service, all further messages
+        <listitem><para>Configures the rate limiting that is applied to log messages generated by this unit.
+        If, in the time interval defined by <varname>LogRateLimitIntervalSec=</varname>, more messages than
+        specified in <varname>LogRateLimitBurst=</varname> are logged by a service, all further messages
         within the interval are dropped until the interval is over. A message about the number of dropped
         messages is generated. The time specification for <varname>LogRateLimitIntervalSec=</varname> may be
-        specified in the following units: "s", "min", "h", "ms", "us" (see
+        specified in the following units: "s", "min", "h", "ms", "us". See
         <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
-        details).  The default settings are set by <varname>RateLimitIntervalSec=</varname> and
+        details. The default settings are set by <varname>RateLimitIntervalSec=</varname> and
         <varname>RateLimitBurst=</varname> configured in
-        <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Note
-        that this only applies to log messages that are processed by the logging subsystem, i.e. by
-        <filename>systemd-journald.service</filename>. This means, if you connect a service's stderr directly
-        to a file via <varname>StandardOutput=file:…</varname> or a similar setting the rate limiting will
-        not be applied to messages written that way (but they will be enforced for messages generated via
-        <function>syslog()</function> or similar).</para></listitem>
+        <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+        Note that this only applies to log messages that are processed by the logging subsystem, i.e. by
+        <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        This means that if you connect a service's stderr directly to a file via
+        <varname>StandardOutput=file:…</varname> or a similar setting, the rate limiting will not be applied
+        to messages written that way (but it will be enforced for messages generated via
+        <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+        and similar functions).</para></listitem>
       </varlistentry>
 
       <varlistentry>
index 1e2295ba7a842af4a756da9e82ddf4890bdd8c15..a2c82fb9161dd5fa12978217d5f61e88e7af1c2d 100644 (file)
           <term><varname>ID_NET_NAME_ONBOARD=<replaceable>prefix</replaceable><constant>d</constant><replaceable>number</replaceable></varname></term>
 
           <listitem><para>This name is set based on the numeric ordering information given by the firmware
-          for on-board devices. Different schemes are used depending on the firmware type, as described in the table below.</para>
+          for on-board devices. Different schemes are used depending on the firmware type, as described in
+          the table below.</para>
 
             <table>
-              <title>Onboard naming schemes</title>
+              <title>On-board naming schemes</title>
 
               <tgroup cols='2'>
                 <thead>
                 <tbody>
                   <row>
                     <entry><replaceable>prefix</replaceable><constant>o</constant><replaceable>number</replaceable></entry>
-                    <entry>PCI onboard index</entry>
+                    <entry>PCI on-board index</entry>
                   </row>
 
                   <row>
           numbers, which could either result in an incorrect value of the <varname>ID_NET_NAME_SLOT</varname>
           property or none at all.</para>
 
-          <para>Some firmware and hypervisor implementations report unreasonably high numbers for the onboard
-          index. To prevent the generation of bogus onbard interface names, index numbers greater than 16381
-          (2¹⁴-1) were ignored. For s390 PCI devices index values up to 65535 (2¹⁶-1) are valid. To account
-          for that, the limit was increased to 65535.</para>
+          <para>Some firmware and hypervisor implementations report unreasonably high numbers for the
+          on-board index. To prevent the generation of bogus onbard interface names, index numbers greater
+          than 16381 (2¹⁴-1) were ignored. For s390 PCI devices index values up to 65535 (2¹⁶-1) are valid.
+          To account for that, the limit was increased to 65535.</para>
 
           <para>The udev rule <varname>NAME=</varname> replaces <literal>:</literal>,
           <literal>/</literal>, and <literal>%</literal> with an underscore (<literal>_</literal>), and
index 834f480b5ce10050a2b2677045ce87caf04efb8b..7ea88d0b981e0ce92355b97ca883f441b6ffe5f3 100644 (file)
   <refsect1>
       <title>See Also</title>
       <para>Environment variables with details on the trigger will be set for triggered units. See the
-      <literal>Environment Variables Set on Triggered Units</literal> section in
+      section <literal>Environment Variables Set or Propagated by the Service Manager</literal> in
       <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
       for more details.</para>
       <para>
index 7de1350a5935c2e102761d2427a298c4c46e0d93..646e1f21f067988439d0601625585286bc9d10d2 100644 (file)
             <option>notify</option>. However, it extends the logic in one way: the
             <constant>SIGHUP</constant> UNIX process signal is sent to the service's main process when the
             service is asked to reload. (The signal to send can be tweaked via
-            <varname>ReloadSignal=</varname>, see below.). When
+            <varname>ReloadSignal=</varname>, see below.)  When
             initiating the reload process the service is then expected to reply with a notification message
             via <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
             that contains the <literal>RELOADING=1</literal> field in combination with
       <varlistentry>
         <term><varname>RestartSteps=</varname></term>
         <listitem><para>Configures the number of steps to take to increase the interval
-        of auto-restarts from <varname>RestartSec=</varname> to <varname>RestartSecMax=</varname>.
+        of auto-restarts from <varname>RestartSec=</varname> to <varname>RestartMaxDelaySec=</varname>.
         Takes a positive integer or 0 to disable it. Defaults to 0.</para>
 
-        <para>This setting is effective only if <varname>RestartSecMax=</varname> is also set.</para></listitem>
+        <para>This setting is effective only if <varname>RestartMaxDelaySec=</varname> is also set.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>RestartSecMax=</varname></term>
+        <term><varname>RestartMaxDelaySec=</varname></term>
         <listitem><para>Configures the longest time to sleep before restarting a service
         as the interval goes up with <varname>RestartSteps=</varname>. Takes a value
         in the same format as <varname>RestartSec=</varname>, or <literal>infinity</literal>
         limiting configured with <varname>StartLimitIntervalSec=</varname>
         and <varname>StartLimitBurst=</varname>, see
         <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-        for details.  A restarted service enters the failed state only
-        after the start limits are reached.</para>
+        for details.</para>
 
         <para>Setting this to <option>on-failure</option> is the
         recommended choice for long-running services, in order to
         <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
         details.</para>
 
-        <para>This setting also applies to <command>systemd-oomd</command>. Similarly to the kernel OOM
-        kills, this setting determines the state of the unit after <command>systemd-oomd</command> kills a
-        cgroup associated with it.</para></listitem>
+        <para>This setting also applies to
+        <citerefentry><refentrytitle>systemd-oomd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+        Similarly to the kernel OOM kills performed by the kernel, this setting determines the state of the
+        unit after <command>systemd-oomd</command> kills a cgroup associated with it.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index b473a580a6794dfa027878bcd24d99a246b12f2d..5be4ddfe59d987e6338571a1836ab0a6ac35916e 100644 (file)
       <varlistentry>
         <term><varname>vmm.notify_socket</varname></term>
         <listitem>
-          <para>This credential is parsed looking for an <constant>AF_VSOCK</constant> or
-          <constant>AF_UNIX</constant> address where to send a <constant>READY=1</constant>
-          notification datagram when the system has finished booting. See:
-          <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-          This is useful for hypervisors/VMMs or other processes on the host
-          to receive a notification via VSOCK when a virtual machine has finished booting.
-          Note that in case the hypervisor does not support <constant>SOCK_DGRAM</constant>
-          over <constant>AF_VSOCK</constant>, <constant>SOCK_SEQPACKET</constant> will be
-          tried instead. The credential payload for <constant>AF_VSOCK</constant> should be
-          in the form: <literal>vsock:CID:PORT</literal>.</para>
+          <para>Contains a <constant>AF_VSOCK</constant> or <constant>AF_UNIX</constant> address where to
+          send a <constant>READY=1</constant> notification datagram when the system has finished booting. See
+          <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry> for
+          more information. Note that in case the hypervisor does not support <constant>SOCK_DGRAM</constant>
+          over <constant>AF_VSOCK</constant>, <constant>SOCK_SEQPACKET</constant> will be tried instead. The
+          credential payload for <constant>AF_VSOCK</constant> should be in the form
+          <literal>vsock:CID:PORT</literal>.</para>
+
+          <para>This feature is useful for hypervisors/VMMs or other processes on the host to receive a
+          notification via VSOCK when a virtual machine has finished booting.</para>
         </listitem>
       </varlistentry>
 
index a8c8241c94eeac885252a8e05152ca93d6a8fd77..80dbd6410155f26f4c348951049e8b95c15e1b17 100644 (file)
   <refsect1>
       <title>See Also</title>
       <para>Environment variables with details on the trigger will be set for triggered units. See the
-      <literal>Environment Variables Set on Triggered Units</literal> section in
+      <literal>Environment Variables Set or Propagated by the Service Manager</literal> section in
       <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
       for more details.</para>
       <para>
index e28bfe845e6cc4971fde7ba68960018592541442..d603ec9744469fc5aba137d33145bc512a1e02d3 100644 (file)
         <term><varname>OnFailure=</varname></term>
 
         <listitem><para>A space-separated list of one or more units that are activated when this unit enters
-        the <literal>failed</literal> state.  A service unit using <varname>Restart=</varname> enters the
-        failed state only after the start limits are reached.</para></listitem>
+        the <literal>failed</literal> state.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index bdf4bcbf7a517e2ec16d160acaafd7fe5ebcfe5c..c4cdd7971b877730b382da0e11097b0c375b1e45 100644 (file)
         <constant>subvolume</constant>. For details about the resource types, see above. This option is
         mandatory.</para>
 
-        <para>Note that only some combinations of source and target resource types are supported, see
+        <para>Note that only certain combinations of source and target resource types are supported, see
         above.</para></listitem>
       </varlistentry>
     </variablelist>
index a105b8af394accd9986b3e12c84303900fd55b23..f691eef25d8549d6af1c25d7072ea3fb9044752b 100644 (file)
@@ -647,7 +647,7 @@ w- /proc/sys/vm/swappiness - - - - 10</programlisting></para>
       <para>For example:<programlisting>
 # Files created and modified, and directories accessed more than
 # an hour ago in "/tmp/foo/bar", are subject to time-based cleanup.
-d /tmp/foo/bar - - - bmA:1h -</programlisting></para>
+d /tmp/foo/bar - - - bmA:1h -</programlisting></para>
 
       <para>Note that while the aging algorithm is run an exclusive BSD file lock (see <citerefentry
       project='man-pages'><refentrytitle>flock</refentrytitle><manvolnum>2</manvolnum></citerefentry>) is
index f5a2fcc3e85cee9e56fd49d55399de1c4e9c8b47..2e22b1f42e496009f7f586598c7e94bfaff26123 100644 (file)
           <term><option>--measure</option></term>
           <term><option>--no-measure</option></term>
 
-          <listitem><para>Enable or disable a call to <command>systemd-measure</command> to print
-          pre-calculated PCR values. Defaults to false.</para></listitem>
+          <listitem><para>Enable or disable a call to
+          <citerefentry><refentrytitle>systemd-measure</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+          to print pre-calculated PCR values. Defaults to false.</para></listitem>
         </varlistentry>
 
         <varlistentry>
           <term><varname>SigningEngine=<replaceable>ENGINE</replaceable></varname></term>
           <term><option>--signing-engine=<replaceable>ENGINE</replaceable></option></term>
 
-          <listitem><para>An "engine" to for signing of the resulting binary. This option is currently passed
+          <listitem><para>An "engine" for signing of the resulting binary. This option is currently passed
           verbatim to the <option>--engine=</option> option of
           <citerefentry project='archlinux'><refentrytitle>sbsign</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
           </para></listitem>
index 91523e81ee9418abb6edcea329d7634c76fdcb30..496ca70ecc5d8ebf914f144e335d02ee60db94b9 100644 (file)
@@ -4109,7 +4109,7 @@ if conf.get('ENABLE_HWDB') == 1
         if want_tests != 'false'
                 test('hwdb-test',
                      hwdb_test_sh,
-                     suite : 'dist-check',
+                     suite : 'dist',
                      args : [systemd_hwdb.full_path()],
                      timeout : 90)
         endif
@@ -4159,7 +4159,7 @@ public_programs += udevadm
 if want_tests != 'false'
         test('udev-rules-check',
              udevadm,
-             suite : 'dist-check',
+             suite : 'dist',
              args : ['verify', '--resolve-names=never', all_rules])
 endif
 
@@ -4607,7 +4607,7 @@ foreach fuzzer : fuzzers
                         fuzz_in = tuple[1]
                         test('@0@_@1@'.format(name, fuzz_in),
                              exe,
-                             suite : 'fuzzers',
+                             suite : 'fuzz',
                              args : [fuzz_dir != '' ? project_source_root / fuzz_dir / name / fuzz_in
                                                     : fuzz_generated_in_dir / '@0@_@1@'.format(name, fuzz_in)])
                 endforeach
@@ -4669,7 +4669,7 @@ jekyll = find_program('jekyll', required : false)
 if get_option('mode') == 'developer' and want_tests != 'false' and jekyll.found()
         test('github-pages',
              jekyll,
-             suite : 'dist-check',
+             suite : 'dist',
              args : ['build',
                      '--source', project_source_root / 'docs',
                      '--destination', project_build_root / '_site'])
@@ -4685,13 +4685,13 @@ foreach exec : public_programs
         if want_tests != 'false'
                 test('check-help-' + name,
                      check_help,
-                     suite : 'dist-check',
+                     suite : 'dist',
                      args : exec.full_path(),
                      depends: exec)
 
                 test('check-version-' + name,
                      check_version,
-                     suite : 'dist-check',
+                     suite : 'dist',
                      args : [exec.full_path(),
                              meson.project_version()],
                      depends: exec)
index 8fa29dc85ab0b4d10e4b7a8c021d364a8f1bcacf..070af4c67a221e2d4636b62f0949d0e82319fffb 100644 (file)
@@ -19,10 +19,9 @@ enable dbus-broker.service
 enable systemd-networkd.service
 enable systemd-networkd-wait-online.service
 
-# We install dnf in some images but it's only going to be used rarely to install extra packages so let's not
-# have dnf create its cache.
-disable dnf-makecache.timer
-disable dnf-makecache.service
+# We install dnf in some images but it's only going to be used rarely,
+# so let's not have dnf create its cache.
+disable dnf-makecache.*
 
 # We have journald to receive audit data so let's make sure we're not running auditd as well
 disable auditd.service
index 820d27da20dbe7b9e2ff847f8abb7d045c219e76..965ded9675ecb57767fb081fb70179507b739cf8 100644 (file)
@@ -407,7 +407,7 @@ static void print_subtree(const char *prefix, const char *path, char **l) {
                         n++;
                 }
 
-                printf("%s%s%s\n",
+                printf("%s%s %s\n",
                        prefix,
                        special_glyph(has_more ? SPECIAL_GLYPH_TREE_BRANCH : SPECIAL_GLYPH_TREE_RIGHT),
                        *l);
index e368fcc6ef782b65e9d959886344a2dd256d5681..455114d8cad1a4b6b43b5f18b18c0ee83c9f7918 100644 (file)
@@ -326,7 +326,7 @@ const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("RestartUSec", "t", bus_property_get_usec, offsetof(Service, restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RestartSteps", "u", bus_property_get_unsigned, offsetof(Service, restart_steps), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("RestartUSecMax", "t", bus_property_get_usec, offsetof(Service, restart_usec_max), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RestartMaxDelayUSec", "t", bus_property_get_usec, offsetof(Service, restart_max_delay_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RestartUSecNext", "t", property_get_restart_usec_next, 0, 0),
         SD_BUS_PROPERTY("TimeoutStartUSec", "t", bus_property_get_usec, offsetof(Service, timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Service, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -561,8 +561,8 @@ static int bus_service_set_transient_property(
         if (streq(name, "RestartSteps"))
                 return bus_set_transient_unsigned(u, name, &s->restart_steps, message, flags, error);
 
-        if (streq(name, "RestartUSecMax"))
-                return bus_set_transient_usec(u, name, &s->restart_usec_max, message, flags, error);
+        if (streq(name, "RestartMaxDelayUSec"))
+                return bus_set_transient_usec(u, name, &s->restart_max_delay_usec, message, flags, error);
 
         if (streq(name, "TimeoutStartUSec")) {
                 r = bus_set_transient_usec(u, name, &s->timeout_start_usec, message, flags, error);
index 1449867e357225644abc0b9f6385e46033591907..8d1c6f7d775bab46eee3a44c1feb22008bddf348 100644 (file)
@@ -6,7 +6,7 @@
 #include "sd-messages.h"
 
 #include "alloc-util.h"
-#include "bus-error.h"
+#include "bus-common-errors.h"
 #include "dbus-device.h"
 #include "dbus-unit.h"
 #include "device-private.h"
@@ -619,7 +619,8 @@ static int device_add_udev_wants(Unit *u, sd_device *dev) {
 
                         r = manager_add_job_by_name(u->manager, JOB_START, *i, JOB_FAIL, NULL, &error, NULL);
                         if (r < 0)
-                                log_unit_warning_errno(u, r, "Failed to enqueue SYSTEMD_WANTS= job, ignoring: %s", bus_error_message(&error, r));
+                                log_unit_full_errno(u, sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ? LOG_DEBUG : LOG_WARNING, r,
+                                                    "Failed to enqueue %s job, ignoring: %s", property, bus_error_message(&error, r));
                 }
 
         return strv_free_and_replace(d->wants_property, added);
index 2a3c2c2cb8e1a5443e7976d1e5459ca436fa43ca..83efe8445627cc5d7974214c7f3cfb1f17ea8715 100644 (file)
@@ -405,7 +405,7 @@ Service.ExecStop,                        config_parse_exec,
 Service.ExecStopPost,                    config_parse_exec,                           SERVICE_EXEC_STOP_POST,             offsetof(Service, exec_command)
 Service.RestartSec,                      config_parse_sec,                            0,                                  offsetof(Service, restart_usec)
 Service.RestartSteps,                    config_parse_unsigned,                       0,                                  offsetof(Service, restart_steps)
-Service.RestartSecMax,                   config_parse_sec,                            0,                                  offsetof(Service, restart_usec_max)
+Service.RestartMaxDelaySec,              config_parse_sec,                            0,                                  offsetof(Service, restart_max_delay_usec)
 Service.TimeoutSec,                      config_parse_service_timeout,                0,                                  0
 Service.TimeoutStartSec,                 config_parse_service_timeout,                0,                                  0
 Service.TimeoutStopSec,                  config_parse_sec_fix_0,                      0,                                  offsetof(Service, timeout_stop_usec)
index 5a06cc8a1d77fc5b49f6f422e2404ff0ad9f7e6e..5c16a39309e941009aaedd541367e7355fd0de89 100644 (file)
@@ -122,7 +122,7 @@ static void service_init(Unit *u) {
         s->timeout_abort_usec = u->manager->default_timeout_abort_usec;
         s->timeout_abort_set = u->manager->default_timeout_abort_set;
         s->restart_usec = u->manager->default_restart_usec;
-        s->restart_usec_max = USEC_INFINITY;
+        s->restart_max_delay_usec = USEC_INFINITY;
         s->runtime_max_usec = USEC_INFINITY;
         s->type = _SERVICE_TYPE_INVALID;
         s->socket_fd = -EBADF;
@@ -293,18 +293,18 @@ usec_t service_restart_usec_next(Service *s) {
 
         if (n_restarts_next <= 1 ||
             s->restart_steps == 0 ||
-            s->restart_usec_max == USEC_INFINITY ||
-            s->restart_usec >= s->restart_usec_max)
+            s->restart_max_delay_usec == USEC_INFINITY ||
+            s->restart_usec >= s->restart_max_delay_usec)
                 value = s->restart_usec;
         else if (n_restarts_next > s->restart_steps)
-                value = s->restart_usec_max;
+                value = s->restart_max_delay_usec;
         else {
                 /* Enforced in service_verify() and above */
-                assert(s->restart_usec_max > s->restart_usec);
+                assert(s->restart_max_delay_usec > s->restart_usec);
 
                 /* ((restart_usec_max - restart_usec)^(1/restart_steps))^(n_restart_next - 1) */
                 value = usec_add(s->restart_usec,
-                                 (usec_t) powl(s->restart_usec_max - s->restart_usec,
+                                 (usec_t) powl(s->restart_max_delay_usec - s->restart_usec,
                                                (long double) (n_restarts_next - 1) / s->restart_steps));
         }
 
@@ -689,15 +689,15 @@ static int service_verify(Service *s) {
         if (s->exit_type == SERVICE_EXIT_CGROUP && cg_unified() < CGROUP_UNIFIED_SYSTEMD)
                 log_unit_warning(UNIT(s), "Service has ExitType=cgroup set, but we are running with legacy cgroups v1, which might not work correctly. Continuing.");
 
-        if (s->restart_usec_max == USEC_INFINITY && s->restart_steps > 0)
-                log_unit_warning(UNIT(s), "Service has RestartSteps= but no RestartSecMax= setting. Ignoring.");
+        if (s->restart_max_delay_usec == USEC_INFINITY && s->restart_steps > 0)
+                log_unit_warning(UNIT(s), "Service has RestartSteps= but no RestartMaxDelaySec= setting. Ignoring.");
 
-        if (s->restart_usec_max != USEC_INFINITY && s->restart_steps == 0)
-                log_unit_warning(UNIT(s), "Service has RestartSecMax= but no RestartSteps= setting. Ignoring.");
+        if (s->restart_max_delay_usec != USEC_INFINITY && s->restart_steps == 0)
+                log_unit_warning(UNIT(s), "Service has RestartMaxDelaySec= but no RestartSteps= setting. Ignoring.");
 
-        if (s->restart_usec_max < s->restart_usec) {
-                log_unit_warning(UNIT(s), "RestartSecMax= has a value smaller than RestartSec=, resetting RestartSec= to RestartSecMax=.");
-                s->restart_usec = s->restart_usec_max;
+        if (s->restart_max_delay_usec < s->restart_usec) {
+                log_unit_warning(UNIT(s), "RestartMaxDelaySec= has a value smaller than RestartSec=, resetting RestartSec= to RestartMaxDelaySec=.");
+                s->restart_usec = s->restart_max_delay_usec;
         }
 
         return 0;
@@ -991,14 +991,14 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
         fprintf(f,
                 "%sRestartSec: %s\n"
                 "%sRestartSteps: %u\n"
-                "%sRestartSecMax: %s\n"
+                "%sRestartMaxDelaySec: %s\n"
                 "%sTimeoutStartSec: %s\n"
                 "%sTimeoutStopSec: %s\n"
                 "%sTimeoutStartFailureMode: %s\n"
                 "%sTimeoutStopFailureMode: %s\n",
                 prefix, FORMAT_TIMESPAN(s->restart_usec, USEC_PER_SEC),
                 prefix, s->restart_steps,
-                prefix, FORMAT_TIMESPAN(s->restart_usec_max, USEC_PER_SEC),
+                prefix, FORMAT_TIMESPAN(s->restart_max_delay_usec, USEC_PER_SEC),
                 prefix, FORMAT_TIMESPAN(s->timeout_start_usec, USEC_PER_SEC),
                 prefix, FORMAT_TIMESPAN(s->timeout_stop_usec, USEC_PER_SEC),
                 prefix, service_timeout_failure_mode_to_string(s->timeout_start_failure_mode),
index 5b7f67457e2c2ccc340d5f8ee02459db40d8d056..55c4127deed84b7dcc76b9d8e91065cabdc709fd 100644 (file)
@@ -117,7 +117,7 @@ struct Service {
 
         usec_t restart_usec;
         unsigned restart_steps;
-        usec_t restart_usec_max;
+        usec_t restart_max_delay_usec;
         usec_t timeout_start_usec;
         usec_t timeout_stop_usec;
         usec_t timeout_abort_usec;
index 6e0b88e9d731c8813861a067bfec34baa224bc72..91e7505cd95eba15e83cad23e274ab7b2805fc7e 100644 (file)
@@ -4198,14 +4198,14 @@ _public_ int sd_bus_get_description(sd_bus *bus, const char **description) {
         assert_return(bus, -EINVAL);
         assert_return(bus = bus_resolve(bus), -ENOPKG);
         assert_return(description, -EINVAL);
-        assert_return(bus->description, -ENXIO);
-        assert_return(!bus_origin_changed(bus), -ECHILD);
 
-        if (bus->description)
-                *description = bus->description;
-        else
-                *description = runtime_scope_to_string(bus->runtime_scope);
+        const char *d = bus->description;
+        if (!d)
+                d = runtime_scope_to_string(bus->runtime_scope);
+        if (!d)
+                return -ENXIO;
 
+        *description = d;
         return 0;
 }
 
index 73731294fb38bb00d25f1076ebfa90160e6a11dc..1224654290c7126307637d7640f0c24c0cf4af8f 100644 (file)
@@ -2603,7 +2603,6 @@ _public_ int sd_event_source_set_description(sd_event_source *s, const char *des
 _public_ int sd_event_source_get_description(sd_event_source *s, const char **description) {
         assert_return(s, -EINVAL);
         assert_return(description, -EINVAL);
-        assert_return(!event_origin_changed(s->event), -ECHILD);
 
         if (!s->description)
                 return -ENXIO;
index ac9dc5116e8d72c3d4819e4f246b8d6b5f736307..fcf5c710f1d376eac45f525dd203743d120d5223 100644 (file)
@@ -638,7 +638,7 @@ int mount_all(const char *dest,
 
                 r = chase(mount_table[k].where, dest, CHASE_NONEXISTENT|CHASE_PREFIX_ROOT, &where, NULL);
                 if (r < 0)
-                        return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, mount_table[k].where);
+                        return log_error_errno(r, "Failed to resolve %s%s: %m", strempty(dest), mount_table[k].where);
 
                 /* Skip this entry if it is not a remount. */
                 if (mount_table[k].what) {
@@ -697,7 +697,7 @@ int mount_all(const char *dest,
                          * for those. */
                         r = chase(mount_table[k].what, dest, CHASE_PREFIX_ROOT, &prefixed, NULL);
                         if (r < 0)
-                                return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, mount_table[k].what);
+                                return log_error_errno(r, "Failed to resolve %s%s: %m", strempty(dest), mount_table[k].what);
                 }
 
                 r = mount_verbose_full(
index d898f0d4c911803a122cd50c471444fd1f1e00cb..b1c4f1cad8e4dba8563e7abcf8f0838395ff120d 100644 (file)
@@ -752,38 +752,48 @@ int remove_veth_links(const char *primary, char **pairs) {
 }
 
 static int network_iface_pair_parse(const char* iftype, char ***l, const char *p, const char* ifprefix) {
-        _cleanup_free_ char *a = NULL, *b = NULL;
         int r;
 
-        r = extract_first_word(&p, &a, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
-        if (r < 0)
-                return log_error_errno(r, "Failed to extract first word in %s parameter: %m", iftype);
-        if (r == 0)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Short read while reading %s parameter: %m", iftype);
-        if (!ifname_valid(a))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "%s, interface name not valid: %s", iftype, a);
-
-        if (isempty(p)) {
-                if (ifprefix)
-                        b = strjoin(ifprefix, a);
-                else
-                        b = strdup(a);
-        } else
-                b = strdup(p);
-        if (!b)
-                return log_oom();
+        for (;;) {
+                _cleanup_free_ char *word = NULL, *a = NULL, *b = NULL;
+                const char *interface;
 
-        if (!ifname_valid(b))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                        "%s, interface name not valid: %s", iftype, b);
+                r = extract_first_word(&p, &word, NULL, 0);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse interface name: %m");
+                if (r == 0)
+                        break;
 
-        r = strv_push_pair(l, a, b);
-        if (r < 0)
-                return log_oom();
+                interface = word;
+                r = extract_first_word(&interface, &a, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to extract first word in %s parameter: %m", iftype);
+                if (r == 0)
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "Short read while reading %s parameter: %m", iftype);
+                if (!ifname_valid(a))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "%s, interface name not valid: %s", iftype, a);
+
+                if (isempty(interface)) {
+                        if (ifprefix)
+                                b = strjoin(ifprefix, a);
+                        else
+                                b = strdup(a);
+                } else
+                        b = strdup(interface);
+                if (!b)
+                        return log_oom();
+
+                if (!ifname_valid(b))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "%s, interface name not valid: %s", iftype, b);
+
+                r = strv_consume_pair(l, TAKE_PTR(a), TAKE_PTR(b));
+                if (r < 0)
+                        return log_oom();
+        }
 
-        a = b = NULL;
         return 0;
 }
 
index 5e21538597e27bff190f218d091e01c085f9433f..61798e166cca99c1122c75f3bdf61e9eb3b065ca 100644 (file)
@@ -90,7 +90,7 @@ static int oci_unsupported(const char *name, JsonVariant *v, JsonDispatchFlags f
 }
 
 static int oci_terminal(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        Settings *s = userdata;
+        Settings *s = ASSERT_PTR(userdata);
 
         /* If not specified, or set to true, we'll default to either an interactive or a read-only
          * console. If specified as false, we'll forcibly move to "pipe" mode though. */
@@ -115,6 +115,7 @@ static int oci_console_dimension(const char *name, JsonVariant *variant, JsonDis
 }
 
 static int oci_console_size(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
+        Settings *s = ASSERT_PTR(userdata);
 
         static const JsonDispatch table[] = {
                 { "height", JSON_VARIANT_UNSIGNED, oci_console_dimension, offsetof(Settings, console_height), JSON_MANDATORY },
@@ -122,7 +123,7 @@ static int oci_console_size(const char *name, JsonVariant *v, JsonDispatchFlags
                 {}
         };
 
-        return json_dispatch(v, table, oci_unexpected, flags, userdata);
+        return json_dispatch(v, table, oci_unexpected, flags, s);
 }
 
 static int oci_absolute_path(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
@@ -186,9 +187,8 @@ static int oci_args(const char *name, JsonVariant *v, JsonDispatchFlags flags, v
 
 static int oci_rlimit_type(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
         const char *z;
-        int t, *type = userdata;
-
-        assert_se(type);
+        int *type = ASSERT_PTR(userdata);
+        int t;
 
         z = startswith(json_variant_string(v), "RLIMIT_");
         if (!z)
@@ -206,7 +206,8 @@ static int oci_rlimit_type(const char *name, JsonVariant *v, JsonDispatchFlags f
 }
 
 static int oci_rlimit_value(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        rlim_t z, *value = ASSERT_PTR(userdata);
+        rlim_t *value = ASSERT_PTR(userdata);
+        rlim_t z;
 
         if (json_variant_is_negative(v))
                 z = RLIM_INFINITY;
@@ -227,7 +228,6 @@ static int oci_rlimit_value(const char *name, JsonVariant *v, JsonDispatchFlags
 }
 
 static int oci_rlimits(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-
         Settings *s = ASSERT_PTR(userdata);
         JsonVariant *e;
         int r;
@@ -276,7 +276,8 @@ static int oci_rlimits(const char *name, JsonVariant *v, JsonDispatchFlags flags
 }
 
 static int oci_capability_array(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        uint64_t *mask = userdata, m = 0;
+        uint64_t *mask = ASSERT_PTR(userdata);
+        uint64_t m = 0;
         JsonVariant *e;
 
         JSON_VARIANT_ARRAY_FOREACH(e, v) {
@@ -347,10 +348,10 @@ static int oci_oom_score_adj(const char *name, JsonVariant *v, JsonDispatchFlags
 }
 
 static int oci_uid_gid(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        uid_t *uid = userdata, u;
+        uid_t *uid = ASSERT_PTR(userdata);
+        uid_t u;
         uint64_t k;
 
-        assert(uid);
         assert_cc(sizeof(uid_t) == sizeof(gid_t));
 
         k = json_variant_unsigned(v);
@@ -395,6 +396,7 @@ static int oci_supplementary_gids(const char *name, JsonVariant *v, JsonDispatch
 }
 
 static int oci_user(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
+
         static const JsonDispatch table[] = {
                 { "uid",            JSON_VARIANT_UNSIGNED, oci_uid_gid,            offsetof(Settings, uid), JSON_MANDATORY },
                 { "gid",            JSON_VARIANT_UNSIGNED, oci_uid_gid,            offsetof(Settings, gid), JSON_MANDATORY },
@@ -427,7 +429,7 @@ static int oci_process(const char *name, JsonVariant *v, JsonDispatchFlags flags
 }
 
 static int oci_root(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        Settings *s = userdata;
+        Settings *s = ASSERT_PTR(userdata);
         int r;
 
         static const JsonDispatch table[] = {
@@ -511,13 +513,15 @@ typedef struct oci_mount_data {
         char **options;
 } oci_mount_data;
 
-static void cleanup_oci_mount_data(oci_mount_data *data) {
+static void oci_mount_data_done(oci_mount_data *data) {
         free(data->destination);
         free(data->source);
-        strv_free(data->options);
         free(data->type);
+        strv_free(data->options);
 }
 
+DEFINE_TRIVIAL_DESTRUCTOR(oci_mount_data_donep, oci_mount_data, oci_mount_data_done);
+
 static int oci_mounts(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
         Settings *s = ASSERT_PTR(userdata);
         JsonVariant *e;
@@ -533,8 +537,8 @@ static int oci_mounts(const char *name, JsonVariant *v, JsonDispatchFlags flags,
                 };
 
                 _cleanup_free_ char *joined_options = NULL;
+                _cleanup_(oci_mount_data_donep) oci_mount_data data = {};
                 CustomMount *m;
-                _cleanup_(cleanup_oci_mount_data) oci_mount_data data = {};
 
                 r = json_dispatch(e, table, oci_unexpected, flags, &data);
                 if (r < 0)
@@ -610,20 +614,27 @@ static int oci_namespace_type(const char *name, JsonVariant *v, JsonDispatchFlag
         return 0;
 }
 
+struct namespace_data {
+        unsigned long type;
+        char *path;
+};
+
+static void namespace_data_done(struct namespace_data *p) {
+        assert(p);
+
+        free(p->path);
+}
+
+DEFINE_TRIVIAL_DESTRUCTOR(namespace_data_donep, struct namespace_data, namespace_data_done);
+
 static int oci_namespaces(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        Settings *s = userdata;
+        Settings *s = ASSERT_PTR(userdata);
         unsigned long n = 0;
         JsonVariant *e;
         int r;
 
-        assert_se(s);
-
         JSON_VARIANT_ARRAY_FOREACH(e, v) {
-
-                struct namespace_data {
-                        unsigned long type;
-                        char *path;
-                } data = {};
+                _cleanup_(namespace_data_donep) struct namespace_data data = {};
 
                 static const JsonDispatch table[] = {
                         { "type", JSON_VARIANT_STRING, oci_namespace_type, offsetof(struct namespace_data, type), JSON_MANDATORY },
@@ -632,26 +643,19 @@ static int oci_namespaces(const char *name, JsonVariant *v, JsonDispatchFlags fl
                 };
 
                 r = json_dispatch(e, table, oci_unexpected, flags, &data);
-                if (r < 0) {
-                        free(data.path);
+                if (r < 0)
                         return r;
-                }
 
                 if (data.path) {
-                        if (data.type != CLONE_NEWNET) {
-                                free(data.path);
+                        if (data.type != CLONE_NEWNET)
                                 return json_log(e, flags, SYNTHETIC_ERRNO(EOPNOTSUPP),
                                                 "Specifying namespace path for non-network namespace is not supported.");
-                        }
 
-                        if (s->network_namespace_path) {
-                                free(data.path);
+                        if (s->network_namespace_path)
                                 return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL),
                                                 "Network namespace path specified more than once, refusing.");
-                        }
 
-                        free(s->network_namespace_path);
-                        s->network_namespace_path = data.path;
+                        free_and_replace(s->network_namespace_path, data.path);
                 }
 
                 if (FLAGS_SET(n, data.type))
@@ -675,10 +679,10 @@ static int oci_namespaces(const char *name, JsonVariant *v, JsonDispatchFlags fl
 }
 
 static int oci_uid_gid_range(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        uid_t *uid = userdata, u;
+        uid_t *uid = ASSERT_PTR(userdata);
+        uid_t u;
         uint64_t k;
 
-        assert(uid);
         assert_cc(sizeof(uid_t) == sizeof(gid_t));
 
         /* This is very much like oci_uid_gid(), except the checks are a bit different, as this is a UID range rather
@@ -777,11 +781,9 @@ static int oci_device_type(const char *name, JsonVariant *v, JsonDispatchFlags f
 }
 
 static int oci_device_major(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        unsigned *u = userdata;
+        unsigned *u = ASSERT_PTR(userdata);
         uint64_t k;
 
-        assert_se(u);
-
         k = json_variant_unsigned(v);
         if (!DEVICE_MAJOR_VALID(k))
                 return json_log(v, flags, SYNTHETIC_ERRNO(ERANGE),
@@ -792,11 +794,9 @@ static int oci_device_major(const char *name, JsonVariant *v, JsonDispatchFlags
 }
 
 static int oci_device_minor(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        unsigned *u = userdata;
+        unsigned *u = ASSERT_PTR(userdata);
         uint64_t k;
 
-        assert_se(u);
-
         k = json_variant_unsigned(v);
         if (!DEVICE_MINOR_VALID(k))
                 return json_log(v, flags, SYNTHETIC_ERRNO(ERANGE),
@@ -807,11 +807,10 @@ static int oci_device_minor(const char *name, JsonVariant *v, JsonDispatchFlags
 }
 
 static int oci_device_file_mode(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        mode_t *mode = userdata, m;
+        mode_t *mode = ASSERT_PTR(userdata);
+        mode_t m;
         uint64_t k;
 
-        assert(mode);
-
         k = json_variant_unsigned(v);
         m = (mode_t) k;
 
@@ -931,7 +930,7 @@ static int oci_cgroups_path(const char *name, JsonVariant *v, JsonDispatchFlags
 }
 
 static int oci_cgroup_device_type(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        mode_t *mode = userdata;
+        mode_t *mode = ASSERT_PTR(userdata);
         const char *n;
 
         assert_se(n = json_variant_string(v));
@@ -958,7 +957,7 @@ struct device_data {
 };
 
 static int oci_cgroup_device_access(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        struct device_data *d = userdata;
+        struct device_data *d = ASSERT_PTR(userdata);
         bool r = false, w = false, m = false;
         const char *s;
         size_t i;
@@ -984,7 +983,6 @@ static int oci_cgroup_device_access(const char *name, JsonVariant *v, JsonDispat
 }
 
 static int oci_cgroup_devices(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-
         _cleanup_free_ struct device_data *list = NULL;
         Settings *s = ASSERT_PTR(userdata);
         size_t n_list = 0, i;
@@ -1187,7 +1185,7 @@ static int oci_cgroup_memory(const char *name, JsonVariant *v, JsonDispatchFlags
                 {}
         };
 
-        Settings *s = userdata;
+        Settings *s = ASSERT_PTR(userdata);
         int r;
 
         r = json_dispatch(v, table, oci_unexpected, flags, &data);
@@ -1303,7 +1301,7 @@ static int oci_cgroup_cpu(const char *name, JsonVariant *v, JsonDispatchFlags fl
                 .period = UINT64_MAX,
         };
 
-        Settings *s = userdata;
+        Settings *s = ASSERT_PTR(userdata);
         int r;
 
         r = json_dispatch(v, table, oci_unexpected, flags, &data);
@@ -1741,13 +1739,15 @@ struct syscall_rule {
         size_t n_arguments;
 };
 
-static void syscall_rule_free(struct syscall_rule *rule) {
+static void syscall_rule_done(struct syscall_rule *rule) {
         assert(rule);
 
         strv_free(rule->names);
         free(rule->arguments);
 };
 
+DEFINE_TRIVIAL_DESTRUCTOR(syscall_rule_donep, struct syscall_rule, syscall_rule_done);
+
 static int oci_seccomp_action(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
         uint32_t *action = ASSERT_PTR(userdata);
         int r;
@@ -1831,18 +1831,17 @@ static int oci_seccomp_syscalls(const char *name, JsonVariant *v, JsonDispatchFl
                         { "args",   JSON_VARIANT_ARRAY,  oci_seccomp_args,   0,                                     0              },
                         {}
                 };
-                struct syscall_rule rule = {
+                _cleanup_(syscall_rule_donep) struct syscall_rule rule = {
                         .action = UINT32_MAX,
                 };
 
                 r = json_dispatch(e, table, oci_unexpected, flags, &rule);
                 if (r < 0)
-                        goto fail_rule;
+                        return r;
 
                 if (strv_isempty(rule.names)) {
                         json_log(e, flags, 0, "System call name list is empty.");
-                        r = -EINVAL;
-                        goto fail_rule;
+                        return -EINVAL;
                 }
 
                 STRV_FOREACH(i, rule.names) {
@@ -1856,15 +1855,8 @@ static int oci_seccomp_syscalls(const char *name, JsonVariant *v, JsonDispatchFl
 
                         r = seccomp_rule_add_array(sc, rule.action, nr, rule.n_arguments, rule.arguments);
                         if (r < 0)
-                                goto fail_rule;
+                                return r;
                 }
-
-                syscall_rule_free(&rule);
-                continue;
-
-        fail_rule:
-                syscall_rule_free(&rule);
-                return r;
         }
 
         return 0;
@@ -2031,7 +2023,7 @@ static int oci_linux(const char *name, JsonVariant *v, JsonDispatchFlags flags,
 }
 
 static int oci_hook_timeout(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
-        usec_t *u = userdata;
+        usec_t *u = ASSERT_PTR(userdata);
         uint64_t k;
 
         k = json_variant_unsigned(v);
index 02267522759de0252d9e82dffe188859da5df31b..89381f56031a6e301f435756f118034e5ed7af7f 100644 (file)
@@ -269,6 +269,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
                         goto try_again;
                 if (error_shall_fallback(error_id))
                         goto fail;
+                if (streq(error_id, "io.systemd.Resolve.NoSuchResourceRecord"))
+                        goto no_data;
                 goto not_found;
         }
 
@@ -367,6 +369,10 @@ not_found:
         *h_errnop = HOST_NOT_FOUND;
         return NSS_STATUS_NOTFOUND;
 
+no_data:
+        *h_errnop = NO_DATA;
+        return NSS_STATUS_NOTFOUND;
+
 try_again:
         UNPROTECT_ERRNO;
         *errnop = -r;
@@ -425,6 +431,8 @@ enum nss_status _nss_resolve_gethostbyname3_r(
                         goto try_again;
                 if (error_shall_fallback(error_id))
                         goto fail;
+                if (streq(error_id, "io.systemd.Resolve.NoSuchResourceRecord"))
+                        goto no_data;
                 goto not_found;
         }
 
@@ -542,6 +550,10 @@ not_found:
         *h_errnop = HOST_NOT_FOUND;
         return NSS_STATUS_NOTFOUND;
 
+no_data:
+        *h_errnop = NO_DATA;
+        return NSS_STATUS_NOTFOUND;
+
 try_again:
         UNPROTECT_ERRNO;
         *errnop = -r;
index 28405e2f6463ce14b4e13c14a9d867f005d5e7c4..ecc2eda5dc00fcf3920eef0b3fa756512d16b540 100644 (file)
@@ -146,7 +146,7 @@ static int run(int argc, char *argv[]) {
 
         r = safe_atollu(swap, &s);
         if (r < 0 || s == 0)
-                log_warning("Swap is currently not detected; memory pressure usage will be degraded");
+                log_warning("No swap; memory pressure usage will be degraded");
 
         if (!is_pressure_supported())
                 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Pressure Stall Information (PSI) is not supported");
index 3f994690e622a610e05d471f4190a03365a6924b..400ca0d2e8e1920edd570c93df4948c303608b37 100644 (file)
@@ -282,7 +282,6 @@ int dns_transaction_new(
                 .bypass = dns_packet_ref(bypass),
                 .current_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID,
                 .clamp_feature_level_servfail = _DNS_SERVER_FEATURE_LEVEL_INVALID,
-                .clamp_feature_level_nxdomain = _DNS_SERVER_FEATURE_LEVEL_INVALID,
                 .id = pick_new_id(s->manager),
         };
 
@@ -472,10 +471,8 @@ static int dns_transaction_pick_server(DnsTransaction *t) {
 
         /* If we changed the server invalidate the feature level clamping, as the new server might have completely
          * different properties. */
-        if (server != t->server) {
+        if (server != t->server)
                 t->clamp_feature_level_servfail = _DNS_SERVER_FEATURE_LEVEL_INVALID;
-                t->clamp_feature_level_nxdomain = _DNS_SERVER_FEATURE_LEVEL_INVALID;
-        }
 
         t->current_feature_level = dns_server_possible_feature_level(server);
 
@@ -483,9 +480,6 @@ static int dns_transaction_pick_server(DnsTransaction *t) {
         if (t->clamp_feature_level_servfail != _DNS_SERVER_FEATURE_LEVEL_INVALID &&
             t->current_feature_level > t->clamp_feature_level_servfail)
                 t->current_feature_level = t->clamp_feature_level_servfail;
-        if (t->clamp_feature_level_nxdomain != _DNS_SERVER_FEATURE_LEVEL_INVALID &&
-            t->current_feature_level > t->clamp_feature_level_nxdomain)
-                t->current_feature_level = t->clamp_feature_level_nxdomain;
 
         log_debug("Using feature level %s for transaction %u.", dns_server_feature_level_to_string(t->current_feature_level), t->id);
 
@@ -1277,45 +1271,6 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt
                 return;
         }
 
-        if (t->scope->protocol == DNS_PROTOCOL_DNS &&
-            !t->bypass &&
-            DNS_PACKET_RCODE(p) == DNS_RCODE_NXDOMAIN &&
-            p->opt && !DNS_PACKET_DO(p) &&
-            DNS_SERVER_FEATURE_LEVEL_IS_EDNS0(t->current_feature_level) &&
-            DNS_SERVER_FEATURE_LEVEL_IS_UDP(t->current_feature_level) &&
-            t->scope->dnssec_mode != DNSSEC_YES) {
-
-                /* Some captive portals are special in that the Aruba/Datavalet hardware will miss
-                 * replacing the packets with the local server IP to point to the authenticated side
-                 * of the network if EDNS0 is enabled. Instead they return NXDOMAIN, with DO bit set
-                 * to zero... nothing to see here, yet respond with the captive portal IP, when using
-                 * the more simple UDP level.
-                 *
-                 * Common portal names that fail like so are:
-                 *     secure.datavalet.io
-                 *     securelogin.arubanetworks.com
-                 *     securelogin.networks.mycompany.com
-                 *
-                 * Thus retry NXDOMAIN RCODES with a lower feature level.
-                 *
-                 * Do not lower the server's tracked feature level, as the captive portal should not
-                 * be lying for the wider internet (e.g. _other_ queries were observed fine with
-                 * EDNS0 on these networks, post auth), i.e. let's just lower the level transaction's
-                 * feature level.
-                 *
-                 * This is reported as https://github.com/dns-violations/dns-violations/blob/master/2018/DVE-2018-0001.md
-                 */
-
-                t->clamp_feature_level_nxdomain = DNS_SERVER_FEATURE_LEVEL_UDP;
-
-                log_debug("Server returned error %s in EDNS0 mode, retrying transaction with reduced feature level %s (DVE-2018-0001 mitigation)",
-                          FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p)),
-                          dns_server_feature_level_to_string(t->clamp_feature_level_nxdomain));
-
-                dns_transaction_retry(t, false /* use the same server */);
-                return;
-        }
-
         if (t->server) {
                 /* Report that we successfully received a valid packet with a good rcode after we initially got a bad
                  * rcode and subsequently downgraded the protocol */
index 5a0e35704cd2db4dbda1f86f1bea489a9352fb9d..dd3b897a67abfef7e31622ee3a871dec479b7bd9 100644 (file)
@@ -97,11 +97,8 @@ struct DnsTransaction {
         /* The features of the DNS server at time of transaction start */
         DnsServerFeatureLevel current_feature_level;
 
-        /* If we got SERVFAIL back, we retry the lookup, using a lower feature level than we used
-         * before. Similar, if we get NXDOMAIN in pure EDNS0 mode, we check in EDNS0-less mode before giving
-         * up (as mitigation for DVE-2018-0001). */
+        /* If we got SERVFAIL back, we retry the lookup, using a lower feature level than we used before. */
         DnsServerFeatureLevel clamp_feature_level_servfail;
-        DnsServerFeatureLevel clamp_feature_level_nxdomain;
 
         uint16_t id;
 
index a321179609743acdfe41a52dc3d16035ac683237..b32071104b603ee4ee3694b7de3a10cb5d22db76 100644 (file)
@@ -2210,6 +2210,7 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
                 return bus_append_parse_boolean(m, field, eq);
 
         if (STR_IN_SET(field, "RestartSec",
+                              "RestartMaxDelaySec",
                               "TimeoutStartSec",
                               "TimeoutStopSec",
                               "TimeoutAbortSec",
@@ -2226,7 +2227,8 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
                 return bus_append_parse_sec_rename(m, "TimeoutStopSec", eq);
         }
 
-        if (streq(field, "FileDescriptorStoreMax"))
+        if (STR_IN_SET(field, "FileDescriptorStoreMax",
+                              "RestartSteps"))
                 return bus_append_safe_atou(m, field, eq);
 
         if (STR_IN_SET(field, "ExecCondition",
index 8bf33ceb12e6166637fc0b22d378881a649afef8..2e94156432b63f3b5edb1547e2533e8bf21be547 100755 (executable)
@@ -11,19 +11,35 @@ TEST_NO_NSPAWN=1
 
 test_append_files() {
     local workspace="${1:?}"
+    local container="$workspace/testsuite-13-container-template"
 
-    # On openSUSE the static linked version of busybox is named "busybox-static".
-    busybox="$(type -P busybox-static || type -P busybox)"
-    inst_simple "$busybox" "$(dirname "$busybox")/busybox"
+    # Create a dummy container "template" with a minimal toolset, which we can
+    # then use as a base for our nspawn/machinectl tests
+    initdir="$container" setup_basic_dirs
+    initdir="$container" image_install \
+        bash \
+        cat \
+        hostname \
+        grep \
+        ip \
+        ls \
+        md5sum \
+        mountpoint \
+        nc \
+        ps \
+        seq \
+        sleep \
+        stat \
+        touch \
+        true
 
-    if command -v selinuxenabled >/dev/null && selinuxenabled; then
-        image_install chcon selinuxenabled
-        cp -ar /etc/selinux "$workspace/etc/selinux"
-        sed -i "s/^SELINUX=.*$/SELINUX=permissive/" "$workspace/etc/selinux/config"
-    fi
-
-    "$TEST_BASE_DIR/create-busybox-container" "$workspace/testsuite-13.nc-container"
-    initdir="$workspace/testsuite-13.nc-container" image_install nc ip md5sum
+    cp /etc/os-release "$container/usr/lib/os-release"
+    cat >"$container/sbin/init" <<EOF
+#!/bin/bash
+echo "Hello from dummy init, beautiful day, innit?"
+ip link
+EOF
+    chmod +x "$container/sbin/init"
 }
 
 do_test "$@"
index 6b7c251049659edce3267d1e58d65cf47997bdfa..1e360658ed5364a268dac9ecbe98582f5cfa914a 100755 (executable)
@@ -10,7 +10,11 @@ TEST_DESCRIPTION="Tests for auxiliary utilities"
 test_append_files() {
     local workspace="${1:?}"
 
-    printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >"$workspace/etc/machine-id"
+    if ! get_bool "${TEST_PREFER_NSPAWN:-}" && ! get_bool "${TEST_NO_QEMU:-}"; then
+        # Check if we can correctly boot with an invalid machine ID only if we run
+        # the QEMU test, as nspawn refuses the invalid machine ID with -EUCLEAN
+        printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >"$workspace/etc/machine-id"
+    fi
 }
 
 do_test "$@"
diff --git a/test/create-busybox-container b/test/create-busybox-container
deleted file mode 100755 (executable)
index 5b2c80e..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env bash
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-set -eu
-set -o pipefail
-
-root="${1:?Usage: $0 container-root}"
-mkdir -p "$root"
-mkdir -p "$root/usr/bin"
-
-# On openSUSE the static linked version of busybox is named "busybox-static".
-busybox="$(type -P busybox-static || type -P busybox)"
-cp "$busybox" "$root/usr/bin/busybox"
-
-mkdir "$root/var"
-mkdir -p "$root/usr/lib"
-touch "$root/usr/lib/os-release"
-
-ln -s busybox "$root/usr/bin/cat"
-ln -s busybox "$root/usr/bin/hostname"
-ln -s busybox "$root/usr/bin/ip"
-ln -s busybox "$root/usr/bin/md5sum"
-ln -s busybox "$root/usr/bin/mountpoint"
-ln -s busybox "$root/usr/bin/ps"
-ln -s busybox "$root/usr/bin/seq"
-ln -s busybox "$root/usr/bin/sh"
-ln -s busybox "$root/usr/bin/sleep"
-ln -s busybox "$root/usr/bin/stat"
-ln -s busybox "$root/usr/bin/test"
-ln -s busybox "$root/usr/bin/touch"
-ln -s busybox "$root/usr/bin/tr"
-ln -s busybox "$root/usr/bin/true"
-ln -s busybox "$root/usr/bin/usleep"
-
-# Mock the bare minimum of getent to make systemd-nspawn --user= "work"
-cat >"$root/usr/bin/getent" <<\EOF
-#!/bin/sh
-
-if [[ $# - eq 0 ]]; then
-    :
-elif [[ $1 == passwd ]]; then
-    echo "testuser:x:1000:1000:testuser:/:/bin/sh"
-elif [[ $1 == initgroups ]]; then
-    echo "testuser"
-fi
-EOF
-chmod +x "$root/usr/bin/getent"
-
-mkdir -p "$root/usr/sbin"
-cat >"$root/usr/sbin/init" <<\EOF
-#!/bin/sh
-
-printf "ps aufx:\n"
-ps aufx
-
-printf "/proc/1/cmdline:\n"
-printf "%s\n\n" "$(tr '\0' ' ' </proc/1/cmdline)"
-
-printf "/proc/1/environ:\n"
-printf "%s\n\n" "$(tr '\0' '\n' </proc/1/environ)"
-
-printf "/proc/1/mountinfo:\n"
-cat /proc/self/mountinfo
-printf "\n"
-
-printf "/proc/1/cgroup:\n"
-printf "%s\n\n" "$(cat /proc/1/cgroup)"
-
-printf "/proc/1/uid_map:\n"
-printf "%s\n\n" "$(cat /proc/1/uid_map)"
-
-printf "/proc/1/setgroups:\n"
-printf "%s\n\n" "$(cat /proc/1/setgroups)"
-
-printf "/proc/1/gid_map:\n"
-printf "%s\n\n" "$(cat /proc/1/gid_map)"
-
-printf "ip link:\n"
-ip link
-EOF
-chmod +x "$root/usr/sbin/init"
-
-ln -srf "$root/usr/bin" "$root/bin"
-ln -srf "$root/usr/sbin" "$root/sbin"
-ln -srf "$root/usr/lib" "$root/lib"
index 48f837cee52c2605625215106a72e9ee4aed9462..0b0a32c0d1468cd8c5472cd40020bb2c6a884f1e 100644 (file)
@@ -45,10 +45,6 @@ if install_tests
                                install_dir : testdata_dir)
         endif
 
-        install_data('create-busybox-container',
-                     install_mode : 'rwxr-xr-x',
-                     install_dir : testdata_dir)
-
         # The unit tests implemented as shell scripts expect to find testdata/
         # in the directory where they are stored.
         meson.add_install_script(meson_make_symlink,
@@ -91,7 +87,7 @@ rule_syntax_check_py = find_program('rule-syntax-check.py')
 if want_tests != 'false'
         test('rule-syntax-check',
              rule_syntax_check_py,
-             suite : 'dist-check',
+             suite : 'dist',
              args : all_rules)
 endif
 
@@ -133,7 +129,7 @@ if rpm.found() and rpmspec.found()
         if want_tests != 'false'
                 test('test-rpm-macros',
                      test_rpm_macros,
-                     suite : 'dist-check',
+                     suite : 'dist',
                      args : [project_build_root])
         endif
 else
@@ -163,7 +159,7 @@ if want_tests != 'false' and dmi_arches.contains(host_machine.cpu_family())
 
                 test(name,
                      udev_dmi_memory_id_test,
-                     suite : 'dist-check',
+                     suite : 'dist',
                      args : [udev_prog_paths['dmi_memory_id'].full_path(),
                              source,
                              source + '.txt'],
index 1bf9f2d54f89d38f7a15ee75a504e5c51dfbd4cd..057b748f81824969e8d71c16ccb878f77716714b 100644 (file)
@@ -214,6 +214,7 @@ BASICTOOLS=(
     script
     sed
     seq
+    setfacl
     setfattr
     setfont
     setpriv
@@ -475,6 +476,8 @@ run_qemu() {
         kernel_params+=("rd.hostonly=0")
     fi
 
+    # Debian/Ubuntu's initramfs tries to check if it can resume from hibernation
+    # and wastes a minute or so probing disks, skip that as it's not useful here
     kernel_params+=(
         "root=LABEL=systemd_boot"
         "rw"
@@ -486,6 +489,7 @@ run_qemu() {
         "SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/testsuite-$1.units:/usr/lib/systemd/tests/testdata/units:"
         "systemd.unit=testsuite.target"
         "systemd.wants=testsuite-$1.service"
+        "noresume"
     )
 
     if ! get_bool "$INTERACTIVE_DEBUG"; then
@@ -883,8 +887,8 @@ INNER_EOF
 # Let's make one to prevent unexpected "<bin> not found" issues in the future
 export PATH="/sbin:/bin:/usr/sbin:/usr/bin"
 
-mount -t proc proc /proc
-mount -t sysfs sysfs /sys
+mountpoint -q /proc || mount -t proc proc /proc
+mountpoint -q /sys || mount -t sysfs sysfs /sys
 mount -o remount,rw /
 
 DEFAULT_ENVIRONMENT="\$DEFAULT_ENVIRONMENT ASAN_RT_PATH=$ASAN_RT_PATH"
@@ -958,7 +962,7 @@ install_fs_tools() {
 install_modules() {
     dinfo "Install modules"
 
-    instmods dummy vfat veth
+    instmods bridge dummy ipvlan macvlan vfat veth
     instmods loop =block
     instmods nls_ascii =nls
     instmods overlay =overlayfs
@@ -2652,13 +2656,14 @@ inst_binary() {
 
     # Same as above, but we need to wrap certain libraries unconditionally
     #
-    # chown, getent, login, su, useradd, userdel - dlopen() (not only) systemd's PAM modules
+    # chown, getent, login, setfacl, su, useradd, userdel
+    #    - dlopen() (not only) systemd's PAM modules
     # ls, mkfs.*, mksquashfs, mkswap, setpriv, stat
-    #       - pull in nss_systemd with certain options (like ls -l) when
-    #         nsswitch.conf uses [SUCCESS=merge] (like on Arch Linux)
+    #   - pull in nss_systemd with certain options (like ls -l) when
+    #     nsswitch.conf uses [SUCCESS=merge] (like on Arch Linux)
     # delv, dig - pull in nss_resolve if `resolve` is in nsswitch.conf
     # tar - called by machinectl in TEST-25
-    bin_rx='/(chown|delv|dig|getent|login|ls|mkfs\.[a-z0-9]+|mksquashfs|mkswap|setpriv|stat|su|tar|useradd|userdel)$'
+    bin_rx='/(chown|delv|dig|getent|login|ls|mkfs\.[a-z0-9]+|mksquashfs|mkswap|setfacl|setpriv|stat|su|tar|useradd|userdel)$'
     if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$bin" =~ $bin_rx ]]; then
         wrap_binary=1
     fi
index 8ccf4c5dc35c1dc614a18bb6ca0d6e21ccd7b22d..966b11bc7fb1d6b700b1670f9f9963c77cdc170c 100755 (executable)
@@ -4,9 +4,10 @@
 set -eux
 set -o pipefail
 
-export PAGER=
+# shellcheck source=test/units/util.sh
+. "$(dirname "$0")"/util.sh
 
-CREATE_BB_CONTAINER="/usr/lib/systemd/tests/testdata/create-busybox-container"
+export PAGER=
 
 at_exit() {
     set +e
@@ -14,6 +15,7 @@ at_exit() {
     machinectl status long-running >/dev/null && machinectl kill --signal=KILL long-running
     mountpoint -q /var/lib/machines && timeout 10 sh -c "while ! umount /var/lib/machines; do sleep .5; done"
     [[ -n "${NSPAWN_FRAGMENT:-}" ]] && rm -f "/etc/systemd/nspawn/$NSPAWN_FRAGMENT" "/var/lib/machines/$NSPAWN_FRAGMENT"
+    rm -f /run/systemd/nspawn/*.nspawn
 }
 
 trap at_exit EXIT
@@ -24,18 +26,17 @@ mount -t tmpfs tmpfs /var/lib/machines
 
 # Create a couple of containers we can refer to in tests
 for i in {0..4}; do
-    "$CREATE_BB_CONTAINER" "/var/lib/machines/container$i"
+    create_dummy_container "/var/lib/machines/container$i"
     machinectl start "container$i"
 done
 # Create one "long running" container with some basic signal handling
-"$CREATE_BB_CONTAINER" /var/lib/machines/long-running
+create_dummy_container /var/lib/machines/long-running
 cat >/var/lib/machines/long-running/sbin/init <<\EOF
-#!/bin/sh -x
-#
+#!/usr/bin/bash -x
+
 PID=0
 
-# sh doesn't recognize RTMIN+4, so we have to use the signal number directly
-trap "touch /poweroff" 38
+trap "touch /poweroff" RTMIN+4
 trap "touch /reboot" INT
 trap "touch /trap" TRAP
 trap 'kill $PID' EXIT
@@ -82,24 +83,24 @@ machinectl disable long-running
 test ! -L /etc/systemd/system/machines.target.wants/systemd-nspawn@long-running.service
 machinectl disable long-running long-running long-running container1
 
-[[ "$(machinectl shell testuser@ /bin/sh -c 'echo -ne $FOO')" == "" ]]
-[[ "$(machinectl shell --setenv=FOO=bar testuser@ /bin/sh -c 'echo -ne $FOO')" == "bar" ]]
+[[ "$(machinectl shell testuser@ /usr/bin/bash -c 'echo -ne $FOO')" == "" ]]
+[[ "$(machinectl shell --setenv=FOO=bar testuser@ /usr/bin/bash -c 'echo -ne $FOO')" == "bar" ]]
 
 [[ "$(machinectl show --property=State --value long-running)" == "running" ]]
 # Equivalent to machinectl kill --signal=SIGRTMIN+4 --kill-whom=leader
 rm -f /var/lib/machines/long-running/poweroff
 machinectl poweroff long-running
-timeout 10 sh -c "while ! test -e /var/lib/machines/long-running/poweroff; do sleep .5; done"
+timeout 10 bash -c "while ! test -e /var/lib/machines/long-running/poweroff; do sleep .5; done"
 machinectl poweroff long-running long-running long-running
 # Equivalent to machinectl kill --signal=SIGINT --kill-whom=leader
 rm -f /var/lib/machines/long-running/reboot
 machinectl reboot long-running
-timeout 10 sh -c "while ! test -e /var/lib/machines/long-running/reboot; do sleep .5; done"
+timeout 10 bash -c "while ! test -e /var/lib/machines/long-running/reboot; do sleep .5; done"
 machinectl reboot long-running long-running long-running
 # Skip machinectl terminate for now, as it doesn't play well with our "init"
 rm -f /var/lib/machines/long-running/trap
 machinectl kill --signal=SIGTRAP --kill-whom=leader long-running
-timeout 10 sh -c "while ! test -e /var/lib/machines/long-running/trap; do sleep .5; done"
+timeout 10 bash -c "while ! test -e /var/lib/machines/long-running/trap; do sleep .5; done"
 machinectl kill --signal=SIGTRAP --kill-whom=leader long-running long-running long-running
 # All used signals should've been caught by a handler
 [[ "$(machinectl show --property=State --value long-running)" == "running" ]]
@@ -181,7 +182,7 @@ machinectl import-fs /tmp/container.dir container-dir
 machinectl start container-dir
 rm -fr /tmp/container.dir
 
-timeout 10 sh -c "while ! machinectl clean --all; do sleep .5; done"
+timeout 10 bash -c "while ! machinectl clean --all; do sleep .5; done"
 
 NSPAWN_FRAGMENT="machinectl-test-$RANDOM.nspawn"
 cat >"/var/lib/machines/$NSPAWN_FRAGMENT" <<EOF
index cbfdb18290c1db91c4218916a29ce2b5139b6874..6329d25f3b78202d4647c521543aa9674f24d8cf 100755 (executable)
@@ -4,9 +4,11 @@
 set -eux
 set -o pipefail
 
+# shellcheck source=test/units/util.sh
+. "$(dirname "$0")"/util.sh
+
 export SYSTEMD_LOG_LEVEL=debug
 export SYSTEMD_LOG_TARGET=journal
-CREATE_BB_CONTAINER="/usr/lib/systemd/tests/testdata/create-busybox-container"
 
 # shellcheck disable=SC2317
 at_exit() {
@@ -16,6 +18,7 @@ at_exit() {
     [[ -n "${DEV:-}" ]] && rm -f "$DEV"
     [[ -n "${NETNS:-}" ]] && umount "$NETNS" && rm -f "$NETNS"
     [[ -n "${TMPDIR:-}" ]] && rm -fr "$TMPDIR"
+    rm -f /run/systemd/nspawn/*.nspawn
 }
 
 trap at_exit EXIT
@@ -32,7 +35,7 @@ mount --bind /proc/self/ns/net "$NETNS"
 TMPDIR="$(mktemp -d)"
 touch "$TMPDIR/hello"
 OCI="$(mktemp -d /var/lib/machines/testsuite-13.oci-bundle.XXX)"
-"$CREATE_BB_CONTAINER" "$OCI/rootfs"
+create_dummy_container "$OCI/rootfs"
 mkdir -p "$OCI/rootfs/opt/var"
 mkdir -p "$OCI/rootfs/opt/readonly"
 
@@ -52,7 +55,7 @@ cat >"$OCI/config.json" <<EOF
     ]
 }
 EOF
-systemd-nspawn --oci-bundle="$OCI" sh -xec 'mountpoint /root'
+systemd-nspawn --oci-bundle="$OCI" bash -xec 'mountpoint /root'
 
 # And now for something a bit more involved
 # Notes:
@@ -97,7 +100,7 @@ cat >"$OCI/config.json" <<EOF
         ],
         "cwd" : "/root",
         "args" : [
-            "sh",
+            "bash",
             "-xe",
             "/entrypoint.sh"
         ],
@@ -347,7 +350,7 @@ EOF
 # Create a simple "entrypoint" script that validates that the container
 # is created correctly according to the OCI config
 cat >"$OCI/rootfs/entrypoint.sh" <<EOF
-#!/bin/sh -e
+#!/usr/bin/bash -e
 
 # Mounts
 mountpoint /root
@@ -380,4 +383,84 @@ touch /opt/readonly/foo && exit 1
 
 exit 0
 EOF
-systemd-nspawn --oci-bundle="$OCI"
+timeout 30 systemd-nspawn --oci-bundle="$OCI"
+
+# Test a couple of invalid configs
+INVALID_SNIPPETS=(
+    # Invalid object
+    '"foo" : { }'
+    '"process" : { "foo" : [ ] }'
+    # Non-absolute mount
+    '"mounts" : [ { "destination" : "foo", "type" : "tmpfs", "source" : "tmpfs" } ]'
+    # Invalid rlimit
+    '"process" : { "rlimits" : [ { "type" : "RLIMIT_FOO", "soft" : 0, "hard" : 0 } ] }'
+    # rlimit without RLIMIT_ prefix
+    '"process" : { "rlimits" : [ { "type" : "CORE", "soft" : 0, "hard" : 0 } ] }'
+    # Invalid env assignment
+    '"process" : { "env" : [ "foo" ] }'
+    '"process" : { "env" : [ "foo=bar", 1 ] }'
+    # Invalid process args
+    '"process" : { "args" : [ ] }'
+    '"process" : { "args" : [ "" ] }'
+    '"process" : { "args" : [ "foo", 1 ] }'
+    # Invalid capabilities
+    '"process" : { "capabilities" : { "bounding" : [ 1 ] } }'
+    '"process" : { "capabilities" : { "bounding" : [ "FOO_BAR" ] } }'
+    # Unsupported option (without JSON_PERMISSIVE)
+    '"linux" : { "resources" : { "cpu" : { "realtimeRuntime" : 1 } } }'
+    # Invalid namespace
+    '"linux" : { "namespaces" : [ { "type" : "foo" } ] }'
+    # Namespace path for a non-network namespace
+    '"linux" : { "namespaces" : [ { "type" : "user", "path" : "/foo/bar" } ] }'
+    # Duplicate namespace
+    '"linux" : { "namespaces" : [ { "type" : "ipc" }, { "type" : "ipc" } ] }'
+    # Invalid device type
+    '"linux" : { "devices" : [ { "type" : "foo", "path" : "/dev/foo" } ] }'
+    # Invalid cgroups path
+    '"linux" : { "cgroupsPath" : "/foo/bar/baz" }'
+    '"linux" : { "cgroupsPath" : "foo/bar/baz" }'
+    # Invalid sysctl assignments
+    '"linux" : { "sysctl" : { "vm.swappiness" : 60 } }'
+    '"linux" : { "sysctl" : { "foo..bar" : "baz" } }'
+    # Invalid seccomp assignments
+    '"linux" : { "seccomp" : { } }'
+    '"linux" : { "seccomp" : { "defaultAction" : 1 } }'
+    '"linux" : { "seccomp" : { "defaultAction" : "foo" } }'
+    '"linux" : { "seccomp" : { "defaultAction" : "SCMP_ACT_ALLOW", "syscalls" : [ { "action" : "SCMP_ACT_ERRNO", "names" : [ ] } ] } }'
+    # Invalid masked paths
+    '"linux" : { "maskedPaths" : [ "/foo", 1 ] }'
+    '"linux" : { "maskedPaths" : [ "/foo", "bar" ] }'
+    # Invalid read-only paths
+    '"linux" : { "readonlyPaths" : [ "/foo", 1 ] }'
+    '"linux" : { "readonlyPaths" : [ "/foo", "bar" ] }'
+    # Invalid hooks
+    '"hooks" : { "prestart" : [ { "path" : "/bin/sh", "timeout" : 0 } ] }'
+    # Invalid annotations
+    '"annotations" : { "" : "bar" }'
+    '"annotations" : { "foo" : 1 }'
+)
+
+for snippet in "${INVALID_SNIPPETS[@]}"; do
+    : "Snippet: $snippet"
+    cat >"$OCI/config.json" <<EOF
+{
+    "ociVersion" : "1.0.0",
+    "root" : {
+            "path" : "rootfs"
+    },
+    $snippet
+}
+EOF
+    (! systemd-nspawn --oci-bundle="$OCI" sh -c 'echo hello')
+done
+
+# Invalid OCI bundle version
+cat >"$OCI/config.json" <<EOF
+{
+    "ociVersion" : "6.6.6",
+    "root" : {
+            "path" : "rootfs"
+    }
+}
+EOF
+(! systemd-nspawn --oci-bundle="$OCI" sh -c 'echo hello')
index 8f8daf05ccad929fb793062e37b3e1393f423a94..c01361999a0cef1ad060c7bd1205eb497085788e 100755 (executable)
@@ -1,17 +1,39 @@
 #!/usr/bin/env bash
 # SPDX-License-Identifier: LGPL-2.1-or-later
 # shellcheck disable=SC2016
+#
+# Notes on coverage: when collecting coverage we need the $BUILD_DIR present
+# and writable in the container as well. To do this in the least intrusive way,
+# two things are going on in the background (only when built with -Db_coverage=true):
+#   1) the systemd-nspawn@.service is copied to /etc/systemd/system/ with
+#      --bind=$BUILD_DIR appended to the ExecStart= line
+#   2) each create_dummy_container() call also creates an .nspawn file in /run/systemd/nspawn/
+#      with the last fragment from the path used as a name
+#
+# The first change is quite self-contained and applies only to containers run
+# with machinectl. The second one might cause some unexpected side-effects, namely:
+#   - nspawn config (setting) files don't support dropins, so tests that test
+#     the config files might need some tweaking (as seen below with
+#     the $COVERAGE_BUILD_DIR shenanigans) since they overwrite the .nspawn file
+#   - also a note - if /etc/systemd/nspawn/cont-name.nspawn exists, it takes
+#     precedence and /run/systemd/nspawn/cont-name.nspawn won't be read even
+#     if it exists
+#   - in some cases we don't create a test container using create_dummy_container(),
+#     so in that case an explicit call to coverage_create_nspawn_dropin() is needed
 set -eux
 set -o pipefail
 
+# shellcheck source=test/units/util.sh
+. "$(dirname "$0")"/util.sh
+
 export SYSTEMD_LOG_LEVEL=debug
 export SYSTEMD_LOG_TARGET=journal
-CREATE_BB_CONTAINER="/usr/lib/systemd/tests/testdata/create-busybox-container"
 
 at_exit() {
     set +e
 
     mountpoint -q /var/lib/machines && umount /var/lib/machines
+    rm -f /run/systemd/nspawn/*.nspawn
 }
 
 trap at_exit EXIT
@@ -37,7 +59,7 @@ IS_USERNS_SUPPORTED=no
 # with enabled user namespaces support. By setting this value explicitly
 # we can ensure the user namespaces support to be detected correctly.
 sysctl -w user.max_user_namespaces=10000
-if unshare -U sh -c :; then
+if unshare -U bash -c :; then
     IS_USERNS_SUPPORTED=yes
 fi
 
@@ -45,12 +67,12 @@ fi
 mkdir -p /var/lib/machines
 mount -t tmpfs tmpfs /var/lib/machines
 
-testcase_sanity_check() {
+testcase_sanity() {
     local template root image uuid tmpdir
 
     tmpdir="$(mktemp -d)"
     template="$(mktemp -d /tmp/nspawn-template.XXX)"
-    "$CREATE_BB_CONTAINER" "$template"
+    create_dummy_container "$template"
     # Create a simple image from the just created container template
     image="$(mktemp /var/lib/machines/testsuite-13.image-XXX.img)"
     dd if=/dev/zero of="$image" bs=1M count=32
@@ -65,49 +87,50 @@ testcase_sanity_check() {
 
     # --template=
     root="$(mktemp -u -d /var/lib/machines/testsuite-13.sanity.XXX)"
-    (! systemd-nspawn --directory="$root" sh -xec 'echo hello')
+    coverage_create_nspawn_dropin "$root"
+    (! systemd-nspawn --directory="$root" bash -xec 'echo hello')
     # Initialize $root from $template (the $root directory must not exist, hence
     # the `mktemp -u` above)
-    systemd-nspawn --directory="$root" --template="$template" sh -xec 'echo hello'
-    systemd-nspawn --directory="$root" sh -xec 'echo hello; touch /initialized'
+    systemd-nspawn --directory="$root" --template="$template" bash -xec 'echo hello'
+    systemd-nspawn --directory="$root" bash -xec 'echo hello; touch /initialized'
     test -e "$root/initialized"
     # Check if the $root doesn't get re-initialized once it's not empty
-    systemd-nspawn --directory="$root" --template="$template" sh -xec 'echo hello'
+    systemd-nspawn --directory="$root" --template="$template" bash -xec 'echo hello'
     test -e "$root/initialized"
 
-    systemd-nspawn --directory="$root" --ephemeral sh -xec 'touch /ephemeral'
+    systemd-nspawn --directory="$root" --ephemeral bash -xec 'touch /ephemeral'
     test ! -e "$root/ephemeral"
     (! systemd-nspawn --directory="$root" \
                       --bind="${COVERAGE_BUILD_DIR:-$tmpdir}" \
                       --read-only \
-                      sh -xec 'touch /nope')
+                      bash -xec 'touch /nope')
     test ! -e "$root/nope"
-    systemd-nspawn --image="$image" sh -xec 'echo hello'
+    systemd-nspawn --image="$image" bash -xec 'echo hello'
 
     # --volatile=
     touch "$root/usr/has-usr"
     # volatile(=yes): rootfs is tmpfs, /usr/ from the OS tree is mounted read only
     systemd-nspawn --directory="$root"\
                    --volatile \
-                   sh -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope'
+                   bash -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope'
     test ! -e "$root/nope"
     test ! -e "$root/usr/read-only"
     systemd-nspawn --directory="$root"\
                    --volatile=yes \
-                   sh -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope'
+                   bash -xec 'test -e /usr/has-usr; touch /usr/read-only && exit 1; touch /nope'
     test ! -e "$root/nope"
     test ! -e "$root/usr/read-only"
     # volatile=state: rootfs is read-only, /var/ is tmpfs
     systemd-nspawn --directory="$root" \
                    --bind="${COVERAGE_BUILD_DIR:-$tmpdir}" \
                    --volatile=state \
-                   sh -xec 'test -e /usr/has-usr; mountpoint /var; touch /read-only && exit 1; touch /var/nope'
+                   bash -xec 'test -e /usr/has-usr; mountpoint /var; touch /read-only && exit 1; touch /var/nope'
     test ! -e "$root/read-only"
     test ! -e "$root/var/nope"
     # volatile=state: tmpfs overlay is mounted over rootfs
     systemd-nspawn --directory="$root" \
                    --volatile=overlay \
-                   sh -xec 'test -e /usr/has-usr; touch /nope; touch /var/also-nope; touch /usr/nope-too'
+                   bash -xec 'test -e /usr/has-usr; touch /nope; touch /var/also-nope; touch /usr/nope-too'
     test ! -e "$root/nope"
     test ! -e "$root/var/also-nope"
     test ! -e "$root/usr/nope-too"
@@ -115,29 +138,43 @@ testcase_sanity_check() {
     # --machine=, --hostname=
     systemd-nspawn --directory="$root" \
                    --machine="foo-bar.baz" \
-                   sh -xec '[[ $(hostname) == foo-bar.baz ]]'
+                   bash -xec '[[ $(hostname) == foo-bar.baz ]]'
     systemd-nspawn --directory="$root" \
                    --hostname="hello.world.tld" \
-                   sh -xec '[[ $(hostname) == hello.world.tld ]]'
+                   bash -xec '[[ $(hostname) == hello.world.tld ]]'
     systemd-nspawn --directory="$root" \
                    --machine="foo-bar.baz" \
                    --hostname="hello.world.tld" \
-                   sh -xec '[[ $(hostname) == hello.world.tld ]]'
+                   bash -xec '[[ $(hostname) == hello.world.tld ]]'
 
     # --uuid=
     rm -f "$root/etc/machine-id"
     uuid="deadbeef-dead-dead-beef-000000000000"
     systemd-nspawn --directory="$root" \
                    --uuid="$uuid" \
-                   sh -xec "[[ \$container_uuid == $uuid ]]"
+                   bash -xec "[[ \$container_uuid == $uuid ]]"
 
     # --as-pid2
-    systemd-nspawn --directory="$root" sh -xec '[[ $$ -eq 1 ]]'
-    systemd-nspawn --directory="$root" --as-pid2 sh -xec '[[ $$ -eq 2 ]]'
+    systemd-nspawn --directory="$root" bash -xec '[[ $$ -eq 1 ]]'
+    systemd-nspawn --directory="$root" --as-pid2 bash -xec '[[ $$ -eq 2 ]]'
 
     # --user=
-    systemd-nspawn --directory="$root" sh -xec '[[ $USER == root ]]'
-    systemd-nspawn --directory="$root" --user=testuser sh -xec '[[ $USER == testuser ]]'
+    # "Fake" getent passwd's bare minimum, so we don't have to pull it in
+    # with all the DSO shenanigans
+    cat >"$root/bin/getent" <<\EOF
+#!/bin/bash
+
+if [[ $# -eq 0 ]]; then
+    :
+elif [[ $1 == passwd ]]; then
+    echo "testuser:x:1000:1000:testuser:/:/bin/sh"
+elif [[ $1 == initgroups ]]; then
+    echo "testuser"
+fi
+EOF
+    chmod +x "$root/bin/getent"
+    systemd-nspawn --directory="$root" bash -xec '[[ $USER == root ]]'
+    systemd-nspawn --directory="$root" --user=testuser bash -xec '[[ $USER == testuser ]]'
 
     # --settings= + .nspawn files
     mkdir -p /run/systemd/nspawn/
@@ -146,22 +183,22 @@ testcase_sanity_check() {
     systemd-nspawn --directory="$root" \
                    --machine=foo-bar \
                    --settings=yes \
-                   sh -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
+                   bash -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
     systemd-nspawn --directory="$root" \
                    --machine=foo-bar \
                    --uuid="$uuid" \
                    --settings=yes \
-                   sh -xec "[[ \$container_uuid == $uuid ]]"
+                   bash -xec "[[ \$container_uuid == $uuid ]]"
     systemd-nspawn --directory="$root" \
                    --machine=foo-bar \
                    --uuid="$uuid" \
                    --settings=override \
-                   sh -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
+                   bash -xec '[[ $container_uuid == deadbeef-dead-dead-beef-111111111111 ]]'
     systemd-nspawn --directory="$root" \
                    --machine=foo-bar \
                    --uuid="$uuid" \
                    --settings=trusted \
-                   sh -xec "[[ \$container_uuid == $uuid ]]"
+                   bash -xec "[[ \$container_uuid == $uuid ]]"
 
     # Mounts
     mkdir "$tmpdir"/{1,2,3}
@@ -170,35 +207,49 @@ testcase_sanity_check() {
     # --bind=
     systemd-nspawn --directory="$root" \
                    --bind="$tmpdir:/foo" \
-                   sh -xec 'test -e /foo/foo; touch /foo/bar'
+                   bash -xec 'test -e /foo/foo; touch /foo/bar'
     test -e "$tmpdir/bar"
     # --bind-ro=
     systemd-nspawn --directory="$root" \
                    --bind-ro="$tmpdir:/foo" \
-                   sh -xec 'test -e /foo/foo; touch /foo/baz && exit 1; true'
+                   bash -xec 'test -e /foo/foo; touch /foo/baz && exit 1; true'
     # --inaccessible=
     systemd-nspawn --directory="$root" \
                    --inaccessible=/var \
-                   sh -xec 'touch /var/foo && exit 1; true'
+                   bash -xec 'touch /var/foo && exit 1; true'
     # --tmpfs=
     systemd-nspawn --directory="$root" \
                    --tmpfs=/var:rw,nosuid,noexec \
-                   sh -xec 'touch /var/nope'
+                   bash -xec 'touch /var/nope'
     test ! -e "$root/var/nope"
     # --overlay=
     systemd-nspawn --directory="$root" \
                    --overlay="$tmpdir/1:$tmpdir/2:$tmpdir/3:/var" \
-                   sh -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/foo'
+                   bash -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/foo'
     test -e "$tmpdir/3/foo"
     # --overlay-ro=
     systemd-nspawn --directory="$root" \
                    --overlay-ro="$tmpdir/1:$tmpdir/2:$tmpdir/3:/var" \
-                   sh -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/nope && exit 1; true'
+                   bash -xec 'test -e /var/one; test -e /var/two; test -e /var/three; touch /var/nope && exit 1; true'
     test ! -e "$tmpdir/3/nope"
     rm -fr "$tmpdir"
 
+    # --port (sanity only)
+    systemd-nspawn --network-veth --directory="$root" --port=80 --port=90 true
+    systemd-nspawn --network-veth --directory="$root" --port=80:8080 true
+    systemd-nspawn --network-veth --directory="$root" --port=tcp:80 true
+    systemd-nspawn --network-veth --directory="$root" --port=tcp:80:8080 true
+    systemd-nspawn --network-veth --directory="$root" --port=udp:80 true
+    systemd-nspawn --network-veth --directory="$root" --port=udp:80:8080 --port=tcp:80:8080 true
+    (! systemd-nspawn --network-veth --directory="$root" --port= true)
+    (! systemd-nspawn --network-veth --directory="$root" --port=-1 true)
+    (! systemd-nspawn --network-veth --directory="$root" --port=: true)
+    (! systemd-nspawn --network-veth --directory="$root" --port=icmp:80:8080 true)
+    (! systemd-nspawn --network-veth --directory="$root" --port=tcp::8080 true)
+    (! systemd-nspawn --network-veth --directory="$root" --port=8080: true)
+
     # Assorted tests
-    systemd-nspawn --directory="$root" --suppress-sync=yes sh -xec 'echo hello'
+    systemd-nspawn --directory="$root" --suppress-sync=yes bash -xec 'echo hello'
     systemd-nspawn --capability=help
     systemd-nspawn --resolv-conf=help
     systemd-nspawn --timezone=help
@@ -247,22 +298,223 @@ testcase_sanity_check() {
     (! systemd-nspawn --rlimit==)
 }
 
-testcase_check_bind_tmp_path() {
+nspawn_settings_cleanup() {
+    for dev in sd-host-only sd-shared{1,2} sd-macvlan{1,2} sd-ipvlan{1,2}; do
+        ip link del "$dev" || :
+    done
+
+    return 0
+}
+
+testcase_nspawn_settings() {
+    local root container dev private_users
+
+    mkdir -p /run/systemd/nspawn
+    root="$(mktemp -d /var/lib/machines/testsuite-13.nspawn-settings.XXX)"
+    container="$(basename "$root")"
+    create_dummy_container "$root"
+    rm -f "/etc/systemd/nspawn/$container.nspawn"
+    mkdir -p "$root/tmp" "$root"/opt/{tmp,inaccessible,also-inaccessible}
+
+    for dev in sd-host-only sd-shared{1,2} sd-macvlan{1,2} sd-ipvlan{1,2}; do
+        ip link add "$dev" type dummy
+    done
+    udevadm settle
+    ip link
+    trap nspawn_settings_cleanup RETURN
+
+    # Let's start with one huge config to test as much as we can at once
+    cat >"/run/systemd/nspawn/$container.nspawn" <<EOF
+[Exec]
+Boot=no
+Ephemeral=no
+ProcessTwo=no
+Parameters=bash /entrypoint.sh "foo bar" 'bar baz'
+Environment=FOO=bar
+Environment=BAZ="hello world"
+User=root
+WorkingDirectory=/tmp
+Capability=CAP_BLOCK_SUSPEND CAP_BPF CAP_CHOWN
+DropCapability=CAP_AUDIT_CONTROL CAP_AUDIT_WRITE
+AmbientCapability=CAP_BPF CAP_CHOWN
+NoNewPrivileges=no
+MachineID=f28f129b51874b1280a89421ec4b4ad4
+PrivateUsers=no
+NotifyReady=no
+SystemCallFilter=@basic-io @chown
+SystemCallFilter=~ @clock
+LimitNOFILE=1024:2048
+LimitRTPRIO=8:16
+OOMScoreAdjust=32
+CPUAffinity=0,0-5,1-5
+Hostname=nspawn-settings
+ResolvConf=copy-host
+Timezone=delete
+LinkJournal=no
+SuppressSync=no
+
+[Files]
+ReadOnly=no
+Volatile=no
+TemporaryFileSystem=/tmp
+TemporaryFileSystem=/opt/tmp
+Inaccessible=/opt/inaccessible
+Inaccessible=/opt/also-inaccessible
+PrivateUsersOwnership=auto
+Overlay=+/var::/var
+${COVERAGE_BUILD_DIR:+"Bind=$COVERAGE_BUILD_DIR"}
+
+[Network]
+Private=yes
+VirtualEthernet=yes
+VirtualEthernetExtra=my-fancy-veth1
+VirtualEthernetExtra=fancy-veth2:my-fancy-veth2
+Interface=sd-shared1 sd-shared2:sd-shared2
+MACVLAN=sd-macvlan1 sd-macvlan2:my-macvlan2
+IPVLAN=sd-ipvlan1 sd-ipvlan2:my-ipvlan2
+Zone=sd-zone0
+Port=80
+Port=81:8181
+Port=tcp:60
+Port=udp:60:61
+EOF
+    cat >"$root/entrypoint.sh" <<\EOF
+#!/bin/bash -ex
+
+[[ "$1" == "foo bar" ]]
+[[ "$2" == "bar baz" ]]
+
+[[ "$USER" == root ]]
+[[ "$FOO" == bar ]]
+[[ "$BAZ" == "hello world" ]]
+[[ "$PWD" == /tmp ]]
+[[ "$(</etc/machine-id)" == f28f129b51874b1280a89421ec4b4ad4 ]]
+[[ "$(ulimit -S -n)" -eq 1024 ]]
+[[ "$(ulimit -H -n)" -eq 2048 ]]
+[[ "$(ulimit -S -r)" -eq 8 ]]
+[[ "$(ulimit -H -r)" -eq 16 ]]
+[[ "$(</proc/self/oom_score_adj)" -eq 32 ]]
+[[ "$(hostname)" == nspawn-settings ]]
+[[ -e /etc/resolv.conf ]]
+[[ ! -e /etc/localtime ]]
+
+mountpoint /tmp
+touch /tmp/foo
+mountpoint /opt/tmp
+touch /opt/tmp/foo
+touch /opt/inaccessible/foo && exit 1
+touch /opt/also-inaccessible/foo && exit 1
+mountpoint /var
+
+ip link
+ip link | grep host-only && exit 1
+ip link | grep host0@
+ip link | grep my-fancy-veth1@
+ip link | grep my-fancy-veth2@
+ip link | grep sd-shared1
+ip link | grep sd-shared2
+ip link | grep mv-sd-macvlan1@
+ip link | grep my-macvlan2@
+ip link | grep iv-sd-ipvlan1@
+ip link | grep my-ipvlan2@
+EOF
+    timeout 30 systemd-nspawn --directory="$root"
+
+    # And now for stuff that needs to run separately
+    #
+    # Note on the condition below: since our container tree is owned by root,
+    # both "yes" and "identity" private users settings will behave the same
+    # as PrivateUsers=0:65535, which makes BindUser= fail as the UID already
+    # exists there, so skip setting it in such case
+    for private_users in "131072:65536" yes identity pick; do
+        cat >"/run/systemd/nspawn/$container.nspawn" <<EOF
+[Exec]
+Hostname=private-users
+PrivateUsers=$private_users
+
+[Files]
+PrivateUsersOwnership=auto
+BindUser=
+$([[ "$private_users" =~ (yes|identity) ]] || echo "BindUser=testuser")
+${COVERAGE_BUILD_DIR:+"Bind=$COVERAGE_BUILD_DIR"}
+EOF
+        cat "/run/systemd/nspawn/$container.nspawn"
+        chown -R root:root "$root"
+        systemd-nspawn --directory="$root" bash -xec '[[ "$(hostname)" == private-users ]]'
+    done
+
+    rm -fr "$root" "/run/systemd/nspawn/$container.nspawn"
+}
+
+bind_user_cleanup() {
+    userdel --force --remove nspawn-bind-user-1
+    userdel --force --remove nspawn-bind-user-2
+}
+
+testcase_bind_user() {
+    local root
+
+    root="$(mktemp -d /var/lib/machines/testsuite-13.bind-user.XXX)"
+    create_dummy_container "$root"
+    useradd --create-home --user-group nspawn-bind-user-1
+    useradd --create-home --user-group nspawn-bind-user-2
+    trap bind_user_cleanup RETURN
+    touch /home/nspawn-bind-user-1/foo
+    touch /home/nspawn-bind-user-2/bar
+    # Add a couple of POSIX ACLs to test the patch-uid stuff
+    mkdir -p "$root/opt"
+    setfacl -R -m 'd:u:nspawn-bind-user-1:rwX' -m 'u:nspawn-bind-user-1:rwX' "$root/opt"
+    setfacl -R -m 'd:g:nspawn-bind-user-1:rwX' -m 'g:nspawn-bind-user-1:rwX' "$root/opt"
+
+    systemd-nspawn --directory="$root" \
+                   --private-users=pick \
+                   --bind-user=nspawn-bind-user-1 \
+                   bash -xec 'test -e /run/host/home/nspawn-bind-user-1/foo'
+
+    systemd-nspawn --directory="$root" \
+                   --private-users=pick \
+                   --private-users-ownership=chown \
+                   --bind-user=nspawn-bind-user-1 \
+                   --bind-user=nspawn-bind-user-2 \
+                   bash -xec 'test -e /run/host/home/nspawn-bind-user-1/foo; test -e /run/host/home/nspawn-bind-user-2/bar'
+    chown -R root:root "$root"
+
+    # User/group name collision
+    echo "nspawn-bind-user-2:x:1000:1000:nspawn-bind-user-2:/home/nspawn-bind-user-2:/bin/bash" >"$root/etc/passwd"
+    (! systemd-nspawn --directory="$root" \
+                      --private-users=pick \
+                      --bind-user=nspawn-bind-user-1 \
+                      --bind-user=nspawn-bind-user-2 \
+                      true)
+    rm -f "$root/etc/passwd"
+
+    echo "nspawn-bind-user-2:x:1000:" >"$root/etc/group"
+    (! systemd-nspawn --directory="$root" \
+                      --private-users=pick \
+                      --bind-user=nspawn-bind-user-1 \
+                      --bind-user=nspawn-bind-user-2 \
+                      true)
+    rm -f "$root/etc/group"
+
+    rm -fr "$root"
+}
+
+testcase_bind_tmp_path() {
     # https://github.com/systemd/systemd/issues/4789
     local root
 
     root="$(mktemp -d /var/lib/machines/testsuite-13.bind-tmp-path.XXX)"
-    "$CREATE_BB_CONTAINER" "$root"
+    create_dummy_container "$root"
     : >/tmp/bind
     systemd-nspawn --register=no \
                    --directory="$root" \
                    --bind=/tmp/bind \
-                   /bin/sh -c 'test -e /tmp/bind'
+                   bash -c 'test -e /tmp/bind'
 
     rm -fr "$root" /tmp/bind
 }
 
-testcase_check_norbind() {
+testcase_norbind() {
     # https://github.com/systemd/systemd/issues/13170
     local root
 
@@ -271,25 +523,25 @@ testcase_check_norbind() {
     echo -n "outer" >/tmp/binddir/subdir/file
     mount -t tmpfs tmpfs /tmp/binddir/subdir
     echo -n "inner" >/tmp/binddir/subdir/file
-    "$CREATE_BB_CONTAINER" "$root"
+    create_dummy_container "$root"
 
     systemd-nspawn --register=no \
                    --directory="$root" \
                    --bind=/tmp/binddir:/mnt:norbind \
-                   /bin/sh -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; return 1; fi'
+                   bash -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; exit 1; fi'
 
     umount /tmp/binddir/subdir
     rm -fr "$root" /tmp/binddir/
 }
 
-check_rootidmap_cleanup() {
+rootidmap_cleanup() {
     local dir="${1:?}"
 
     mountpoint -q "$dir/bind" && umount "$dir/bind"
     rm -fr "$dir"
 }
 
-testcase_check_rootidmap() {
+testcase_rootidmap() {
     local root cmd permissions
     local owner=1000
 
@@ -299,18 +551,18 @@ testcase_check_rootidmap() {
     dd if=/dev/zero of=/tmp/rootidmap/ext4.img bs=4k count=2048
     mkfs.ext4 /tmp/rootidmap/ext4.img
     mount /tmp/rootidmap/ext4.img /tmp/rootidmap/bind
-    trap "check_rootidmap_cleanup /tmp/rootidmap/" RETURN
+    trap "rootidmap_cleanup /tmp/rootidmap/" RETURN
 
     touch /tmp/rootidmap/bind/file
     chown -R "$owner:$owner" /tmp/rootidmap/bind
 
-    "$CREATE_BB_CONTAINER" "$root"
+    create_dummy_container "$root"
     cmd='PERMISSIONS=$(stat -c "%u:%g" /mnt/file); if [[ $PERMISSIONS != "0:0" ]]; then echo "*** wrong permissions: $PERMISSIONS"; return 1; fi; touch /mnt/other_file'
     if ! SYSTEMD_LOG_TARGET=console \
             systemd-nspawn --register=no \
                            --directory="$root" \
                            --bind=/tmp/rootidmap/bind:/mnt:rootidmap \
-                           /bin/sh -c "$cmd" |& tee nspawn.out; then
+                           bash -c "$cmd" |& tee nspawn.out; then
         if grep -q "Failed to map ids for bind mount.*: Function not implemented" nspawn.out; then
             echo "idmapped mounts are not supported, skipping the test..."
             return 0
@@ -326,23 +578,28 @@ testcase_check_rootidmap() {
     fi
 }
 
-testcase_check_notification_socket() {
+testcase_notification_socket() {
     # https://github.com/systemd/systemd/issues/4944
-    local cmd='echo a | $(busybox which nc) -U -u -w 1 /run/host/notify'
+    local root
+    local cmd='echo a | nc -U -u -w 1 /run/host/notify'
+
+    root="$(mktemp -d /var/lib/machines/testsuite-13.check_notification_socket.XXX)"
+    create_dummy_container "$root"
 
-    # /testsuite-13.nc-container is prepared by test.sh
-    systemd-nspawn --register=no --directory=/testsuite-13.nc-container /bin/sh -x -c "$cmd"
-    systemd-nspawn --register=no --directory=/testsuite-13.nc-container -U /bin/sh -x -c "$cmd"
+    systemd-nspawn --register=no --directory="$root" bash -x -c "$cmd"
+    systemd-nspawn --register=no --directory="$root" -U bash -x -c "$cmd"
+
+    rm -fr "$root"
 }
 
-testcase_check_os_release() {
+testcase_os_release() {
     local root entrypoint os_release_source
 
-    root="$(mktemp -d /var/lib/machines/testsuite-13.check-os-release.XXX)"
-    "$CREATE_BB_CONTAINER" "$root"
+    root="$(mktemp -d /var/lib/machines/testsuite-13.os-release.XXX)"
+    create_dummy_container "$root"
     entrypoint="$root/entrypoint.sh"
     cat >"$entrypoint" <<\EOF
-#!/bin/sh -ex
+#!/usr/bin/bash -ex
 
 . /tmp/os-release
 [[ -n "${ID:-}" && "$ID" != "$container_host_id" ]] && exit 1
@@ -376,20 +633,20 @@ EOF
     rm -fr "$root"
 }
 
-testcase_check_machinectl_bind() {
+testcase_machinectl_bind() {
     local service_path service_name root container_name ec
-    local cmd='for i in $(seq 1 20); do if test -f /tmp/marker; then exit 0; fi; usleep 500000; done; exit 1;'
+    local cmd='for i in $(seq 1 20); do if test -f /tmp/marker; then exit 0; fi; sleep .5; done; exit 1;'
 
-    root="$(mktemp -d /var/lib/machines/testsuite-13.check-machinectl-bind.XXX)"
-    "$CREATE_BB_CONTAINER" "$root"
-    container_name="${root##*/}"
+    root="$(mktemp -d /var/lib/machines/testsuite-13.machinectl-bind.XXX)"
+    create_dummy_container "$root"
+    container_name="$(basename "$root")"
 
     service_path="$(mktemp /run/systemd/system/nspawn-machinectl-bind-XXX.service)"
     service_name="${service_path##*/}"
     cat >"$service_path" <<EOF
 [Service]
 Type=notify
-ExecStart=systemd-nspawn --directory="$root" --notify-ready=no /bin/sh -xec "$cmd"
+ExecStart=systemd-nspawn --directory="$root" --notify-ready=no /usr/bin/bash -xec "$cmd"
 EOF
 
     systemctl daemon-reload
@@ -399,13 +656,14 @@ EOF
 
     timeout 10 bash -c "while [[ '\$(systemctl show -P SubState $service_name)' == running ]]; do sleep .2; done"
     ec="$(systemctl show -P ExecMainStatus "$service_name")"
+    systemctl stop "$service_name"
 
     rm -fr "$root" "$service_path"
 
     return "$ec"
 }
 
-testcase_check_selinux() {
+testcase_selinux() {
     # Basic test coverage to avoid issues like https://github.com/systemd/systemd/issues/19976
     if ! command -v selinuxenabled >/dev/null || ! selinuxenabled; then
         echo >&2 "SELinux is not enabled, skipping SELinux-related tests"
@@ -414,8 +672,8 @@ testcase_check_selinux() {
 
     local root
 
-    root="$(mktemp -d /var/lib/machines/testsuite-13.check-selinux.XXX)"
-    "$CREATE_BB_CONTAINER" "$root"
+    root="$(mktemp -d /var/lib/machines/testsuite-13.selinux.XXX)"
+    create_dummy_container "$root"
     chcon -R -t container_t "$root"
 
     systemd-nspawn --register=no \
@@ -427,17 +685,19 @@ testcase_check_selinux() {
     rm -fr "$root"
 }
 
-testcase_check_ephemeral_config() {
+testcase_ephemeral_config() {
     # https://github.com/systemd/systemd/issues/13297
     local root container_name
 
-    root="$(mktemp -d /var/lib/machines/testsuite-13.check-ephemeral-config.XXX)"
-    "$CREATE_BB_CONTAINER" "$root"
-    container_name="${root##*/}"
+    root="$(mktemp -d /var/lib/machines/testsuite-13.ephemeral-config.XXX)"
+    create_dummy_container "$root"
+    container_name="$(basename "$root")"
 
     mkdir -p /run/systemd/nspawn/
+    rm -f "/etc/systemd/nspawn/$container_name.nspawn"
     cat >"/run/systemd/nspawn/$container_name.nspawn" <<EOF
 [Files]
+${COVERAGE_BUILD_DIR:+"Bind=$COVERAGE_BUILD_DIR"}
 BindReadOnly=/tmp/ephemeral-config
 EOF
     touch /tmp/ephemeral-config
@@ -445,15 +705,15 @@ EOF
     systemd-nspawn --register=no \
                    --directory="$root" \
                    --ephemeral \
-                   /bin/sh -x -c "test -f /tmp/ephemeral-config"
+                   bash -x -c "test -f /tmp/ephemeral-config"
 
     systemd-nspawn --register=no \
                    --directory="$root" \
                    --ephemeral \
                    --machine=foobar \
-                   /bin/sh -x -c "! test -f /tmp/ephemeral-config"
+                   bash -x -c "! test -f /tmp/ephemeral-config"
 
-    rm -fr "$root" "/run/systemd/nspawn/$container_name"
+    rm -fr "$root" "/run/systemd/nspawn/$container_name.nspawn"
 }
 
 matrix_run_one() {
@@ -473,7 +733,7 @@ matrix_run_one() {
     fi
 
     root="$(mktemp -d "/var/lib/machines/testsuite-13.unified-$1-cgns-$2-api-vfs-writable-$3.XXX")"
-    "$CREATE_BB_CONTAINER" "$root"
+    create_dummy_container "$root"
 
     SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$cgroupsv2" SYSTEMD_NSPAWN_USE_CGNS="$use_cgns" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$api_vfs_writable" \
         systemd-nspawn --register=no \
@@ -548,7 +808,7 @@ matrix_run_one() {
         systemd-nspawn --register=no \
                        --directory="$root" \
                        --network-namespace-path=/run/netns/nspawn_test \
-                       /bin/ip a | grep -v -E '^1: lo.*UP'
+                       ip a | grep -v -E '^1: lo.*UP'
     ip netns del nspawn_test
 
     rm -fr "$root"
index c63586e1a2b27a6dda1f699045d5301d0b48af29..8dc4d9123c7eef29aa38271d4f388ca6e15e980b 100755 (executable)
@@ -27,7 +27,7 @@ echo "MARKER_RUNTIME" >/run/testsuite-23-marker-runtime
 
 systemctl bind --mkdir testsuite-23-namespaced.service /run/testsuite-23-marker-runtime /tmp/testfile-marker-runtime
 
-timeout 10 sh -xec 'while [[ "$(systemctl show -P SubState testsuite-23-namespaced.service)" == running ]]; do sleep .5; done'
+timeout 10 bash -xec 'while [[ "$(systemctl show -P SubState testsuite-23-namespaced.service)" == running ]]; do sleep .5; done'
 systemctl is-active testsuite-23-namespaced.service
 
 # Now test that systemctl bind fails when attempted on a non-namespaced unit
@@ -35,5 +35,5 @@ systemctl start testsuite-23-non-namespaced.service
 
 (! systemctl bind --mkdir testsuite-49-non-namespaced.service /run/testsuite-23-marker-runtime /tmp/testfile-marker-runtime)
 
-timeout 10 sh -xec 'while [[ "$(systemctl show -P SubState testsuite-23-non-namespaced.service)" == running ]]; do sleep .5; done'
+timeout 10 bash -xec 'while [[ "$(systemctl show -P SubState testsuite-23-non-namespaced.service)" == running ]]; do sleep .5; done'
 (! systemctl is-active testsuite-23-non-namespaced.service)
index d151c39965d4072c39b33de320c3452869b080b6..fdba709734eb25b87bf9dac6626a29948bb2c00a 100755 (executable)
@@ -80,3 +80,33 @@ runas() {
     shift
     XDG_RUNTIME_DIR=/run/user/"$(id -u "$userid")" setpriv --reuid="$userid" --init-groups "$@"
 }
+
+coverage_create_nspawn_dropin() {
+    # If we're collecting coverage, bind mount the $BUILD_DIR into the nspawn
+    # container so gcov can update the counters. This is mostly for standalone
+    # containers, as machinectl stuff is handled by overriding the systemd-nspawn@.service
+    # (see test/test-functions:install_systemd())
+    local root="${1:?}"
+    local container
+
+    if [[ -z "${COVERAGE_BUILD_DIR:-}" ]]; then
+        return 0
+    fi
+
+    container="$(basename "$root")"
+    mkdir -p "/run/systemd/nspawn"
+    echo -ne "[Files]\nBind=$COVERAGE_BUILD_DIR\n" >"/run/systemd/nspawn/${container:?}.nspawn"
+}
+
+create_dummy_container() {
+    local root="${1:?}"
+
+    if [[ ! -d /testsuite-13-container-template ]]; then
+        echo >&2 "Missing container template, probably not running in TEST-13-NSPAWN?"
+        exit 1
+    fi
+
+    mkdir -p "$root"
+    cp -a /testsuite-13-container-template/* "$root"
+    coverage_create_nspawn_dropin "$root"
+}
index 47cd0e755589016b5449a89d6dbb959f08350c17..70eb6b7bc3c4d133b1928be224e2b67e04d5dd13 100644 (file)
 Description=Userspace Out-Of-Memory (OOM) Killer Socket
 Documentation=man:systemd-oomd.service(8)
 DefaultDependencies=no
-Before=sockets.target
+Before=sockets.target shutdown.target
+Conflicts=shutdown.target
+ConditionControlGroupController=v2
+ConditionControlGroupController=memory
+ConditionPathExists=/proc/pressure/cpu
+ConditionPathExists=/proc/pressure/io
+ConditionPathExists=/proc/pressure/memory
 
 [Socket]
 ListenStream=/run/systemd/oom/io.system.ManagedOOM