]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #27519 from yuwata/journalctl-fixes
authorLuca Boccassi <bluca@debian.org>
Wed, 31 May 2023 10:05:54 +0000 (11:05 +0100)
committerGitHub <noreply@github.com>
Wed, 31 May 2023 10:05:54 +0000 (11:05 +0100)
journalctl: several fixes and cleanups for --follow

44 files changed:
TODO
man/integritytab.xml
man/repart.d.xml
man/systemd-analyze.xml
man/systemd-gpt-auto-generator.xml
man/tmpfiles.d.xml
man/udevadm.xml
meson.build
meson_options.txt
mkosi.presets/00-base/mkosi.build
mkosi.presets/00-base/mkosi.conf.d/10-opensuse.conf
src/basic/syscall-list.txt
src/basic/syscalls-alpha.txt
src/basic/syscalls-arc.txt
src/basic/syscalls-arm.txt
src/basic/syscalls-arm64.txt
src/basic/syscalls-i386.txt
src/basic/syscalls-ia64.txt
src/basic/syscalls-loongarch64.txt
src/basic/syscalls-m68k.txt
src/basic/syscalls-mips64.txt
src/basic/syscalls-mips64n32.txt
src/basic/syscalls-mipso32.txt
src/basic/syscalls-parisc.txt
src/basic/syscalls-powerpc.txt
src/basic/syscalls-powerpc64.txt
src/basic/syscalls-riscv32.txt
src/basic/syscalls-riscv64.txt
src/basic/syscalls-s390.txt
src/basic/syscalls-s390x.txt
src/basic/syscalls-sparc.txt
src/basic/syscalls-x86_64.txt
src/gpt-auto-generator/gpt-auto-generator.c
src/home/homed-home.c
src/integritysetup/integrity-util.c
src/partition/repart.c
src/resolve/resolvectl.c
src/shared/dissect-image.c
src/shared/gpt.c
src/shared/loop-util.c
test/README.testsuite
test/test-fstab-generator.sh
test/units/testsuite-58.sh
tmpfiles.d/credstore.conf

diff --git a/TODO b/TODO
index f37579e2cae7deb48f7494d44d985a701e7d963e..79643583dd0674a1ad3d7c29c56dac984d168004 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1920,6 +1920,8 @@ Features:
 * dbus: when a unit failed to load (i.e. is in UNIT_ERROR state), we
   should be able to safely try another attempt when the bus call LoadUnit() is invoked.
 
+* document org.freedesktop.MemoryAllocation1
+
 * maybe do not install getty@tty1.service symlink in /etc but in /usr?
 
 * print a nicer explanation if people use variable/specifier expansion in ExecStart= for the first word
index 44f0a559290298dcdd94bd3bb1e81a6d4951ca46..44da039ddecf9dce658a9d5c8ec9612b5e2c00a1 100644 (file)
         </para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>no-journal</option></term>
+
+        <listitem><para>
+        Disable the journal. Corresponds to the "direct writes" mode documented in
+        <ulink url="https://docs.kernel.org/admin-guide/device-mapper/dm-integrity.html">the dm-integrity documentation</ulink>.
+        Note that without a journal, if there is a crash, it is possible that the integrity tags and data will not match. If used, the journal-*
+        options below will have no effect if passed.
+        </para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>journal-watermark=[0..100]%</option></term>
 
index d272d112da6140b6311f0ecb14c4b73da51e650e..8fe2fc3199fd0b3bb1f3f0a72901dc6ff1372bda 100644 (file)
 
       <varlistentry>
         <term><varname>ExcludeFiles=</varname></term>
+        <term><varname>ExcludeFilesTarget=</varname></term>
 
         <listitem><para>Takes an absolute file system path referring to a source file or directory on the
         host. This setting may be used to exclude files or directories from the host from being copied into
         contents are excluded but not the directory itself. If the path is a directory and does not end with
         <literal>/</literal>, both the directory and its contents are excluded.</para>
 
+        <para><varname>ExcludeFilesTarget=</varname> is like <varname>ExcludeFiles=</varname> except that
+        instead of excluding the path on the host from being copied into the partition, we exclude any files
+        and directories from being copied into the given path in the partition.</para>
+
         <para>When
         <citerefentry><refentrytitle>systemd-repart</refentrytitle><manvolnum>8</manvolnum></citerefentry>
         is invoked with the <option>--image=</option> or <option>--root=</option> command line switches the
index e0eba1cf64401af087dde2659909814239cbc231..4aa73d91f7464d4b9ac6d4520010b02e7cca0ff3 100644 (file)
@@ -304,10 +304,13 @@ Timestamp units-load-finish: Thu 2019-03-14 23:28:07 CET
       <title><command>systemd-analyze malloc [<replaceable>D-Bus service</replaceable>…]</command></title>
 
       <para>This command can be used to request the output of the internal memory state (as returned by
-      <citerefentry><refentrytitle>malloc_info</refentrytitle><manvolnum>3</manvolnum></citerefentry>) of
-      a D-Bus service implementing this pattern. If no service is specified, the command will be sent to
+      <citerefentry project='man-pages'><refentrytitle>malloc_info</refentrytitle><manvolnum>3</manvolnum></citerefentry>)
+      of a D-Bus service. If no service is specified, the query will be sent to
       <filename>org.freedesktop.systemd1</filename> (the system or user service manager). The output format
-      is subject to change without notice and should not be parsed by applications.</para>
+      is not guaranteed to be stable and should not be parsed by applications.</para>
+
+      <para>The service must implement the <filename>org.freedesktop.MemoryAllocation1</filename> interface.
+      In the systemd suite, it is currently only implemented by the manager.</para>
     </refsect2>
 
     <refsect2>
@@ -734,7 +737,7 @@ $ systemd-analyze verify /tmp/source
 Failed to prepare filename /tmp/source: Invalid argument
 
 $ systemd-analyze verify /tmp/source:alias.service
-/tmp/systemd-analyze-XXXXXX/alias.service:7: Unknown key name 'MysteryKey' in section 'Service', ignoring.
+alias.service:7: Unknown key name 'MysteryKey' in section 'Service', ignoring.
         </programlisting>
       </example>
 
@@ -794,9 +797,10 @@ $ systemd-analyze verify /tmp/source:alias.service
       Packaging Metadata</ulink> documentation for more information.</para>
 
       <example>
-        <title>Table output</title>
+        <title>Print information about a core file as JSON</title>
 
-        <programlisting>$ systemd-analyze inspect-elf --json=pretty /tmp/core.fsverity.1000.f77dac5dc161402aa44e15b7dd9dcf97.58561.1637106137000000
+        <programlisting>$ systemd-analyze inspect-elf --json=pretty \
+        core.fsverity.1000.f77dac5dc161402aa44e15b7dd9dcf97.58561.1637106137000000
 {
         "elfType" : "coredump",
         "elfArchitecture" : "AMD x86-64",
index 100c5c259e8eb48f2d58e185297242458b63ca2f..e176d32d9c3197c5deb51742798c16d6a25c3ea1 100644 (file)
     <title>Description</title>
 
     <para><filename>systemd-gpt-auto-generator</filename> is a unit generator that automatically discovers
-    root, <filename>/home/</filename>, <filename>/srv/</filename>, <filename>/var/</filename>,
-    <filename>/var/tmp/</filename>, the EFI System Partition, the Extended Boot Loader Partition and swap
+    the root partition, <filename>/home/</filename>, <filename>/srv/</filename>, <filename>/var/</filename>,
+    <filename>/var/tmp/</filename>, the EFI System Partition, the Extended Boot Loader Partition, and swap
     partitions and creates mount and swap units for them, based on the partition type GUIDs of GUID partition
-    tables (GPT), see <ulink url="https://uefi.org/specifications">UEFI Specification</ulink>, chapter 5. It
-    implements the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions
-    Specification</ulink>. Note that this generator has no effect on non-GPT systems, and on specific mount
-    points that are directories already containing files. Also, on systems where the units are explicitly
-    configured (for example, listed in <citerefentry
-    project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>), the
-    units this generator creates are overridden, but additional implicit dependencies might be
-    created.</para>
+    tables (GPT). See <ulink url="https://uefi.org/specifications">UEFI Specification</ulink>, chapter 5 for
+    more details. It implements the <ulink
+    url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable
+    Partitions Specification</ulink>.</para>
+
+    <para>Note that this generator has no effect on non-GPT systems. It will also not create mount point
+    configuration for directories which already contain files or if the mount point is explicitly configured
+    in <citerefentry
+    project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>. If
+    the units this generator creates are overridden, for example by units in directories with higher
+    precedence, drop-ins and additional dependencies created by this generator might still be used.</para>
 
     <para>This generator will only look for the root partition on the same physical disk where the EFI System
     Partition (ESP) is located. Note that support from the boot loader is required: the EFI variable
     <varname>LoaderDevicePartUUID</varname> of the <constant>4a67b082-0a4c-41cf-b6c7-440b29bb8c4f</constant>
-    vendor UUID is used to determine from which partition, and hence the disk from which the system was
-    booted. If the boot loader does not set this variable, this generator will not be able to autodetect the
-    root partition. See the <ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader
-    Interface</ulink> for details.</para>
+    vendor UUID is used to determine from which partition, and hence the disk, from which the system was
+    booted. If the boot loader does not set this variable, this generator will not be able to detect the root
+    partition. See the <ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>
+    for details.</para>
 
     <para>Similarly, this generator will only look for the other partitions on the same physical disk as the
     root partition. In this case, boot loader support is not required. These partitions will not be searched
     listed in <filename>/etc/crypttab</filename> with a different device mapper device name.</para>
 
     <para>When systemd is running in the initrd the <filename>/</filename> partition may be encrypted in LUKS
-      format as well. In this case, a device mapper device is set up under the name <filename>/dev/mapper/root</filename>,
-      and a <filename>sysroot.mount</filename> is set up that mounts the device under <filename>/sysroot</filename>.
-      For more information, see <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+    format as well. In this case, a device mapper device is set up under the name
+    <filename>/dev/mapper/root</filename>, and a <filename>sysroot.mount</filename> is set up that mounts the
+    device under <filename>/sysroot</filename>. For more information, see
+    <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
     </para>
 
     <para>The root partition can be specified by symlinking <filename>/run/systemd/volatile-root</filename>
     replaced by some form of volatile file system (overlayfs).
     </para>
 
-    <para>Mount and automount units for the EFI System Partition (ESP) are generated on EFI systems. The ESP
-    is mounted to <filename>/boot/</filename> (except if an Extended Boot Loader partition exists, see
-    below), unless a mount point directory <filename>/efi/</filename> exists, in which case it is mounted
-    there. Since this generator creates an automount unit, the mount will only be activated on-demand, when
-    accessed. On systems where <filename>/boot/</filename> (or <filename>/efi/</filename> if it exists) is an
-    explicitly configured mount (for example, listed in <citerefentry
-    project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>) or where
-    the <filename>/boot/</filename> (or <filename>/efi/</filename>) mount point is non-empty, no mount units
-    are generated.</para>
-
-    <para>If the disk contains an Extended Boot Loader partition, as defined in the <ulink
-    url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink>, it is made
-    available at <filename>/boot/</filename> (by means of an automount point, similar to the ESP, see
-    above). If both an EFI System Partition and an Extended Boot Loader partition exist the latter is
-    preferably mounted to <filename>/boot/</filename>. Make sure to create both <filename>/efi/</filename>
-    and <filename>/boot/</filename> to ensure both partitions are mounted.</para>
+    <para>Mount and automount units for the EFI System Partition (ESP) and Extended Boot Loader Partition
+    (XBOOTLDR) are generated on EFI systems. If the disk contains an XBOOTLDR partition, as defined in the
+    <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader
+    Specification</ulink>, it is made available at <filename>/boot/</filename>. This generator creates an
+    automount unit; the mount will only be activated on-demand when accessed. The mount point will be created
+    if necessary.</para>
+
+    <para>The ESP is mounted to <filename>/boot/</filename> if that directory exists and is not used for
+    XBOOTLDR, and otherwise to <filename>/efi/</filename>. Same as for <filename>/boot/</filename>, an
+    automount unit is used. The mount point will be created if necessary.</para>
+
+    <para>No configuration is created for mount points that are configured in <citerefentry
+    project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry> or when
+    the target directory contains files.</para>
 
     <para>When using this generator in conjunction with btrfs file
     systems, make sure to set the correct default subvolumes on them,
index f691eef25d8549d6af1c25d7072ea3fb9044752b..ef0bb1f7f89bc4e3dad9e20afe26713128a03954 100644 (file)
@@ -206,11 +206,11 @@ L     /tmp/foobar -    -    -     -   /dev/null</programlisting>
         <varlistentry>
           <term><varname>e</varname></term>
           <listitem><para>Adjust the mode and ownership of existing directories and remove their contents
-          based on age.
-          Lines of this type accept shell-style globs in place of normal path names. Contents of the
-          directories are subject to time-based cleanup if the age argument is specified. If the age argument
-          is <literal>0</literal>, contents will be unconditionally deleted every time
-          <command>systemd-tmpfiles --clean</command> is run.</para>
+          based on age. Lines of this type accept shell-style globs in place of normal path names. Contents
+          of the directories are subject to time-based cleanup if the age argument is specified. If the age
+          argument is <literal>0</literal>, contents will be unconditionally deleted every time
+          <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+          <option>--clean</option> is run.</para>
 
           <para>For this entry to be useful, at least one of the mode, user, group, or age arguments must be
           specified, since otherwise this entry has no effect. As an exception, an entry with no effect may
@@ -444,17 +444,18 @@ L     /tmp/foobar -    -    -     -   /dev/null</programlisting>
         <varlistentry>
           <term><varname>a</varname></term>
           <term><varname>a+</varname></term>
-          <listitem><para>Set POSIX ACLs (access control lists), see <citerefentry
-          project='man-pages'><refentrytitle>acl</refentrytitle>
-          <manvolnum>5</manvolnum></citerefentry>. Additionally, if 'X' is used, the execute bit is set only
-          if the file is a directory or already has execute permission for some user, as mentioned in
+          <listitem><para>Set POSIX ACLs (access control lists), see
+          <citerefentry project='man-pages'><refentrytitle>acl</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+          Additionally, if 'X' is used, the execute bit is set only if the file is a directory or already has
+          execute permission for some user, as mentioned in
           <citerefentry project='man-pages'><refentrytitle>setfacl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
           If suffixed with <varname>+</varname>, the specified entries will be added to the existing set.
-          <command>systemd-tmpfiles</command> will automatically add the required base entries for user
-          and group based on the access mode of the file, unless base entries already exist or are explicitly
-          specified. The mask will be added if not specified explicitly or already present. Lines of this type
-          accept shell-style globs in place of normal path names. This can be useful for allowing additional
-          access to certain files. Does not follow symlinks.</para></listitem>
+          <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+          will automatically add the required base entries for user and group based on the access mode of the
+          file, unless base entries already exist or are explicitly specified. The mask will be added if not
+          specified explicitly or already present. Lines of this type accept shell-style globs in place of
+          normal path names. This can be useful for allowing additional access to certain files. Does not
+          follow symlinks.</para></listitem>
         </varlistentry>
 
         <varlistentry>
@@ -472,8 +473,10 @@ L     /tmp/foobar -    -    -     -   /dev/null</programlisting>
 
       <para>If the exclamation mark (<literal>!</literal>) is used, this line is only safe to execute during
       boot, and can break a running system. Lines without the exclamation mark are presumed to be safe to
-      execute at any time, e.g. on package upgrades. <command>systemd-tmpfiles</command> will take lines with
-      an exclamation mark only into consideration, if the <option>--boot</option> option is given.</para>
+      execute at any time, e.g. on package upgrades.
+      <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      will take lines with an exclamation mark only into consideration, if the <option>--boot</option> option
+      is given.</para>
 
       <para>For example:
       <programlisting># Make sure these are created by default so that nobody else can
@@ -559,10 +562,12 @@ w- /proc/sys/vm/swappiness - - - - 10</programlisting></para>
 
       <para>The user and group to use for this file or directory. This may either be a numeric ID or a
       user/group name. If omitted or when set to <literal>-</literal>, the user and group of the user who
-      invokes <command>systemd-tmpfiles</command> is used. For <varname>z</varname> and <varname>Z</varname>
-      lines, when omitted or when set to <literal>-</literal>, the file ownership will not be modified. These
-      parameters are ignored for <varname>x</varname>, <varname>r</varname>, <varname>R</varname>,
-      <varname>L</varname>, <varname>t</varname>, and <varname>a</varname> lines.</para>
+      invokes
+      <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry> is
+      used. For <varname>z</varname> and <varname>Z</varname> lines, when omitted or when set to
+      <literal>-</literal>, the file ownership will not be modified. These parameters are ignored for
+      <varname>x</varname>, <varname>r</varname>, <varname>R</varname>, <varname>L</varname>,
+      <varname>t</varname>, and <varname>a</varname> lines.</para>
 
       <para>This field should generally only reference system users/groups, i.e. users/groups that are
       guaranteed to be resolvable during early boot. If this field references users/groups that only become
index 1e2202aa66d6ec9501c172df83681569c0b72457..a1c977341306d8a6d9ea6669d1c10e2c9c1be92e 100644 (file)
       …
       </title>
 
-      <para>Verify syntactic and semantic correctness of udev rules files.</para>
+      <para>Verify syntactic, semantic, and stylistic correctness of udev rules files.</para>
 
       <para>Positional arguments could be used to specify one or more files to check.
       If no files are specified, the udev rules are read from the files located in
       the same udev/rules.d directories that are processed by the udev daemon.</para>
 
-      <para>The exit status is <constant>0</constant> if all specified udev rules files
-      are syntactically and semantically correct, and a non-zero error code otherwise.</para>
+      <para>The exit status is <constant>0</constant> if all specified udev
+      rules files are syntactically, semantically, and stylistically correct,
+      and a non-zero error code otherwise.</para>
 
       <variablelist>
         <varlistentry>
index 97622b6d9731f2ccda89201357815847664709b1..92b9a6ce5b23f7ff086a2d0354134e478131bb83 100644 (file)
@@ -1134,10 +1134,10 @@ else
                         clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus', check : false).returncode() == 0
                 endif
         elif bpf_compiler == 'gcc'
-                warning('GCC BPF Compiler support is experimental and not recommended.')
                 bpf_gcc = find_program('bpf-gcc',
+                                       'bpf-none-gcc',
                                        required : true,
-                                       version : '>= 12.1.0')
+                                       version : '>= 13.1.0')
                 bpf_gcc_found = bpf_gcc.found()
         endif
 
@@ -3851,7 +3851,9 @@ public_programs += executable(
 # there.
 meson.add_install_script('sh', '-c', mkdir_p.format(credstoredir))
 if install_sysconfdir
+        # Keep in sync with tmpfiles.d/credstore.conf
         meson.add_install_script('sh', '-c', mkdir_p_mode.format(sysconfdir / 'credstore', '0700'))
+        meson.add_install_script('sh', '-c', mkdir_p_mode.format(sysconfdir / 'credstore.encrypted', '0700'))
 endif
 
 executable(
index 04234c658b9a1e5da56eefa5cf0aedeed9705d39..46a74b763587e307a7afcb9f697488afcdb9f370 100644 (file)
@@ -501,7 +501,7 @@ option('analyze', type: 'boolean', value: true,
        description : 'install systemd-analyze')
 
 option('bpf-compiler', type : 'combo', choices : ['clang', 'gcc'],
-    description: 'compiler used to build BPF programs, note: gcc is experimental')
+    description: 'compiler used to build BPF programs')
 option('bpf-framework', type : 'combo', choices : ['auto', 'true', 'false'],
     description: 'build BPF programs from source code in restricted C')
 
index 627df806843b1ce4c559fa5b72243728564048ef..11e8b1c812c604348fe7f7148659be75068ed76e 100755 (executable)
@@ -176,6 +176,12 @@ if [ ! -f "$BUILDDIR"/build.ninja ]; then
         )
     fi
 
+    if grep -q '^ID="opensuse' /etc/os-release; then
+        CONFIGURE_OPTS+=(
+            -Dbpf-compiler=gcc
+        )
+    fi
+
     ( set -x; meson setup "$BUILDDIR" "${CONFIGURE_OPTS[@]}" )
 fi
 
index c5c44b8df86f978c54faaedae96f0cf7bf7bfaa1..d4cdef12a45853bc6945ed4dae497d18cf9fede4 100644 (file)
@@ -36,6 +36,7 @@ Packages=
 BuildPackages=
         audit-devel
         bpftool
+        cross-bpf-gcc13
         dbus-1-devel
         docbook-xsl-stylesheets
         fdupes
index fbc5566a651de8a046c4404c720569be3d363b0d..616bda7117fd6621cd9ad42142cb9efff8fbcd9d 100644 (file)
@@ -427,6 +427,7 @@ renameat2
 request_key
 restart_syscall
 riscv_flush_icache
+riscv_hwprobe
 rmdir
 rseq
 rt_sigaction
index 38988407fcb0258dc4b821809a060a21f03a7b0b..641e1a43a9b3138a3779db14d6e85f971423a162 100644 (file)
@@ -427,6 +427,7 @@ renameat2   510
 request_key    440
 restart_syscall        412
 riscv_flush_icache
+riscv_hwprobe
 rmdir  137
 rseq   527
 rt_sigaction   352
index 801f551c258513952ff38d50659f7fed011da18b..0f825045354c91c960e18c2dbe576c77e6ad26f3 100644 (file)
@@ -427,6 +427,7 @@ renameat2   276
 request_key    218
 restart_syscall        128
 riscv_flush_icache
+riscv_hwprobe
 rmdir
 rseq   293
 rt_sigaction   134
index 94bbcbf7036a408dd2d4e96d2af07eb7f457c6e5..013b899889619aa1ea6182121033bf546d41cfce 100644 (file)
@@ -427,6 +427,7 @@ renameat2   382
 request_key    310
 restart_syscall        0
 riscv_flush_icache
+riscv_hwprobe
 rmdir  40
 rseq   398
 rt_sigaction   174
index 207c43937e56551dfb9dc68f83c1a1b171016a8f..717c873d80483402242bb70f4d74abe7c3548739 100644 (file)
@@ -427,6 +427,7 @@ renameat2   276
 request_key    218
 restart_syscall        128
 riscv_flush_icache
+riscv_hwprobe
 rmdir
 rseq   293
 rt_sigaction   134
index 4c0c99368ef0ff984eccee8aeab9afb3770590ed..96170784db1b5636118a89a310a4f423afc27c9b 100644 (file)
@@ -427,6 +427,7 @@ renameat2   353
 request_key    287
 restart_syscall        0
 riscv_flush_icache
+riscv_hwprobe
 rmdir  40
 rseq   386
 rt_sigaction   174
index 9346b2e0d15862752dca4ad386b039f3cc0123b7..4b6481e1d34ebe2d23c17ef8496e0e1348c1d303 100644 (file)
@@ -427,6 +427,7 @@ renameat2   1338
 request_key    1272
 restart_syscall        1246
 riscv_flush_icache
+riscv_hwprobe
 rmdir  1056
 rseq   1357
 rt_sigaction   1177
index a6a0bca93add7445960e6bbcb0f1713d682fcfde..9222352c2648aaea854b29ea97f18283aec6d9bd 100644 (file)
@@ -427,6 +427,7 @@ renameat2   276
 request_key    218
 restart_syscall        128
 riscv_flush_icache
+riscv_hwprobe
 rmdir
 rseq   293
 rt_sigaction   134
index f5a95685f6d76d54572b9d56e8ec2d151676a179..3427196dc52254616d8376e9d723fe67f55f7528 100644 (file)
@@ -427,6 +427,7 @@ renameat2   351
 request_key    280
 restart_syscall        0
 riscv_flush_icache
+riscv_hwprobe
 rmdir  40
 rseq   384
 rt_sigaction   174
index 7d0b9976b066533ef5f7d8c8a7991f3c15fe990c..aded3d24d912078527676d329e8e69ed8ba2d512 100644 (file)
@@ -427,6 +427,7 @@ renameat2   5311
 request_key    5240
 restart_syscall        5213
 riscv_flush_icache
+riscv_hwprobe
 rmdir  5082
 rseq   5327
 rt_sigaction   5013
index 2e15c66124fdb0db7743a9c453ecc4dc7a4bee55..76e81e65b1e4fb1003ec1c6e3b8b95594f2fcca2 100644 (file)
@@ -427,6 +427,7 @@ renameat2   6315
 request_key    6244
 restart_syscall        6214
 riscv_flush_icache
+riscv_hwprobe
 rmdir  6082
 rseq   6331
 rt_sigaction   6013
index a8d95e3e3559fcb3f1e5c89f157321882f7df245..02fa281b5cf3afe622e0a3ae239a7ccf2ab3639c 100644 (file)
@@ -427,6 +427,7 @@ renameat2   4351
 request_key    4281
 restart_syscall        4253
 riscv_flush_icache
+riscv_hwprobe
 rmdir  4040
 rseq   4367
 rt_sigaction   4194
index 905729f8198c612d03d84bb91eee88f26a544099..e409d69de86b4219a66b586710e8802ec2fe1c6d 100644 (file)
@@ -427,6 +427,7 @@ renameat2   337
 request_key    265
 restart_syscall        0
 riscv_flush_icache
+riscv_hwprobe
 rmdir  40
 rseq   354
 rt_sigaction   174
index ad68616e250f2a35096428a7ed78cda12965e3d4..7e70248340b3c55e2a2844db00f33573b7766d1b 100644 (file)
@@ -427,6 +427,7 @@ renameat2   357
 request_key    270
 restart_syscall        0
 riscv_flush_icache
+riscv_hwprobe
 rmdir  40
 rseq   387
 rt_sigaction   173
index 9e8dc6dd8cc5f0ee3c464b9e30fb300ac4b2e0e1..e9c37cd1d9b7ebda3dd9cf8af3f474556c8901f7 100644 (file)
@@ -427,6 +427,7 @@ renameat2   357
 request_key    270
 restart_syscall        0
 riscv_flush_icache
+riscv_hwprobe
 rmdir  40
 rseq   387
 rt_sigaction   173
index 50f4de65b8381275e2959738cc8ddcb93c7b0d16..6ef882f3d0f67e7a66d6b32f9eadd80f3bc14fc8 100644 (file)
@@ -427,6 +427,7 @@ renameat2   276
 request_key    218
 restart_syscall        128
 riscv_flush_icache     259
+riscv_hwprobe  258
 rmdir
 rseq   293
 rt_sigaction   134
index afa33b2bcc7ef7d3547f86a1ec539a937548ade3..700ff225b368799f9839f1f15dcf446b0f886518 100644 (file)
@@ -427,6 +427,7 @@ renameat2   276
 request_key    218
 restart_syscall        128
 riscv_flush_icache     259
+riscv_hwprobe  258
 rmdir
 rseq   293
 rt_sigaction   134
index bbc824c005965cf8f029eaea6ad449c59672621f..caa89112bb0b2d25c86762be09cc7f34f1407732 100644 (file)
@@ -204,7 +204,7 @@ madvise     219
 mbind  268
 membarrier     356
 memfd_create   350
-memfd_secret
+memfd_secret   447
 memory_ordering
 migrate_pages  287
 mincore        218
@@ -427,6 +427,7 @@ renameat2   347
 request_key    279
 restart_syscall        7
 riscv_flush_icache
+riscv_hwprobe
 rmdir  40
 rseq   383
 rt_sigaction   174
index bc385eabadf823e744cf886b7c3b703ff7c9985f..a18a9a5658004e7cfc481f0c5638b5baf7cf208d 100644 (file)
@@ -204,7 +204,7 @@ madvise     219
 mbind  268
 membarrier     356
 memfd_create   350
-memfd_secret
+memfd_secret   447
 memory_ordering
 migrate_pages  287
 mincore        218
@@ -427,6 +427,7 @@ renameat2   347
 request_key    279
 restart_syscall        7
 riscv_flush_icache
+riscv_hwprobe
 rmdir  40
 rseq   383
 rt_sigaction   174
index 6c39ad86f4fe9c2f660582a52a634a78cf4beae7..991f7da201fdfd468061e0cd7d035a9c37ea53c5 100644 (file)
@@ -427,6 +427,7 @@ renameat2   345
 request_key    282
 restart_syscall        0
 riscv_flush_icache
+riscv_hwprobe
 rmdir  137
 rseq   365
 rt_sigaction   102
index 2942c2e489cdc6efc0fe38452f205f4524ba58e7..40df5e1baf2ca816f0ed3ae2fd9a43bd9fe5a426 100644 (file)
@@ -427,6 +427,7 @@ renameat2   316
 request_key    249
 restart_syscall        219
 riscv_flush_icache
+riscv_hwprobe
 rmdir  84
 rseq   334
 rt_sigaction   13
index e3b3b1b22809e5d7da0d54c39e27a2fb758bc5cf..8036724034f109994a10a208c5a8b61d6595a936 100644 (file)
@@ -25,7 +25,6 @@
 #include "gpt.h"
 #include "image-policy.h"
 #include "initrd-util.h"
-#include "mkdir.h"
 #include "mountpoint-util.h"
 #include "parse-util.h"
 #include "path-util.h"
@@ -109,7 +108,7 @@ static int add_cryptsetup(
 
                 r = efi_stub_measured(LOG_WARNING);
                 if (r == 0)
-                        log_debug("Will not measure volume key of volume '%s', because not booted via systemd-stub with measurements enabled.", id);
+                        log_debug("Will not measure volume key of volume '%s', not booted via systemd-stub with measurements enabled.", id);
                 else if (r > 0) {
                         if (!strextend_with_separator(&options, ",", "tpm2-measure-pcr=yes"))
                                 return log_oom();
@@ -128,8 +127,7 @@ static int add_cryptsetup(
         if (r < 0)
                 return r;
 
-        const char *dmname;
-        dmname = strjoina("dev-mapper-", e, ".device");
+        const char *dmname = strjoina("dev-mapper-", e, ".device");
 
         if (require) {
                 r = generator_add_symlink(arg_dest, "cryptsetup.target", "requires", n);
@@ -160,7 +158,8 @@ static int add_cryptsetup(
 
         return 0;
 #else
-        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Partition is encrypted, but the project was compiled without libcryptsetup support");
+        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+                               "Partition is encrypted, but systemd-gpt-auto-generator was compiled without libcryptsetup support");
 #endif
 }
 
@@ -280,12 +279,13 @@ static int add_mount(
 static int path_is_busy(const char *where) {
         int r;
 
+        assert(where);
+
         /* already a mountpoint; generators run during reload */
         r = path_is_mount_point(where, NULL, AT_SYMLINK_FOLLOW);
         if (r > 0)
                 return false;
-
-        /* the directory might not exist on a stateless system */
+        /* The directory will be created by the mount or automount unit when it is started. */
         if (r == -ENOENT)
                 return false;
 
@@ -294,13 +294,17 @@ static int path_is_busy(const char *where) {
 
         /* not a mountpoint but it contains files */
         r = dir_is_empty(where, /* ignore_hidden_or_backup= */ false);
-        if (r < 0)
+        if (r == -ENOTDIR) {
+                log_debug("\"%s\" is not a directory, ignoring.", where);
+                return true;
+        } else if (r < 0)
                 return log_warning_errno(r, "Cannot check if \"%s\" is empty: %m", where);
-        if (r > 0)
-                return false;
+        else if (r == 0) {
+                log_debug("\"%s\" already populated, ignoring.", where);
+                return true;
+        }
 
-        log_debug("\"%s\" already populated, ignoring.", where);
-        return true;
+        return false;
 }
 
 static int add_partition_mount(
@@ -471,6 +475,45 @@ static int add_automount(
         return generator_add_symlink(arg_dest, SPECIAL_LOCAL_FS_TARGET, "wants", unit);
 }
 
+static int slash_boot_in_fstab(void) {
+        static int cache = -1;
+
+        if (cache >= 0)
+                return cache;
+
+        cache = fstab_is_mount_point("/boot");
+        if (cache < 0)
+                return log_error_errno(cache, "Failed to parse fstab: %m");
+        return cache;
+}
+
+static int slash_efi_in_fstab(void) {
+        static int cache = -1;
+
+        if (cache >= 0)
+                return cache;
+
+        cache = fstab_is_mount_point("/efi");
+        if (cache < 0)
+                return log_error_errno(cache, "Failed to parse fstab: %m");
+        return cache;
+}
+
+static bool slash_boot_exists(void) {
+        static int cache = -1;
+
+        if (cache >= 0)
+                return cache;
+
+        if (access("/boot", F_OK) >= 0)
+                return (cache = true);
+        if (errno != ENOENT)
+                log_error_errno(errno, "Failed to determine whether /boot/ exists, assuming no: %m");
+        else
+                log_debug_errno(errno, "/boot/: %m");
+        return (cache = false);
+}
+
 static int add_partition_xbootldr(DissectedPartition *p) {
         _cleanup_free_ char *options = NULL;
         int r;
@@ -482,11 +525,11 @@ static int add_partition_xbootldr(DissectedPartition *p) {
                 return 0;
         }
 
-        r = fstab_is_mount_point("/boot");
+        r = slash_boot_in_fstab();
         if (r < 0)
-                return log_error_errno(r, "Failed to parse fstab: %m");
+                return r;
         if (r > 0) {
-                log_debug("/boot specified in fstab, ignoring XBOOTLDR partition.");
+                log_debug("/boot/ specified in fstab, ignoring XBOOTLDR partition.");
                 return 0;
         }
 
@@ -504,17 +547,18 @@ static int add_partition_xbootldr(DissectedPartition *p) {
                         &options,
                         /* ret_ms_flags= */ NULL);
         if (r < 0)
-                return log_error_errno(r, "Failed to determine default mount options for Boot Loader Partition: %m");
-
-        return add_automount("boot",
-                             p->node,
-                             "/boot",
-                             p->fstype,
-                             /* rw= */ true,
-                             /* growfs= */ false,
-                             options,
-                             "Boot Loader Partition",
-                             120 * USEC_PER_SEC);
+                return log_error_errno(r, "Failed to determine default mount options for /boot/: %m");
+
+        return add_automount(
+                        "boot",
+                        p->node,
+                        "/boot",
+                        p->fstype,
+                        /* rw= */ true,
+                        /* growfs= */ false,
+                        options,
+                        "Boot Loader Partition",
+                        120 * USEC_PER_SEC);
 }
 
 #if ENABLE_EFI
@@ -530,43 +574,42 @@ static int add_partition_esp(DissectedPartition *p, bool has_xbootldr) {
                 return 0;
         }
 
-        /* If /efi exists we'll use that. Otherwise we'll use /boot, as that's usually the better choice, but
-         * only if there's no explicit XBOOTLDR partition around. */
-        if (access("/efi", F_OK) < 0) {
-                if (errno != ENOENT)
-                        return log_error_errno(errno, "Failed to determine whether /efi exists: %m");
-
-                /* Use /boot as fallback, but only if there's no XBOOTLDR partition and /boot exists */
-                if (!has_xbootldr) {
-                        if (access("/boot", F_OK) < 0) {
-                                if (errno != ENOENT)
-                                        return log_error_errno(errno, "Failed to determine whether /boot exists: %m");
-                        } else {
+        /* If /boot/ is present, unused, and empty, we'll take that.
+         * Otherwise, if /efi/ is unused and empty (or missing), we'll take that.
+         * Otherwise, we do nothing.
+         */
+        if (!has_xbootldr && slash_boot_exists()) {
+                r = slash_boot_in_fstab();
+                if (r < 0)
+                        return r;
+                if (r == 0) {
+                        r = path_is_busy("/boot");
+                        if (r < 0)
+                                return r;
+                        if (r == 0) {
                                 esp_path = "/boot";
                                 id = "boot";
                         }
                 }
         }
-        if (!esp_path)
+
+        if (!esp_path) {
+                r = slash_efi_in_fstab();
+                if (r < 0)
+                        return r;
+                if (r > 0)
+                        return 0;
+
+                r = path_is_busy("/efi");
+                if (r < 0)
+                        return r;
+                if (r > 0)
+                        return 0;
+
                 esp_path = "/efi";
-        if (!id)
                 id = "efi";
-
-        /* We create an .automount which is not overridden by the .mount from the fstab generator. */
-        r = fstab_is_mount_point(esp_path);
-        if (r < 0)
-                return log_error_errno(r, "Failed to parse fstab: %m");
-        if (r > 0) {
-                log_debug("%s specified in fstab, ignoring.", esp_path);
-                return 0;
         }
 
-        r = path_is_busy(esp_path);
-        if (r < 0)
-                return r;
-        if (r > 0)
-                return 0;
-
         if (is_efi_boot()) {
                 sd_id128_t loader_uuid;
 
@@ -595,17 +638,18 @@ static int add_partition_esp(DissectedPartition *p, bool has_xbootldr) {
                         &options,
                         /* ret_ms_flags= */ NULL);
         if (r < 0)
-                return log_error_errno(r, "Failed to determine default mount options for EFI System Partition: %m");
-
-        return add_automount(id,
-                             p->node,
-                             esp_path,
-                             p->fstype,
-                             /* rw= */ true,
-                             /* growfs= */ false,
-                             options,
-                             "EFI System Partition Automount",
-                             120 * USEC_PER_SEC);
+                return log_error_errno(r, "Failed to determine default mount options for %s: %m", esp_path);
+
+        return add_automount(
+                        id,
+                        p->node,
+                        esp_path,
+                        p->fstype,
+                        /* rw= */ true,
+                        /* growfs= */ false,
+                        options,
+                        "EFI System Partition Automount",
+                        120 * USEC_PER_SEC);
 }
 #else
 static int add_partition_esp(DissectedPartition *p, bool has_xbootldr) {
index d16509d57437cc73b3a18b47e26885ad049a0d93..a79a719383852a01b2cc5cd8dceb7a42028ba392 100644 (file)
@@ -2681,8 +2681,6 @@ static int home_dispatch_acquire(Home *h, Operation *o) {
         assert(o);
         assert(o->type == OPERATION_ACQUIRE);
 
-        assert(!h->current_operation);
-
         switch (home_get_state(h)) {
 
         case HOME_UNFIXATED:
@@ -2718,6 +2716,8 @@ static int home_dispatch_acquire(Home *h, Operation *o) {
                 return 0;
         }
 
+        assert(!h->current_operation);
+
         r = home_ratelimit(h, &error);
         if (r >= 0)
                 r = call(h, o->secret, for_state, &error);
index c2d2f950de56d05848ea09e1506b2b4381accf73..66f93e7d2eb2f86d0f5880c936a5e8116d99131f 100644 (file)
@@ -34,6 +34,9 @@ int parse_integrity_options(
                 else if (streq(word, "allow-discards")) {
                         if (ret_activate_flags)
                                 *ret_activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
+                } else if (streq(word, "no-journal")) {
+                        if (ret_activate_flags)
+                                *ret_activate_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
                 } else if ((val = startswith(word, "journal-watermark="))) {
                         r = parse_percent(val);
                         if (r < 0)
index 5a2f992e2dc40a03319890c4a4577e66b30a544d..4fde0a58a5e956e21cd6034e8cc2ad7ab8856c4f 100644 (file)
@@ -230,7 +230,8 @@ typedef struct Partition {
 
         char *format;
         char **copy_files;
-        char **exclude_files;
+        char **exclude_files_source;
+        char **exclude_files_target;
         char **make_directories;
         EncryptMode encrypt;
         VerityMode verity;
@@ -374,7 +375,8 @@ static Partition* partition_free(Partition *p) {
 
         free(p->format);
         strv_free(p->copy_files);
-        strv_free(p->exclude_files);
+        strv_free(p->exclude_files_source);
+        strv_free(p->exclude_files_target);
         strv_free(p->make_directories);
         free(p->verity_match_key);
 
@@ -401,7 +403,8 @@ static void partition_foreignize(Partition *p) {
 
         p->format = mfree(p->format);
         p->copy_files = strv_free(p->copy_files);
-        p->exclude_files = strv_free(p->exclude_files);
+        p->exclude_files_source = strv_free(p->exclude_files_source);
+        p->exclude_files_target = strv_free(p->exclude_files_target);
         p->make_directories = strv_free(p->make_directories);
         p->verity_match_key = mfree(p->verity_match_key);
 
@@ -1597,31 +1600,32 @@ static DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_minimize, minimize_mod
 static int partition_read_definition(Partition *p, const char *path, const char *const *conf_file_dirs) {
 
         ConfigTableItem table[] = {
-                { "Partition", "Type",            config_parse_type,          0, &p->type              },
-                { "Partition", "Label",           config_parse_label,         0, &p->new_label         },
-                { "Partition", "UUID",            config_parse_uuid,          0, p                     },
-                { "Partition", "Priority",        config_parse_int32,         0, &p->priority          },
-                { "Partition", "Weight",          config_parse_weight,        0, &p->weight            },
-                { "Partition", "PaddingWeight",   config_parse_weight,        0, &p->padding_weight    },
-                { "Partition", "SizeMinBytes",    config_parse_size4096,      1, &p->size_min          },
-                { "Partition", "SizeMaxBytes",    config_parse_size4096,     -1, &p->size_max          },
-                { "Partition", "PaddingMinBytes", config_parse_size4096,      1, &p->padding_min       },
-                { "Partition", "PaddingMaxBytes", config_parse_size4096,     -1, &p->padding_max       },
-                { "Partition", "FactoryReset",    config_parse_bool,          0, &p->factory_reset     },
-                { "Partition", "CopyBlocks",      config_parse_copy_blocks,   0, p                     },
-                { "Partition", "Format",          config_parse_fstype,        0, &p->format            },
-                { "Partition", "CopyFiles",       config_parse_copy_files,    0, &p->copy_files        },
-                { "Partition", "ExcludeFiles",    config_parse_exclude_files, 0, &p->exclude_files     },
-                { "Partition", "MakeDirectories", config_parse_make_dirs,     0, p                     },
-                { "Partition", "Encrypt",         config_parse_encrypt,       0, &p->encrypt           },
-                { "Partition", "Verity",          config_parse_verity,        0, &p->verity            },
-                { "Partition", "VerityMatchKey",  config_parse_string,        0, &p->verity_match_key  },
-                { "Partition", "Flags",           config_parse_gpt_flags,     0, &p->gpt_flags         },
-                { "Partition", "ReadOnly",        config_parse_tristate,      0, &p->read_only         },
-                { "Partition", "NoAuto",          config_parse_tristate,      0, &p->no_auto           },
-                { "Partition", "GrowFileSystem",  config_parse_tristate,      0, &p->growfs            },
-                { "Partition", "SplitName",       config_parse_string,        0, &p->split_name_format },
-                { "Partition", "Minimize",        config_parse_minimize,      0, &p->minimize          },
+                { "Partition", "Type",               config_parse_type,          0, &p->type                 },
+                { "Partition", "Label",              config_parse_label,         0, &p->new_label            },
+                { "Partition", "UUID",               config_parse_uuid,          0, p                        },
+                { "Partition", "Priority",           config_parse_int32,         0, &p->priority             },
+                { "Partition", "Weight",             config_parse_weight,        0, &p->weight               },
+                { "Partition", "PaddingWeight",      config_parse_weight,        0, &p->padding_weight       },
+                { "Partition", "SizeMinBytes",       config_parse_size4096,      1, &p->size_min             },
+                { "Partition", "SizeMaxBytes",       config_parse_size4096,     -1, &p->size_max             },
+                { "Partition", "PaddingMinBytes",    config_parse_size4096,      1, &p->padding_min          },
+                { "Partition", "PaddingMaxBytes",    config_parse_size4096,     -1, &p->padding_max          },
+                { "Partition", "FactoryReset",       config_parse_bool,          0, &p->factory_reset        },
+                { "Partition", "CopyBlocks",         config_parse_copy_blocks,   0, p                        },
+                { "Partition", "Format",             config_parse_fstype,        0, &p->format               },
+                { "Partition", "CopyFiles",          config_parse_copy_files,    0, &p->copy_files           },
+                { "Partition", "ExcludeFiles",       config_parse_exclude_files, 0, &p->exclude_files_source },
+                { "Partition", "ExcludeFilesTarget", config_parse_exclude_files, 0, &p->exclude_files_target },
+                { "Partition", "MakeDirectories",    config_parse_make_dirs,     0, p                        },
+                { "Partition", "Encrypt",            config_parse_encrypt,       0, &p->encrypt              },
+                { "Partition", "Verity",             config_parse_verity,        0, &p->verity               },
+                { "Partition", "VerityMatchKey",     config_parse_string,        0, &p->verity_match_key     },
+                { "Partition", "Flags",              config_parse_gpt_flags,     0, &p->gpt_flags            },
+                { "Partition", "ReadOnly",           config_parse_tristate,      0, &p->read_only            },
+                { "Partition", "NoAuto",             config_parse_tristate,      0, &p->no_auto              },
+                { "Partition", "GrowFileSystem",     config_parse_tristate,      0, &p->growfs               },
+                { "Partition", "SplitName",          config_parse_string,        0, &p->split_name_format    },
+                { "Partition", "Minimize",           config_parse_minimize,      0, &p->minimize             },
                 {}
         };
         int r;
@@ -3913,12 +3917,28 @@ static int make_copy_files_denylist(
 
         /* Add the user configured excludes. */
 
-        STRV_FOREACH(e, p->exclude_files) {
+        STRV_FOREACH(e, p->exclude_files_source) {
                 r = add_exclude_path(*e, &denylist, endswith(*e, "/") ? DENY_CONTENTS : DENY_INODE);
                 if (r < 0)
                         return r;
         }
 
+        STRV_FOREACH(e, p->exclude_files_target) {
+                _cleanup_free_ char *path = NULL;
+
+                const char *s = path_startswith(*e, target);
+                if (!s)
+                        continue;
+
+                path = path_join(source, s);
+                if (!path)
+                        return log_oom();
+
+                r = add_exclude_path(path, &denylist, endswith(*e, "/") ? DENY_CONTENTS : DENY_INODE);
+                if (r < 0)
+                        return r;
+        }
+
         /* If we're populating a root partition, we don't want any files to end up under the APIVFS mount
          * points. While we already exclude <source>/proc, users could still do something such as
          * "CopyFiles=/abc:/". Now, if /abc has a proc subdirectory with files in it, those will end up in
index 2638e985fb42c9f1d40f22c0dc944eac36c33347..e65fbbcbab36acc1a5400a7a4195b70b650e5281 100644 (file)
@@ -1165,7 +1165,7 @@ static int show_statistics(int argc, char **argv, void *userdata) {
                            TABLE_UINT64, n_dnssec_insecure,
                            TABLE_FIELD, "Bogus",
                            TABLE_UINT64, n_dnssec_bogus,
-                           TABLE_FIELD, "Indeterminate:",
+                           TABLE_FIELD, "Indeterminate",
                            TABLE_UINT64, n_dnssec_indeterminate);
         if (r < 0)
                 return table_log_add_error(r);
index 39f75dd0dd1106e5f1b6aaf6db0900b944882357..becd13f4c5c6b4c10ac8faa82ab0f11e3c3c545e 100644 (file)
@@ -2019,6 +2019,27 @@ static int mount_root_tmpfs(const char *where, uid_t uid_shift, DissectImageFlag
         return 1;
 }
 
+static int mount_point_is_available(const char *where, const char *path, bool missing_ok) {
+        _cleanup_free_ char *p = NULL;
+        int r;
+
+        /* Check whether <path> is suitable as a mountpoint, i.e. is an empty directory
+         * or does not exist at all (when missing_ok). */
+
+        r = chase(path, where, CHASE_PREFIX_ROOT, &p, NULL);
+        if (r == -ENOENT)
+                return missing_ok;
+        if (r < 0)
+                return log_debug_errno(r, "Failed to chase \"%s\": %m", path);
+
+        r = dir_is_empty(p, /* ignore_hidden_or_backup= */ false);
+        if (r == -ENOTDIR)
+                return false;
+        if (r < 0)
+                return log_debug_errno(r, "Failed to check directory \"%s\": %m", p);
+        return true;
+}
+
 int dissected_image_mount(
                 DissectedImage *m,
                 const char *where,
@@ -2026,7 +2047,7 @@ int dissected_image_mount(
                 uid_t uid_range,
                 DissectImageFlags flags) {
 
-        int r, xbootldr_mounted;
+        int r;
 
         assert(m);
         assert(where);
@@ -2110,45 +2131,42 @@ int dissected_image_mount(
         if (r < 0)
                 return r;
 
-        xbootldr_mounted = mount_partition(PARTITION_XBOOTLDR, m->partitions + PARTITION_XBOOTLDR, where, "/boot", uid_shift, uid_range, flags);
-        if (xbootldr_mounted < 0)
-                return xbootldr_mounted;
+        int slash_boot_is_available;
+        r = slash_boot_is_available = mount_point_is_available(where, "/boot", /* missing_ok = */ true);
+        if (r < 0)
+                return r;
+        if (r > 0) {
+                r = mount_partition(PARTITION_XBOOTLDR, m->partitions + PARTITION_XBOOTLDR, where, "/boot", uid_shift, uid_range, flags);
+                if (r < 0)
+                        return r;
+                slash_boot_is_available = !r;
+        }
 
         if (m->partitions[PARTITION_ESP].found) {
-                int esp_done = false;
+                const char *esp_path = NULL;
 
-                /* Mount the ESP to /efi if it exists. If it doesn't exist, use /boot instead, but only if it
-                 * exists and is empty, and we didn't already mount the XBOOTLDR partition into it. */
+                /* Mount the ESP to /boot/ if it exists and is empty and we didn't already mount the XBOOTLDR
+                 * partition into it. Otherwise, use /efi instead, but only if it exists and is empty. */
 
-                r = chase("/efi", where, CHASE_PREFIX_ROOT, NULL, NULL);
-                if (r < 0) {
-                        if (r != -ENOENT)
+                if (slash_boot_is_available) {
+                        r = mount_point_is_available(where, "/boot", /* missing_ok = */ false);
+                        if (r < 0)
                                 return r;
-
-                        /* /efi doesn't exist. Let's see if /boot is suitable then */
-
-                        if (!xbootldr_mounted) {
-                                _cleanup_free_ char *p = NULL;
-
-                                r = chase("/boot", where, CHASE_PREFIX_ROOT, &p, NULL);
-                                if (r < 0) {
-                                        if (r != -ENOENT)
-                                                return r;
-                                } else if (dir_is_empty(p, /* ignore_hidden_or_backup= */ false) > 0) {
-                                        /* It exists and is an empty directory. Let's mount the ESP there. */
-                                        r = mount_partition(PARTITION_ESP, m->partitions + PARTITION_ESP, where, "/boot", uid_shift, uid_range, flags);
-                                        if (r < 0)
-                                                return r;
-
-                                        esp_done = true;
-                                }
-                        }
+                        if (r > 0)
+                                esp_path = "/boot";
                 }
 
-                if (!esp_done) {
-                        /* OK, let's mount the ESP now to /efi (possibly creating the dir if missing) */
+                if (!esp_path) {
+                        r = mount_point_is_available(where, "/efi", /* missing_ok = */ true);
+                        if (r < 0)
+                                return r;
+                        if (r > 0)
+                                esp_path = "/efi";
+                }
 
-                        r = mount_partition(PARTITION_ESP, m->partitions + PARTITION_ESP, where, "/efi", uid_shift, uid_range, flags);
+                if (esp_path) {
+                        /* OK, let's mount the ESP now (possibly creating the dir if missing) */
+                        r = mount_partition(PARTITION_ESP, m->partitions + PARTITION_ESP, where, esp_path, uid_shift, uid_range, flags);
                         if (r < 0)
                                 return r;
                 }
index 123e57e370dbfe320577b8076eb8e6b127806600..adf7325704410024d76b4bd2dcb364544ad0f69c 100644 (file)
@@ -138,6 +138,7 @@ const GptPartitionType gpt_partition_type_table[] = {
         _GPT_ARCH_SEXTET(ALPHA,       "alpha"),
         _GPT_ARCH_SEXTET(ARC,         "arc"),
         _GPT_ARCH_SEXTET(ARM,         "arm"),
+        _GPT_ARCH_SEXTET(ARM,         "armv7l"), /* Alias: must be listed after arm */
         _GPT_ARCH_SEXTET(ARM64,       "arm64"),
         _GPT_ARCH_SEXTET(ARM64,       "aarch64"), /* Alias: must be listed after arm64 */
         _GPT_ARCH_SEXTET(IA64,        "ia64"),
@@ -148,6 +149,7 @@ const GptPartitionType gpt_partition_type_table[] = {
         _GPT_ARCH_SEXTET(PPC,         "ppc"),
         _GPT_ARCH_SEXTET(PPC64,       "ppc64"),
         _GPT_ARCH_SEXTET(PPC64_LE,    "ppc64-le"),
+        _GPT_ARCH_SEXTET(PPC64_LE,    "ppc64le"), /* Alias: must be listed after ppc64-le */
         _GPT_ARCH_SEXTET(RISCV32,     "riscv32"),
         _GPT_ARCH_SEXTET(RISCV64,     "riscv64"),
         _GPT_ARCH_SEXTET(S390,        "s390"),
@@ -155,6 +157,7 @@ const GptPartitionType gpt_partition_type_table[] = {
         _GPT_ARCH_SEXTET(TILEGX,      "tilegx"),
         _GPT_ARCH_SEXTET(X86,         "x86"),
         _GPT_ARCH_SEXTET(X86_64,      "x86-64"),
+        _GPT_ARCH_SEXTET(X86_64,      "x86_64"), /* Alias: must be listed after x86-64 */
         _GPT_ARCH_SEXTET(X86_64,      "amd64"), /* Alias: must be listed after x86-64 */
 #ifdef SD_GPT_ROOT_NATIVE
         { SD_GPT_ROOT_NATIVE,            "root",            native_architecture(), .designator = PARTITION_ROOT            },
index a85cff09142b2dcdbd758c8b02f3283a6d5c89d8..5418871093def6ebff8088a6b5fb5e58d8409c01 100644 (file)
@@ -817,16 +817,24 @@ static LoopDevice* loop_device_free(LoopDevice *d) {
         }
 
         /* Now that the block device is released, let's also try to remove it */
-        if (control >= 0)
-                for (unsigned n_attempts = 0;;) {
+        if (control >= 0) {
+                useconds_t delay = 5 * USEC_PER_MSEC;
+
+                for (unsigned attempt = 1;; attempt++) {
                         if (ioctl(control, LOOP_CTL_REMOVE, d->nr) >= 0)
                                 break;
-                        if (errno != EBUSY || ++n_attempts >= 64) {
+                        if (errno != EBUSY || attempt > 38) {
                                 log_debug_errno(errno, "Failed to remove device %s: %m", strna(d->node));
                                 break;
                         }
-                        (void) usleep(50 * USEC_PER_MSEC);
+                        if (attempt % 5 == 0) {
+                                log_debug("Device is still busy after %u attempts…", attempt);
+                                delay *= 2;
+                        }
+
+                        (void) usleep(delay);
                 }
+        }
 
         free(d->node);
         sd_device_unref(d->dev);
index 9070d0c60c9caba2d0d6abe1d2ab33ddf8cbc165..695cce15aabb64bd2f0fa5703a59070dfbeca1d0 100644 (file)
@@ -99,7 +99,7 @@ INTERACTIVE_DEBUG=1
     the test, etc.)
 
 The kernel and initrd can be specified with $KERNEL_BIN and $INITRD. (Fedora's
-or Debian's default kernel path and initrd are used by default)
+or Debian's default kernel path and initrd are used by default.)
 
 A script will try to find your qemu binary. If you want to specify a different
 one with $QEMU_BIN.
@@ -107,12 +107,12 @@ one with $QEMU_BIN.
 Debugging the qemu image
 ========================
 
-If you want to log in the testsuite virtual machine, you can specify additional
-kernel command line parameter with $KERNEL_APPEND and then log in as root.
+If you want to log in the testsuite virtual machine, use INTERACTIVE_DEBUG=1
+and log in as root:
 
-$ sudo make -C test/TEST-01-BASIC KERNEL_APPEND="systemd.unit=multi-user.target" run
+$ sudo make -C test/TEST-01-BASIC INTERACTIVE_DEBUG=1 run
 
-Root password is empty.
+The root password is empty.
 
 Ubuntu CI
 =========
index 68c9d0631e2e56e898f1b8ea51a70aebe9902e05..c390c785c9855ac7be54acfdcc7fadeef81d97c0 100755 (executable)
@@ -19,6 +19,10 @@ src="$(dirname "$0")/testdata/test-fstab-generator"
 # fsck(8) is located in /usr/sbin on Debian
 PATH=$PATH:/usr/sbin
 
+# systemd-pcrfs@.service could be enabled or not, depending on the host state
+# of the host system. Override the measurement to avoid the issue.
+export SYSTEMD_FORCE_MEASURE=0
+
 for f in "$src"/test-*.input; do
     echo "*** Running $f"
 
index b1b40851dba7b7cd29c62c62301090c6f3dd0a6f..de00f59d26c22dad609de95bb97928844349e635 100755 (executable)
@@ -95,12 +95,13 @@ testcase_basic() {
     local defs imgs output
     local loop volume
 
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
+    chmod a+rx "$defs"
 
-    # 1. create an empty image
+    echo "*** 1. create an empty image ***"
 
     runas testuser systemd-repart --empty=create \
                                   --size=1G \
@@ -116,23 +117,23 @@ unit: sectors
 first-lba: 2048
 last-lba: 2097118"
 
-    # 2. Testing with root, root2, home, and swap
+    echo "*** 2. Testing with root, root2, home, and swap ***"
 
-    runas testuser tee "$defs/root.conf" <<EOF
+    tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root
 EOF
 
     ln -s root.conf "$defs/root2.conf"
 
-    runas testuser tee "$defs/home.conf" <<EOF
+    tee "$defs/home.conf" <<EOF
 [Partition]
 Type=home
 Label=home-first
 Label=home-always-too-long-xxxxxxxxxxxxxx-%v
 EOF
 
-    runas testuser tee "$defs/swap.conf" <<EOF
+    tee "$defs/swap.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=64M
@@ -191,15 +192,15 @@ $imgs/zzz2 : start=      593904, size=      591856, type=${root_guid}, uuid=${ro
 $imgs/zzz3 : start=     1185760, size=      591864, type=${root_guid}, uuid=${root_uuid2}, name=\"root-${architecture}-2\", attrs=\"GUID:59\"
 $imgs/zzz4 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\""
 
-    # 3. Testing with root, root2, home, swap, and another partition
+    echo "*** 3. Testing with root, root2, home, swap, and another partition ***"
 
-    runas testuser tee "$defs/swap.conf" <<EOF
+    tee "$defs/swap.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=64M
 EOF
 
-    runas testuser tee "$defs/extra.conf" <<EOF
+    tee "$defs/extra.conf" <<EOF
 [Partition]
 Type=linux-generic
 Label=custom_label
@@ -228,7 +229,7 @@ $imgs/zzz3 : start=     1185760, size=      591864, type=${root_guid}, uuid=${ro
 $imgs/zzz4 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\"
 $imgs/zzz5 : start=     1908696, size=      188416, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name=\"custom_label\""
 
-    # 4. Resizing to 2G
+    echo "*** 4. Resizing to 2G ***"
 
     runas testuser systemd-repart --definitions="$defs" \
                                   --size=2G \
@@ -250,11 +251,11 @@ $imgs/zzz3 : start=     1185760, size=      591864, type=${root_guid}, uuid=${ro
 $imgs/zzz4 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\"
 $imgs/zzz5 : start=     1908696, size=     2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name=\"custom_label\""
 
-    # 5. Testing with root, root2, home, swap, another partition, and partition copy
+    echo "*** 5. Testing with root, root2, home, swap, another partition, and partition copy ***"
 
     dd if=/dev/urandom of="$imgs/block-copy" bs=4096 count=10240
 
-    runas testuser tee "$defs/extra2.conf" <<EOF
+    tee "$defs/extra2.conf" <<EOF
 [Partition]
 Type=linux-generic
 Label=block-copy
@@ -285,9 +286,9 @@ $imgs/zzz6 : start=     4194264, size=     2097152, type=0FC63DAF-8483-4772-8E79
 
     cmp --bytes=$((4096*10240)) --ignore-initial=0:$((512*4194264)) "$imgs/block-copy" "$imgs/zzz"
 
-    # 6. Testing Format=/Encrypt=/CopyFiles=
+    echo "*** 6. Testing Format=/Encrypt=/CopyFiles= ***"
 
-    runas testuser tee "$defs/extra3.conf" <<EOF
+    tee "$defs/extra3.conf" <<EOF
 [Partition]
 Type=linux-generic
 Label=luks-format-copy
@@ -298,6 +299,10 @@ CopyFiles=$defs:/def
 SizeMinBytes=48M
 EOF
 
+    # CopyFiles will fail if we try to chown the target file to root.
+    # Make the files owned by the user so that the invocation below works.
+    chown testuser -R "$defs"
+
     runas testuser systemd-repart --definitions="$defs" \
                                   --size=auto \
                                   --dry-run=no \
@@ -344,26 +349,27 @@ $imgs/zzz7 : start=     6291416, size=       98304, type=0FC63DAF-8483-4772-8E79
 testcase_dropin() {
     local defs imgs output
 
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
+    chmod a+rx "$defs"
 
-    runas testuser tee "$defs/root.conf" <<EOF
+    tee "$defs/root.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=64M
 UUID=837c3d67-21b3-478e-be82-7e7f83bf96d3
 EOF
 
-    runas testuser mkdir -p "$defs/root.conf.d"
-    runas testuser tee "$defs/root.conf.d/override1.conf" <<EOF
+    mkdir -p "$defs/root.conf.d"
+    tee "$defs/root.conf.d/override1.conf" <<EOF
 [Partition]
 Label=label1
 SizeMaxBytes=32M
 EOF
 
-    runas testuser tee "$defs/root.conf.d/override2.conf" <<EOF
+    tee "$defs/root.conf.d/override2.conf" <<EOF
 [Partition]
 Label=label2
 EOF
@@ -402,14 +408,14 @@ EOF
 testcase_multiple_definitions() {
     local defs imgs output
 
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
+    chmod a+rx "$defs"
 
-    runas testuser mkdir -p "$defs/1"
-
-    runas testuser tee "$defs/1/root1.conf" <<EOF
+    mkdir -p "$defs/1"
+    tee "$defs/1/root1.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=32M
@@ -417,9 +423,8 @@ UUID=7b93d1f2-595d-4ce3-b0b9-837fbd9e63b0
 Label=label1
 EOF
 
-    runas testuser mkdir -p "$defs/2"
-
-    runas testuser tee "$defs/2/root2.conf" <<EOF
+    mkdir -p "$defs/2"
+    tee "$defs/2/root2.conf" <<EOF
 [Partition]
 Type=swap
 SizeMaxBytes=32M
@@ -473,21 +478,22 @@ EOF
 testcase_copy_blocks() {
     local defs imgs output
 
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
+    chmod a+rx "$defs"
 
-    # First, create a disk image and verify its in order
+    echo "*** First, create a disk image and verify its in order ***"
 
-    runas testuser tee "$defs/esp.conf" <<EOF
+    tee "$defs/esp.conf" <<EOF
 [Partition]
 Type=esp
 SizeMinBytes=10M
 Format=vfat
 EOF
 
-    runas testuser tee "$defs/usr.conf" <<EOF
+    tee "$defs/usr.conf" <<EOF
 [Partition]
 Type=usr-${architecture}
 SizeMinBytes=10M
@@ -495,7 +501,7 @@ Format=ext4
 ReadOnly=yes
 EOF
 
-    runas testuser tee "$defs/root.conf" <<EOF
+    tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 SizeMinBytes=10M
@@ -520,22 +526,22 @@ EOF
         return
     fi
 
-    # Then, create another image with CopyBlocks=auto
+    echo "*** Second, create another image with CopyBlocks=auto ***"
 
-    runas testuser tee "$defs/esp.conf" <<EOF
+    tee "$defs/esp.conf" <<EOF
 [Partition]
 Type=esp
 CopyBlocks=auto
 EOF
 
-    runas testuser tee "$defs/usr.conf" <<EOF
+    tee "$defs/usr.conf" <<EOF
 [Partition]
 Type=usr-${architecture}
 ReadOnly=yes
 CopyBlocks=auto
 EOF
 
-    runas testuser tee "$defs/root.conf" <<EOF
+    tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 CopyBlocks=auto
@@ -555,14 +561,15 @@ EOF
 testcase_unaligned_partition() {
     local defs imgs output
 
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
+    chmod a+rx "$defs"
 
-    # Operate on an image with unaligned partition.
+    echo "*** Operate on an image with unaligned partition ***"
 
-    runas testuser tee "$defs/root.conf" <<EOF
+    tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 EOF
@@ -590,14 +597,15 @@ EOF
 testcase_issue_21817() {
     local defs imgs output
 
-    # testcase for #21817
-
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
+    chmod a+rx "$defs"
 
-    runas testuser tee "$defs/test.conf" <<EOF
+    echo "*** testcase for #21817 ***"
+
+    tee "$defs/test.conf" <<EOF
 [Partition]
 Type=root
 EOF
@@ -626,21 +634,22 @@ EOF
 testcase_issue_24553() {
     local defs imgs output
 
-    # testcase for #24553
-
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
+    chmod a+rx "$defs"
+
+    echo "*** testcase for #24553 ***"
 
-    runas testuser tee "$defs/root.conf" <<EOF
+    tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root
 SizeMinBytes=10G
 SizeMaxBytes=120G
 EOF
 
-    runas testuser tee "$imgs/partscript" <<EOF
+    tee "$imgs/partscript" <<EOF
 label: gpt
 label-id: C9FFE979-A415-C449-B729-78C7AA664B10
 unit: sectors
@@ -650,7 +659,7 @@ start=40, size=524288, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, uuid=F2E89C8A-
 start=524328, size=14848000, type=${root_guid}, uuid=${root_uuid}, name="root-${architecture}"
 EOF
 
-    # 1. Operate on a small image compared with SizeMinBytes=.
+    echo "*** 1. Operate on a small image compared with SizeMinBytes= ***"
     runas testuser truncate -s 8g "$imgs/zzz"
     sfdisk "$imgs/zzz" <"$imgs/partscript"
 
@@ -663,7 +672,7 @@ EOF
     output=$(sfdisk --dump "$imgs/zzz")
     assert_in "$imgs/zzz2 : start=      524328, size=    14848000, type=${root_guid}, uuid=${root_uuid}, name=\"root-${architecture}\"" "$output"
 
-    # 2. Operate on an larger image compared with SizeMinBytes=.
+    echo "*** 2. Operate on an larger image compared with SizeMinBytes= ***"
     rm -f "$imgs/zzz"
     runas testuser truncate -s 12g "$imgs/zzz"
     sfdisk "$imgs/zzz" <"$imgs/partscript"
@@ -677,8 +686,8 @@ EOF
     output=$(sfdisk --dump "$imgs/zzz")
     assert_in "$imgs/zzz2 : start=      524328, size=    24641456, type=${root_guid}, uuid=${root_uuid}, name=\"root-${architecture}\"" "$output"
 
-    # 3. Multiple partitions with Priority= (small disk)
-    runas testuser tee "$defs/root.conf" <<EOF
+    echo "*** 3. Multiple partitions with Priority= (small disk) ***"
+    tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root
 SizeMinBytes=10G
@@ -686,7 +695,7 @@ SizeMaxBytes=120G
 Priority=100
 EOF
 
-    runas testuser tee "$defs/usr.conf" <<EOF
+    tee "$defs/usr.conf" <<EOF
 [Partition]
 Type=usr
 SizeMinBytes=10M
@@ -707,7 +716,7 @@ EOF
     assert_in "$imgs/zzz2 : start=      524328, size=    14848000, type=${root_guid}, uuid=${root_uuid}, name=\"root-${architecture}\"" "$output"
     assert_in "$imgs/zzz3 : start=    15372328, size=     1404848, type=${usr_guid}, uuid=${usr_uuid}, name=\"usr-${architecture}\", attrs=\"GUID:59\"" "$output"
 
-    # 4. Multiple partitions with Priority= (large disk)
+    echo "*** 4. Multiple partitions with Priority= (large disk) ***"
     rm -f "$imgs/zzz"
     runas testuser truncate -s 12g "$imgs/zzz"
     sfdisk "$imgs/zzz" <"$imgs/partscript"
@@ -726,14 +735,15 @@ EOF
 testcase_zero_uuid() {
     local defs imgs output
 
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
+    chmod a+rx "$defs"
 
-    # Test image with zero UUID.
+    echo "*** Test image with zero UUID ***"
 
-    runas testuser tee "$defs/root.conf" <<EOF
+    tee "$defs/root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 UUID=null
@@ -754,12 +764,15 @@ EOF
 testcase_verity() {
     local defs imgs output
 
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
+    chmod a+rx "$defs"
 
-    runas testuser tee "$defs/verity-data.conf" <<EOF
+    echo "*** dm-verity ***"
+
+    tee "$defs/verity-data.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 CopyFiles=${defs}
@@ -768,7 +781,7 @@ VerityMatchKey=root
 Minimize=guess
 EOF
 
-    runas testuser tee "$defs/verity-hash.conf" <<EOF
+    tee "$defs/verity-hash.conf" <<EOF
 [Partition]
 Type=root-${architecture}-verity
 Verity=hash
@@ -776,7 +789,7 @@ VerityMatchKey=root
 Minimize=yes
 EOF
 
-    runas testuser tee "$defs/verity-sig.conf" <<EOF
+    tee "$defs/verity-sig.conf" <<EOF
 [Partition]
 Type=root-${architecture}-verity-sig
 Verity=signature
@@ -784,7 +797,7 @@ VerityMatchKey=root
 EOF
 
     # Unfortunately OpenSSL insists on reading some config file, hence provide one with mostly placeholder contents
-    runas testuser tee >"$defs/verity.openssl.cnf" <<EOF
+    tee >"$defs/verity.openssl.cnf" <<EOF
 [ req ]
 prompt = no
 distinguished_name = req_distinguished_name
@@ -799,17 +812,22 @@ CN = Common Name
 emailAddress = test@email.com
 EOF
 
-    runas testuser openssl req -config "$defs/verity.openssl.cnf" \
-                               -new -x509 \
-                               -newkey rsa:1024 \
-                               -keyout "$defs/verity.key" \
-                               -out "$defs/verity.crt" \
-                               -days 365 \
-                               -nodes
+    openssl req \
+            -config "$defs/verity.openssl.cnf" \
+            -new -x509 \
+            -newkey rsa:1024 \
+            -keyout "$defs/verity.key" \
+            -out "$defs/verity.crt" \
+            -days 365 \
+            -nodes
 
     mkdir -p /run/verity.d
     ln -s "$defs/verity.crt" /run/verity.d/ok.crt
 
+    # CopyFiles will fail if we try to chown the target file to root.
+    # Make the files owned by the user so that the invocation below works.
+    chown testuser -R "$defs"
+
     output=$(runas testuser systemd-repart --definitions="$defs" \
                                            --seed="$seed" \
                                            --dry-run=no \
@@ -820,9 +838,9 @@ EOF
                                            --certificate="$defs/verity.crt" \
                                            "$imgs/verity")
 
-    drh=$(jq -r ".[] | select(.type == \"root-${architecture}\") | .roothash" <<< "$output")
-    hrh=$(jq -r ".[] | select(.type == \"root-${architecture}-verity\") | .roothash" <<< "$output")
-    srh=$(jq -r ".[] | select(.type == \"root-${architecture}-verity-sig\") | .roothash" <<< "$output")
+    drh=$(jq -r ".[] | select(.type == \"root-${architecture}\") | .roothash" <<<"$output")
+    hrh=$(jq -r ".[] | select(.type == \"root-${architecture}-verity\") | .roothash" <<<"$output")
+    srh=$(jq -r ".[] | select(.type == \"root-${architecture}-verity-sig\") | .roothash" <<<"$output")
 
     assert_eq "$drh" "$hrh"
     assert_eq "$hrh" "$srh"
@@ -843,40 +861,49 @@ EOF
 testcase_exclude_files() {
     local defs imgs root output
 
-    defs="$(runas testuser mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
-    root="$(runas testuser mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(runas testuser mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
+    root="$(runas testuser mktemp --directory "/var/tmp/test-repart.root.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs' '$root'" RETURN
-
-    runas testuser touch "$root/abc"
-    runas testuser mkdir "$root/usr"
-    runas testuser touch "$root/usr/def"
-    runas testuser touch "$root/usr/qed"
-    runas testuser mkdir "$root/tmp"
-    runas testuser touch "$root/tmp/prs"
-    runas testuser mkdir "$root/proc"
-    runas testuser touch "$root/proc/prs"
-    runas testuser mkdir "$root/zzz"
-    runas testuser mkdir "$root/zzz/usr"
-    runas testuser touch "$root/zzz/usr/prs"
-    runas testuser mkdir "$root/zzz/proc"
-    runas testuser touch "$root/zzz/proc/prs"
-
-    runas testuser tee "$defs/00-root.conf" <<EOF
+    chmod a+rx "$defs"
+
+    echo "*** file exclusion ***"
+
+    touch "$root/abc"
+    mkdir "$root/usr"
+    touch "$root/usr/def"
+    touch "$root/usr/qed"
+    mkdir "$root/tmp"
+    touch "$root/tmp/prs"
+    mkdir "$root/proc"
+    touch "$root/proc/prs"
+    mkdir "$root/zzz"
+    mkdir "$root/zzz/usr"
+    touch "$root/zzz/usr/prs"
+    mkdir "$root/zzz/proc"
+    touch "$root/zzz/proc/prs"
+
+    tee "$defs/00-root.conf" <<EOF
 [Partition]
 Type=root-${architecture}
 CopyFiles=/
 CopyFiles=/zzz:/
+CopyFiles=/:/oiu
+ExcludeFilesTarget=/oiu/usr
 EOF
 
-    runas testuser tee "$defs/10-usr.conf" <<EOF
+    tee "$defs/10-usr.conf" <<EOF
 [Partition]
 Type=usr-${architecture}
 CopyFiles=/usr:/
 ExcludeFiles=/usr/qed
 EOF
 
+    # CopyFiles will fail if we try to chown the target file to root.
+    # Make the files owned by the user so that the invocation below works.
+    chown testuser -R "$root"
+
     output=$(runas testuser systemd-repart --definitions="$defs" \
                                            --seed="$seed" \
                                            --dry-run=no \
@@ -921,6 +948,11 @@ EOF
     # Test that /zzz/usr/prs did not end up in the usr partition.
     assert_rc 2 ls "$imgs/mnt/usr/prs"
 
+    # Test that /oiu/ and /oiu/zzz ended up in the root partition but /oiu/usr did not.
+    assert_rc 0 ls "$imgs/mnt/oiu"
+    assert_rc 0 ls "$imgs/mnt/oiu/zzz"
+    assert_rc 2 ls "$imgs/mnt/oiu/usr"
+
     umount -R "$imgs/mnt"
     losetup -d "$loop"
 }
@@ -933,8 +965,10 @@ testcase_minimize() {
         return
     fi
 
-    defs="$(mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    echo "*** minimization ***"
+
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
 
@@ -987,8 +1021,10 @@ test_sector() {
         return
     fi
 
-    defs="$(mktemp --directory "/tmp/test-repart.XXXXXXXXXX")"
-    imgs="$(mktemp --directory "/var/tmp/test-repart.XXXXXXXXXX")"
+    echo "*** sector sizes ***"
+
+    defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+    imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
     # shellcheck disable=SC2064
     trap "rm -rf '$defs' '$imgs'" RETURN
 
index fb1ccf82d2a5071cae5f782c6ebfe56e2d13942d..de250f7561ff4f6f0c060a0e24a798a071c4e071 100644 (file)
@@ -7,7 +7,7 @@
 
 # See tmpfiles.d(5) for details
 
-d /etc/credstore 0000 root root
-d /etc/credstore.encrypted 0000 root root
-z /run/credstore 0000 root root
-z /run/credstore.encrypted 0000 root root
+d /etc/credstore 0700 root root
+d /etc/credstore.encrypted 0700 root root
+z /run/credstore 0700 root root
+z /run/credstore.encrypted 0700 root root