[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1051545: bookworm-pu: package systemd/252.16-1~deb12u1



Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian.org at packages.debian.org
Usertags: pu
X-Debbugs-Cc: pkg-systemd-maintainers at lists.alioth.debian.org

Dear Release Team,

We would like to upload the latest stable point release of systemd 252
to bookworm-p-u. Stable release branches are maintained upstream with
the intention of providing bug fixes only and no compatibility
breakages, and with automated non-trivial CI jobs that also cover
Debian and Ubuntu. I have already uploaded to p-u.

Debdiff attached. No packaging changes apart from refreshing patches
and adjusting salsa-ci.yml.

-- 
Kind regards,
Luca Boccassi
diff -Nru systemd-252.14/debian/changelog systemd-252.16/debian/changelog
--- systemd-252.14/debian/changelog	2023-08-11 02:42:44.000000000 +0100
+++ systemd-252.16/debian/changelog	2023-09-09 02:24:49.000000000 +0100
@@ -1,3 +1,10 @@
+systemd (252.16-1~deb12u1) bookworm; urgency=medium
+
+  * New upstream version 252.16
+  * Refresh patches for v252.16
+
+ -- Luca Boccassi <bluca@debian.org>  Sat, 09 Sep 2023 02:24:49 +0100
+
 systemd (252.14-1~deb12u1) bookworm; urgency=medium
 
   * New upstream version 252.14
diff -Nru systemd-252.14/debian/patches/p11kit-switch-to-dlopen.patch systemd-252.16/debian/patches/p11kit-switch-to-dlopen.patch
--- systemd-252.14/debian/patches/p11kit-switch-to-dlopen.patch	2023-08-11 02:42:44.000000000 +0100
+++ systemd-252.16/debian/patches/p11kit-switch-to-dlopen.patch	2023-09-09 02:24:18.000000000 +0100
@@ -41,7 +41,7 @@
                    librt,
                    libseccomp,
 diff --git a/src/shared/pkcs11-util.c b/src/shared/pkcs11-util.c
-index f5f6617..4d7edf8 100644
+index 11cdccc..daee267 100644
 --- a/src/shared/pkcs11-util.c
 +++ b/src/shared/pkcs11-util.c
 @@ -3,6 +3,7 @@
diff -Nru systemd-252.14/debian/salsa-ci.yml systemd-252.16/debian/salsa-ci.yml
--- systemd-252.14/debian/salsa-ci.yml	2023-08-11 02:42:44.000000000 +0100
+++ systemd-252.16/debian/salsa-ci.yml	2023-09-09 02:24:49.000000000 +0100
@@ -9,3 +9,4 @@
   # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1011649
   SALSA_CI_DISABLE_PIUPARTS: 1
   RELEASE: 'bookworm'
+  SALSA_CI_LINTIAN_SUPPRESS_TAGS: "bad-distribution-in-changes-file"
diff -Nru systemd-252.14/man/coredump.conf.xml systemd-252.16/man/coredump.conf.xml
--- systemd-252.14/man/coredump.conf.xml	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/man/coredump.conf.xml	2023-09-09 02:21:12.000000000 +0100
@@ -57,18 +57,22 @@
         <term><varname>Storage=</varname></term>
 
         <listitem><para>Controls where to store cores. One of <literal>none</literal>,
-        <literal>external</literal>, and <literal>journal</literal>. When
-        <literal>none</literal>, the core dumps may be logged (including the backtrace if
-        possible), but not stored permanently. When <literal>external</literal> (the
-        default), cores will be stored in <filename>/var/lib/systemd/coredump/</filename>.
-        When <literal>journal</literal>, cores will be stored in the journal and rotated
-        following normal journal rotation patterns.</para>
+        <literal>external</literal>, and <literal>journal</literal>. When <literal>none</literal>, the core
+        dumps may be logged (including the backtrace if possible), but not stored permanently. When
+        <literal>external</literal> (the default), cores will be stored in
+        <filename>/var/lib/systemd/coredump/</filename>.  When <literal>journal</literal>, cores will be
+        stored in the journal and rotated following normal journal rotation patterns.</para>
 
-        <para>When cores are stored in the journal, they might be
-        compressed following journal compression settings, see
+        <para>When cores are stored in the journal, they might be compressed following journal compression
+        settings, see
         <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
-        When cores are stored externally, they will be compressed
-        by default, see below.</para></listitem>
+        When cores are stored externally, they will be compressed by default, see below.</para>
+
+        <para>Note that in order to process a coredump (i.e. extract a stack trace) the core must be written
+        to disk first. Thus, unless <varname>ProcessSizeMax=</varname> is set to 0 (see below), the core will
+        be written to <filename>/var/lib/systemd/coredump/</filename> either way (under a temporary filename,
+        or even in an unlinked file), <varname>Storage=</varname> thus only controls whether to leave it
+        there even after it was processed.</para></listitem>
       </varlistentry>
 
       <varlistentry>
@@ -84,7 +88,7 @@
         <term><varname>ProcessSizeMax=</varname></term>
 
         <listitem><para>The maximum size in bytes of a core which will be processed. Core dumps exceeding
-        this size may be stored, but the backtrace will not be generated.  Like other sizes in this same
+        this size may be stored, but the stack trace will not be generated.  Like other sizes in this same
         config file, the usual suffixes to the base of 1024 are allowed (B, K, M, G, T, P, and E). Defaults
         to 1G on 32bit systems, 32G on 64bit systems.</para>
 
diff -Nru systemd-252.14/man/daemon.xml systemd-252.16/man/daemon.xml
--- systemd-252.14/man/daemon.xml	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/man/daemon.xml	2023-09-09 02:21:12.000000000 +0100
@@ -553,7 +553,7 @@
       unit installation path during source
       configuration:</para>
 
-      <programlisting>PKG_PROG_PKG_CONFIG
+      <programlisting>PKG_PROG_PKG_CONFIG()
 AC_ARG_WITH([systemdsystemunitdir],
      [AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
      [with_systemdsystemunitdir=auto])
diff -Nru systemd-252.14/man/systemd-gpt-auto-generator.xml systemd-252.16/man/systemd-gpt-auto-generator.xml
--- systemd-252.14/man/systemd-gpt-auto-generator.xml	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/man/systemd-gpt-auto-generator.xml	2023-09-09 02:21:12.000000000 +0100
@@ -238,7 +238,8 @@
         <term><varname>rd.systemd.gpt_auto</varname></term>
 
         <listitem><para>Those options take an optional boolean argument, and default to yes.
-        The generator is enabled by default, and a negative value may be used to disable it.
+        The generator is enabled by default, and a false value may be used to disable it
+        (e.g. <literal>systemd.gpt_auto=0</literal>).
         </para></listitem>
       </varlistentry>
 
diff -Nru systemd-252.14/man/systemd-logind.service.xml systemd-252.16/man/systemd-logind.service.xml
--- systemd-252.14/man/systemd-logind.service.xml	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/man/systemd-logind.service.xml	2023-09-09 02:21:12.000000000 +0100
@@ -43,26 +43,26 @@
       used.</para></listitem>
 
       <listitem><para>Providing <ulink
-      url="https://www.freedesktop.org/wiki/Software/polkit";>polkit</ulink>-based
-      access for users for operations such as system shutdown or sleep</para>
+      url="https://www.freedesktop.org/wiki/Software/polkit";>polkit</ulink>-based access for users for
+      operations such as system shutdown or sleep</para>
       </listitem>
 
-      <listitem><para>Implementing a shutdown/sleep inhibition logic
-      for applications</para></listitem>
+      <listitem><para>Implementing a shutdown/sleep inhibition logic for applications</para></listitem>
 
-      <listitem><para>Handling of power/sleep hardware
-      keys</para></listitem>
+      <listitem><para>Handling of power/sleep hardware keys</para></listitem>
 
       <listitem><para>Multi-seat management</para></listitem>
 
       <listitem><para>Session switch management</para></listitem>
 
-      <listitem><para>Device access management for
-      users</para></listitem>
+      <listitem><para>Device access management for users</para></listitem>
 
-      <listitem><para>Automatic spawning of text logins (gettys) on
-      virtual console activation and user runtime directory
-      management</para></listitem>
+      <listitem><para>Automatic spawning of text logins (gettys) on virtual console activation and user
+      runtime directory management</para></listitem>
+
+      <listitem><para>Scheduled shutdown</para></listitem>
+
+      <listitem><para>Sending "wall" messages</para></listitem>
     </itemizedlist>
 
     <para>User sessions are registered with logind via the
diff -Nru systemd-252.14/.packit.yml systemd-252.16/.packit.yml
--- systemd-252.14/.packit.yml	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/.packit.yml	2023-09-09 02:21:12.000000000 +0100
@@ -17,8 +17,8 @@
 
 actions:
   post-upstream-clone:
-    # Use the Fedora Rawhide specfile
-    - "git clone https://src.fedoraproject.org/rpms/systemd .packit_rpm --depth=1"
+    # Use the Fedora 38 specfile
+    - "git clone --branch f38 https://src.fedoraproject.org/rpms/systemd .packit_rpm --depth=1"
     # Drop the "sources" file so rebase-helper doesn't think we're a dist-git
     - "rm -fv .packit_rpm/sources"
     # Drop backported patches from the specfile, but keep the downstream-only ones
@@ -47,8 +47,8 @@
 - job: copr_build
   trigger: pull_request
   targets:
-  - fedora-rawhide-aarch64
-  - fedora-rawhide-i386
-  - fedora-rawhide-ppc64le
-  - fedora-rawhide-s390x
-  - fedora-rawhide-x86_64
+  - fedora-38-aarch64
+  - fedora-38-i386
+  - fedora-38-ppc64le
+  - fedora-38-s390x
+  - fedora-38-x86_64
diff -Nru systemd-252.14/rules.d/50-udev-default.rules.in systemd-252.16/rules.d/50-udev-default.rules.in
--- systemd-252.14/rules.d/50-udev-default.rules.in	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/rules.d/50-udev-default.rules.in	2023-09-09 02:21:12.000000000 +0100
@@ -17,6 +17,15 @@
 SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
 ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
 
+# Before c43ff248f94266cfc93e300a2d3d163ed805e55b, the following line in
+# 60-drm.rules also sets ID_PATH for all pci, usb, and platform devices:
+####
+# ACTION!="remove", SUBSYSTEM=="drm", SUBSYSTEMS=="pci|usb|platform", IMPORT{builtin}="path_id"
+####
+# Unfortunately, some existing rules already rely on the unexpected behavior.
+# To keep the backward compatibility, let's set ID_PATH for them.
+SUBSYSTEM=="pci|usb|platform", IMPORT{builtin}="path_id"
+
 ACTION!="add", GOTO="default_end"
 
 SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666"
diff -Nru systemd-252.14/rules.d/99-systemd.rules.in systemd-252.16/rules.d/99-systemd.rules.in
--- systemd-252.14/rules.d/99-systemd.rules.in	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/rules.d/99-systemd.rules.in	2023-09-09 02:21:12.000000000 +0100
@@ -12,6 +12,8 @@
 SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270/tty[0-9]*", TAG+="systemd"
 KERNEL=="vport*", TAG+="systemd"
 
+SUBSYSTEM=="ptp", TAG+="systemd"
+
 SUBSYSTEM=="ubi", TAG+="systemd"
 
 SUBSYSTEM=="block", TAG+="systemd"
diff -Nru systemd-252.14/shell-completion/bash/systemctl.in systemd-252.16/shell-completion/bash/systemctl.in
--- systemd-252.14/shell-completion/bash/systemctl.in	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/shell-completion/bash/systemctl.in	2023-09-09 02:21:12.000000000 +0100
@@ -1,4 +1,5 @@
 # systemctl(1) completion                                 -*- shell-script -*-
+# vi: ft=sh
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
 # This file is part of systemd.
@@ -103,21 +104,22 @@
         } | sort -u )
 }
 
-__get_failed_units   () { __systemctl $1 list-units "$2*"      \
-                              | { while read -r a b c d; do [[ $c == "failed"   ]] && echo " $a"; done; }; }
-__get_enabled_units  () { __systemctl $1 list-unit-files "$2*" \
-                              | { while read -r a b c  ; do [[ $b == "enabled"  ]] && echo " $a"; done; }; }
-__get_disabled_units () { __systemctl $1 list-unit-files "$2*" \
-                              | { while read -r a b c  ; do [[ $b == "disabled" ]] && echo " $a"; done; }; }
-__get_masked_units   () { __systemctl $1 list-unit-files "$2*" \
-                              | { while read -r a b c  ; do [[ $b == "masked"   ]] && echo " $a"; done; }; }
-__get_all_unit_files () { { __systemctl $1 list-unit-files "$2*"; } | { while read -r a b; do echo " $a"; done; }; }
+__get_failed_units()   { __systemctl $1 list-units "$2*"      \
+                              | while read -r a b c d; do [[ $c == "failed" ]] && echo " $a"; done; }
+__get_enabled_units()  { __systemctl $1 list-unit-files "$2*" \
+                              | while read -r a b c  ; do [[ $b == "enabled" ]] && echo " $a"; done; }
+__get_disabled_units() { __systemctl $1 list-unit-files "$2*" \
+                              | while read -r a b c  ; do [[ $b == "disabled" ]] && echo " $a"; done; }
+__get_masked_units()   { __systemctl $1 list-unit-files "$2*" \
+                              | while read -r a b c  ; do [[ $b == "masked" ]] && echo " $a"; done; }
+__get_all_unit_files() { __systemctl $1 list-unit-files "$2*" | while read -r a b; do echo " $a"; done; }
 
 __get_machines() {
-    local a b
-    { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
-	{ while read a b; do echo " $a"; done; } | \
-        sort -u
+    local a
+
+    while read a _; do
+        echo " $a"
+    done < <(machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null | sort -u; echo ".host")
 }
 
 _systemctl () {
diff -Nru systemd-252.14/src/basic/path-util.c systemd-252.16/src/basic/path-util.c
--- systemd-252.14/src/basic/path-util.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/basic/path-util.c	2023-09-09 02:21:12.000000000 +0100
@@ -346,8 +346,8 @@
         return strv_uniq(l);
 }
 
-char *path_simplify(char *path) {
-        bool add_slash = false;
+char *path_simplify_full(char *path, PathSimplifyFlags flags) {
+        bool add_slash = false, keep_trailing_slash;
         char *f = ASSERT_PTR(path);
         int r;
 
@@ -361,6 +361,8 @@
         if (isempty(path))
                 return path;
 
+        keep_trailing_slash = FLAGS_SET(flags, PATH_SIMPLIFY_KEEP_TRAILING_SLASH) && endswith(path, "/");
+
         if (path_is_absolute(path))
                 f++;
 
@@ -390,6 +392,9 @@
         if (f == path)
                 *f++ = '.';
 
+        if (*(f-1) != '/' && keep_trailing_slash)
+                *f++ = '/';
+
         *f = '\0';
         return path;
 }
diff -Nru systemd-252.14/src/basic/path-util.h systemd-252.16/src/basic/path-util.h
--- systemd-252.14/src/basic/path-util.h	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/basic/path-util.h	2023-09-09 02:21:12.000000000 +0100
@@ -80,7 +80,14 @@
 #define path_extend(x, ...) path_extend_internal(x, __VA_ARGS__, POINTER_MAX)
 #define path_join(...) path_extend_internal(NULL, __VA_ARGS__, POINTER_MAX)
 
-char* path_simplify(char *path);
+typedef enum PathSimplifyFlags {
+        PATH_SIMPLIFY_KEEP_TRAILING_SLASH = 1 << 0,
+} PathSimplifyFlags;
+
+char *path_simplify_full(char *path, PathSimplifyFlags flags);
+static inline char* path_simplify(char *path) {
+        return path_simplify_full(path, 0);
+}
 
 static inline bool path_equal_ptr(const char *a, const char *b) {
         return !!a == !!b && (!a || path_equal(a, b));
diff -Nru systemd-252.14/src/basic/rlimit-util.c systemd-252.16/src/basic/rlimit-util.c
--- systemd-252.14/src/basic/rlimit-util.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/basic/rlimit-util.c	2023-09-09 02:21:12.000000000 +0100
@@ -401,7 +401,11 @@
         if (rl.rlim_cur <= FD_SETSIZE)
                 return 0;
 
-        rl.rlim_cur = FD_SETSIZE;
+        /* So we might have inherited a hard limit that's larger than the kernel's maximum limit as stored in
+         * /proc/sys/fs/nr_open. If we pass this hard limit unmodified to setrlimit(), we'll get EPERM. To
+         * make sure that doesn't happen, let's limit our hard limit to the value from nr_open. */
+        rl.rlim_max = MIN(rl.rlim_max, (rlim_t) read_nr_open());
+        rl.rlim_cur = MIN((rlim_t) FD_SETSIZE, rl.rlim_max);
         if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
                 return log_debug_errno(errno, "Failed to lower RLIMIT_NOFILE's soft limit to " RLIM_FMT ": %m", rl.rlim_cur);
 
diff -Nru systemd-252.14/src/boot/efi/boot.c systemd-252.16/src/boot/efi/boot.c
--- systemd-252.14/src/boot/efi/boot.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/boot/efi/boot.c	2023-09-09 02:21:12.000000000 +0100
@@ -919,17 +919,21 @@
                 case KEYPRESS(0, 0, 'e'):
                 case KEYPRESS(0, 0, 'E'):
                         /* only the options of configured entries can be edited */
-                        if (!config->editor || !IN_SET(config->entries[idx_highlight]->type,
-                            LOADER_EFI, LOADER_LINUX, LOADER_UNIFIED_LINUX))
+                        if (!config->editor ||
+                            !IN_SET(config->entries[idx_highlight]->type, LOADER_EFI, LOADER_LINUX, LOADER_UNIFIED_LINUX)) {
+                                status = xstrdup16(u"Entry does not support editing the command line.");
                                 break;
+                        }
 
                         /* Unified kernels that are signed as a whole will not accept command line options
                          * when secure boot is enabled unless there is none embedded in the image. Do not try
                          * to pretend we can edit it to only have it be ignored. */
                         if (config->entries[idx_highlight]->type == LOADER_UNIFIED_LINUX &&
                             secure_boot_enabled() &&
-                            config->entries[idx_highlight]->options)
+                            config->entries[idx_highlight]->options) {
+                                status = xstrdup16(u"Entry not editable in SecureBoot mode.");
                                 break;
+                        }
 
                         /* The edit line may end up on the last line of the screen. And even though we're
                          * not telling the firmware to advance the line, it still does in this one case,
diff -Nru systemd-252.14/src/core/execute.c systemd-252.16/src/core/execute.c
--- systemd-252.14/src/core/execute.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/core/execute.c	2023-09-09 02:21:12.000000000 +0100
@@ -4256,6 +4256,7 @@
                                 *exit_status = EXIT_SUCCESS;
                                 return 0;
                         }
+
                         *exit_status = EXIT_CONFIRM;
                         return log_unit_error_errno(unit, SYNTHETIC_ERRNO(ECANCELED),
                                                     "Execution cancelled by the user");
@@ -4426,14 +4427,18 @@
                 r = set_coredump_filter(context->coredump_filter);
                 if (ERRNO_IS_PRIVILEGE(r))
                         log_unit_debug_errno(unit, r, "Failed to adjust coredump_filter, ignoring: %m");
-                else if (r < 0)
+                else if (r < 0) {
+                        *exit_status = EXIT_LIMITS;
                         return log_unit_error_errno(unit, r, "Failed to adjust coredump_filter: %m");
+                }
         }
 
         if (context->nice_set) {
                 r = setpriority_closest(context->nice);
-                if (r < 0)
+                if (r < 0) {
+                        *exit_status = EXIT_NICE;
                         return log_unit_error_errno(unit, r, "Failed to set up process scheduling priority (nice level): %m");
+                }
         }
 
         if (context->cpu_sched_set) {
@@ -4797,11 +4802,11 @@
                                               LOG_UNIT_MESSAGE(unit, "Executable %s missing, skipping: %m",
                                                                command->path),
                                               "EXECUTABLE=%s", command->path);
+                        *exit_status = EXIT_SUCCESS;
                         return 0;
                 }
 
                 *exit_status = EXIT_EXEC;
-
                 return log_unit_struct_errno(unit, LOG_INFO, r,
                                              "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
                                              LOG_UNIT_INVOCATION_ID(unit),
@@ -5267,7 +5272,7 @@
                 return log_unit_error_errno(unit, errno, "Failed to fork: %m");
 
         if (pid == 0) {
-                int exit_status = EXIT_SUCCESS;
+                int exit_status;
 
                 r = exec_child(unit,
                                command,
@@ -5285,9 +5290,8 @@
                                &exit_status);
 
                 if (r < 0) {
-                        const char *status =
-                                exit_status_to_string(exit_status,
-                                                      EXIT_STATUS_LIBC | EXIT_STATUS_SYSTEMD);
+                        const char *status = ASSERT_PTR(
+                                        exit_status_to_string(exit_status, EXIT_STATUS_LIBC | EXIT_STATUS_SYSTEMD));
 
                         log_unit_struct_errno(unit, LOG_ERR, r,
                                               "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
@@ -5295,7 +5299,8 @@
                                               LOG_UNIT_MESSAGE(unit, "Failed at step %s spawning %s: %m",
                                                                status, command->path),
                                               "EXECUTABLE=%s", command->path);
-                }
+                } else
+                        assert(exit_status == EXIT_SUCCESS);
 
                 _exit(exit_status);
         }
diff -Nru systemd-252.14/src/core/mount.c systemd-252.16/src/core/mount.c
--- systemd-252.14/src/core/mount.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/core/mount.c	2023-09-09 02:21:12.000000000 +0100
@@ -201,6 +201,9 @@
 
         assert(m);
 
+        if (usec == USEC_INFINITY)
+                return sd_event_source_set_enabled(m->timer_event_source, SD_EVENT_OFF);
+
         if (m->timer_event_source) {
                 r = sd_event_source_set_time(m->timer_event_source, usec);
                 if (r < 0)
@@ -209,9 +212,6 @@
                 return sd_event_source_set_enabled(m->timer_event_source, SD_EVENT_ONESHOT);
         }
 
-        if (usec == USEC_INFINITY)
-                return 0;
-
         r = sd_event_add_time(
                         UNIT(m)->manager->event,
                         &m->timer_event_source,
diff -Nru systemd-252.14/src/coredump/coredump.c systemd-252.16/src/coredump/coredump.c
--- systemd-252.14/src/coredump/coredump.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/coredump/coredump.c	2023-09-09 02:21:12.000000000 +0100
@@ -1532,7 +1532,7 @@
 
                 r = iovw_put_string_field(iovw, "MESSAGE=", message);
                 if (r < 0)
-                        return r;
+                        goto finish;
         } else {
                 /* The imported iovecs are not supposed to be freed by us so let's store
                  * them at the end of the array so we can skip them while freeing the
diff -Nru systemd-252.14/src/debug-generator/debug-generator.c systemd-252.16/src/debug-generator/debug-generator.c
--- systemd-252.14/src/debug-generator/debug-generator.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/debug-generator/debug-generator.c	2023-09-09 02:21:12.000000000 +0100
@@ -111,7 +111,7 @@
         int r = 0;
 
         STRV_FOREACH(u, arg_wants) {
-                _cleanup_free_ char *p = NULL, *f = NULL;
+                _cleanup_free_ char *f = NULL;
                 const char *target;
 
                 /* This should match what do_queue_default_job() in core/main.c does. */
@@ -122,20 +122,13 @@
                 else
                         target = SPECIAL_DEFAULT_TARGET;
 
-                p = strjoin(arg_dest, "/", target, ".wants/", *u);
-                if (!p)
-                        return log_oom();
-
                 f = path_join(SYSTEM_DATA_UNIT_DIR, *u);
                 if (!f)
                         return log_oom();
 
-                (void) mkdir_parents_label(p, 0755);
-
-                if (symlink(f, p) < 0)
-                        r = log_error_errno(errno,
-                                            "Failed to create wants symlink %s: %m",
-                                            p);
+                r = generator_add_symlink(arg_dest, target, "wants", f);
+                if (r < 0)
+                        return r;
         }
 
         return r;
diff -Nru systemd-252.14/src/home/homework-luks.c systemd-252.16/src/home/homework-luks.c
--- systemd-252.14/src/home/homework-luks.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/home/homework-luks.c	2023-09-09 02:21:12.000000000 +0100
@@ -608,7 +608,7 @@
                 sd_id128_t *ret_found_uuid) {
 
         _cleanup_free_ char *fstype = NULL;
-        sd_id128_t u;
+        sd_id128_t u = SD_ID128_NULL; /* avoid false maybe-unitialized warning */
         int r;
 
         assert(dm_node);
diff -Nru systemd-252.14/src/hostname/hostnamed.c systemd-252.16/src/hostname/hostnamed.c
--- systemd-252.14/src/hostname/hostnamed.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/hostname/hostnamed.c	2023-09-09 02:21:12.000000000 +0100
@@ -1194,7 +1194,7 @@
                         false,
                         UID_INVALID,
                         &c->polkit_registry,
-                        NULL);
+                        error);
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
diff -Nru systemd-252.14/src/libsystemd-network/fuzz-ndisc-rs.c systemd-252.16/src/libsystemd-network/fuzz-ndisc-rs.c
--- systemd-252.14/src/libsystemd-network/fuzz-ndisc-rs.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/libsystemd-network/fuzz-ndisc-rs.c	2023-09-09 02:21:12.000000000 +0100
@@ -22,12 +22,27 @@
         return -ENOSYS;
 }
 
-int icmp6_receive(int fd, void *iov_base, size_t iov_len,
-                  struct in6_addr *dst, triple_timestamp *timestamp) {
+static struct in6_addr dummy_link_local = {
+        .s6_addr = {
+                0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x12, 0x34, 0x56, 0xff, 0xfe, 0x78, 0x9a, 0xbc,
+        },
+};
+
+int icmp6_receive(
+                int fd,
+                void *iov_base,
+                size_t iov_len,
+                struct in6_addr *ret_sender,
+                triple_timestamp *ret_timestamp) {
+
         assert_se(read(fd, iov_base, iov_len) == (ssize_t) iov_len);
 
-        if (timestamp)
-                triple_timestamp_get(timestamp);
+        if (ret_timestamp)
+                triple_timestamp_get(ret_timestamp);
+
+        if (ret_sender)
+                *ret_sender = dummy_link_local;
 
         return 0;
 }
diff -Nru systemd-252.14/src/libsystemd-network/icmp6-util.c systemd-252.16/src/libsystemd-network/icmp6-util.c
--- systemd-252.14/src/libsystemd-network/icmp6-util.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/libsystemd-network/icmp6-util.c	2023-09-09 02:21:12.000000000 +0100
@@ -144,8 +144,12 @@
         return 0;
 }
 
-int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
-                  triple_timestamp *ret_timestamp) {
+int icmp6_receive(
+                int fd,
+                void *buffer,
+                size_t size,
+                struct in6_addr *ret_sender,
+                triple_timestamp *ret_timestamp) {
 
         /* This needs to be initialized with zero. See #20741. */
         CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */
@@ -178,7 +182,7 @@
             sa.in6.sin6_family == AF_INET6)  {
 
                 addr = sa.in6.sin6_addr;
-                if (!in6_addr_is_link_local(&addr))
+                if (!in6_addr_is_link_local(&addr) && !in6_addr_is_null(&addr))
                         return -EADDRNOTAVAIL;
 
         } else if (msg.msg_namelen > 0)
@@ -204,10 +208,14 @@
                         triple_timestamp_from_realtime(&t, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
         }
 
-        if (!triple_timestamp_is_set(&t))
-                triple_timestamp_get(&t);
+        if (ret_timestamp) {
+                if (triple_timestamp_is_set(&t))
+                        *ret_timestamp = t;
+                else
+                        triple_timestamp_get(ret_timestamp);
+        }
 
-        *ret_dst = addr;
-        *ret_timestamp = t;
+        if (ret_sender)
+                *ret_sender = addr;
         return 0;
 }
diff -Nru systemd-252.14/src/libsystemd-network/icmp6-util.h systemd-252.16/src/libsystemd-network/icmp6-util.h
--- systemd-252.14/src/libsystemd-network/icmp6-util.h	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/libsystemd-network/icmp6-util.h	2023-09-09 02:21:12.000000000 +0100
@@ -20,5 +20,9 @@
 int icmp6_bind_router_solicitation(int ifindex);
 int icmp6_bind_router_advertisement(int ifindex);
 int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
-int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
-                  triple_timestamp *ret_timestamp);
+int icmp6_receive(
+                int fd,
+                void *buffer,
+                size_t size,
+                struct in6_addr *ret_sender,
+                triple_timestamp *ret_timestamp);
diff -Nru systemd-252.14/src/libsystemd-network/sd-ndisc.c systemd-252.16/src/libsystemd-network/sd-ndisc.c
--- systemd-252.14/src/libsystemd-network/sd-ndisc.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/libsystemd-network/sd-ndisc.c	2023-09-09 02:21:12.000000000 +0100
@@ -227,8 +227,7 @@
 
                 switch (r) {
                 case -EADDRNOTAVAIL:
-                        log_ndisc(nd, "Received RA from non-link-local address %s. Ignoring.",
-                                  IN6_ADDR_TO_STRING(&rt->address));
+                        log_ndisc(nd, "Received RA from neither link-local nor null address. Ignoring.");
                         break;
 
                 case -EMULTIHOP:
@@ -247,6 +246,11 @@
                 return 0;
         }
 
+        /* The function icmp6_receive() accepts the null source address, but RFC 4861 Section 6.1.2 states
+         * that hosts MUST discard messages with the null source address. */
+        if (in6_addr_is_null(&rt->address))
+                log_ndisc(nd, "Received RA from null address. Ignoring.");
+
         (void) event_source_disable(nd->timeout_event_source);
         (void) ndisc_handle_datagram(nd, rt);
         return 0;
diff -Nru systemd-252.14/src/libsystemd-network/sd-radv.c systemd-252.16/src/libsystemd-network/sd-radv.c
--- systemd-252.14/src/libsystemd-network/sd-radv.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/libsystemd-network/sd-radv.c	2023-09-09 02:21:12.000000000 +0100
@@ -271,8 +271,7 @@
 
                 switch (r) {
                 case -EADDRNOTAVAIL:
-                        log_radv(ra, "Received RS from non-link-local address %s. Ignoring",
-                                 IN6_ADDR_TO_STRING(&src));
+                        log_radv(ra, "Received RS from neither link-local nor null address. Ignoring");
                         break;
 
                 case -EMULTIHOP:
@@ -296,6 +295,9 @@
                 return 0;
         }
 
+        /* TODO: if the sender address is null, check that the message does not have the source link-layer
+         * address option. See RFC 4861 Section 6.1.1. */
+
         const char *addr = IN6_ADDR_TO_STRING(&src);
 
         r = radv_send(ra, &src, ra->lifetime_usec);
diff -Nru systemd-252.14/src/libsystemd-network/test-ndisc-ra.c systemd-252.16/src/libsystemd-network/test-ndisc-ra.c
--- systemd-252.14/src/libsystemd-network/test-ndisc-ra.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/libsystemd-network/test-ndisc-ra.c	2023-09-09 02:21:12.000000000 +0100
@@ -223,12 +223,17 @@
         return 0;
 }
 
-int icmp6_receive(int fd, void *iov_base, size_t iov_len,
-                  struct in6_addr *dst, triple_timestamp *timestamp) {
+int icmp6_receive(
+                int fd,
+                void *iov_base,
+                size_t iov_len,
+                struct in6_addr *ret_sender,
+                triple_timestamp *ret_timestamp) {
+
         assert_se(read (fd, iov_base, iov_len) == (ssize_t)iov_len);
 
-        if (timestamp)
-                triple_timestamp_get(timestamp);
+        if (ret_timestamp)
+                triple_timestamp_get(ret_timestamp);
 
         return 0;
 }
diff -Nru systemd-252.14/src/libsystemd-network/test-ndisc-rs.c systemd-252.16/src/libsystemd-network/test-ndisc-rs.c
--- systemd-252.14/src/libsystemd-network/test-ndisc-rs.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/libsystemd-network/test-ndisc-rs.c	2023-09-09 02:21:12.000000000 +0100
@@ -41,7 +41,8 @@
         assert_se(rt);
 
         log_info("--");
-        assert_se(sd_ndisc_router_get_address(rt, &addr) == -ENODATA);
+        assert_se(sd_ndisc_router_get_address(rt, &addr) >= 0);
+        log_info("Sender: %s", IN6_ADDR_TO_STRING(&addr));
 
         assert_se(sd_ndisc_router_get_timestamp(rt, CLOCK_REALTIME, &t) >= 0);
         log_info("Timestamp: %s", FORMAT_TIMESTAMP(t));
@@ -176,12 +177,27 @@
         return -ENOSYS;
 }
 
-int icmp6_receive(int fd, void *iov_base, size_t iov_len,
-                  struct in6_addr *dst, triple_timestamp *timestamp) {
+static struct in6_addr dummy_link_local = {
+        .s6_addr = {
+                0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x12, 0x34, 0x56, 0xff, 0xfe, 0x78, 0x9a, 0xbc,
+        },
+};
+
+int icmp6_receive(
+                int fd,
+                void *iov_base,
+                size_t iov_len,
+                struct in6_addr *ret_sender,
+                triple_timestamp *ret_timestamp) {
+
         assert_se(read (fd, iov_base, iov_len) == (ssize_t)iov_len);
 
-        if (timestamp)
-                triple_timestamp_get(timestamp);
+        if (ret_timestamp)
+                triple_timestamp_get(ret_timestamp);
+
+        if (ret_sender)
+                *ret_sender = dummy_link_local;
 
         return 0;
 }
diff -Nru systemd-252.14/src/libudev/test-libudev.c systemd-252.16/src/libudev/test-libudev.c
--- systemd-252.14/src/libudev/test-libudev.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/libudev/test-libudev.c	2023-09-09 02:21:12.000000000 +0100
@@ -171,7 +171,7 @@
 }
 
 static void test_monitor(struct udev *udev) {
-        _cleanup_(udev_monitor_unrefp) struct udev_monitor *udev_monitor;
+        _cleanup_(udev_monitor_unrefp) struct udev_monitor *udev_monitor = NULL;
         _cleanup_close_ int fd_ep = -EBADF;
         int fd_udev;
         struct epoll_event ep_udev = {
diff -Nru systemd-252.14/src/login/logind-dbus.c systemd-252.16/src/login/logind-dbus.c
--- systemd-252.14/src/login/logind-dbus.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/login/logind-dbus.c	2023-09-09 02:21:12.000000000 +0100
@@ -1325,7 +1325,7 @@
         return 0;
 }
 
-static int attach_device(Manager *m, const char *seat, const char *sysfs) {
+static int attach_device(Manager *m, const char *seat, const char *sysfs, sd_bus_error *error) {
         _cleanup_(sd_device_unrefp) sd_device *d = NULL;
         _cleanup_free_ char *rule = NULL, *file = NULL;
         const char *id_for_seat;
@@ -1337,13 +1337,13 @@
 
         r = sd_device_new_from_syspath(&d, sysfs);
         if (r < 0)
-                return r;
+                return sd_bus_error_set_errnof(error, r, "Failed to open device '%s': %m", sysfs);
 
         if (sd_device_has_current_tag(d, "seat") <= 0)
-                return -ENODEV;
+                return sd_bus_error_set_errnof(error, ENODEV, "Device '%s' lacks 'seat' udev tag.", sysfs);
 
         if (sd_device_get_property_value(d, "ID_FOR_SEAT", &id_for_seat) < 0)
-                return -ENODEV;
+                return sd_bus_error_set_errnof(error, ENODEV, "Device '%s' lacks 'ID_FOR_SEAT' udev property.", sysfs);
 
         if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
                 return -ENOMEM;
@@ -1428,7 +1428,7 @@
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        r = attach_device(m, seat, sysfs);
+        r = attach_device(m, seat, sysfs, error);
         if (r < 0)
                 return r;
 
diff -Nru systemd-252.14/src/login/logind-session.c systemd-252.16/src/login/logind-session.c
--- systemd-252.14/src/login/logind-session.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/login/logind-session.c	2023-09-09 02:21:12.000000000 +0100
@@ -1397,6 +1397,23 @@
 
         session_device_pause_all(s);
         r = vt_release(s->vtfd, false);
+        if (r == -EIO) {
+                int vt, old_fd;
+
+                /* It might happen if the controlling process exited before or while we were
+                 * restoring the VT as it would leave the old file-descriptor in a hung-up
+                 * state. In this case let's retry with a fresh handle to the virtual terminal. */
+
+                /* We do a little dance to avoid having the terminal be available
+                 * for reuse before we've cleaned it up. */
+                old_fd = TAKE_FD(s->vtfd);
+
+                vt = session_open_vt(s);
+                safe_close(old_fd);
+
+                if (vt >= 0)
+                        r = vt_release(vt, false);
+        }
         if (r < 0)
                 log_debug_errno(r, "Cannot release VT of session %s: %m", s->id);
 }
diff -Nru systemd-252.14/src/network/wait-online/manager.c systemd-252.16/src/network/wait-online/manager.c
--- systemd-252.14/src/network/wait-online/manager.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/network/wait-online/manager.c	2023-09-09 02:21:12.000000000 +0100
@@ -41,9 +41,11 @@
         assert(l);
 
         /* This returns the following:
-         * -EAGAIN: not processed by udev or networkd
-         *       0: operstate is not enough
-         *       1: online */
+         * -EAGAIN       : not processed by udev
+         * -EBUSY        : being processed by networkd
+         * -EADDRNOTAVAIL: requested conditions (operstate and/or addresses) are not satisfied
+         * false         : unmanaged
+         * true          : online */
 
         if (!l->state || streq(l->state, "pending"))
                 /* If no state string exists, networkd (and possibly also udevd) has not detected the
@@ -59,13 +61,13 @@
                 /* If the link is in unmanaged state, then ignore the interface unless the interface is
                  * specified in '--interface/-i' option. */
                 if (!hashmap_contains(m->command_line_interfaces_by_name, l->ifname)) {
-                        log_link_debug(l, "link is not managed by networkd (yet?).");
-                        return 0;
+                        log_link_debug(l, "link is not managed by networkd.");
+                        return false;
                 }
 
         } else if (!streq(l->state, "configured"))
                 /* If the link is in non-configured state, return negative value here. */
-                return log_link_debug_errno(l, SYNTHETIC_ERRNO(EAGAIN),
+                return log_link_debug_errno(l, SYNTHETIC_ERRNO(EBUSY),
                                             "link is being processed by networkd: setup state is %s.",
                                             l->state);
 
@@ -77,84 +79,76 @@
                 s.max = m->required_operstate.max >= 0 ? m->required_operstate.max
                                                        : l->required_operstate.max;
 
-        if (l->operational_state < s.min || l->operational_state > s.max) {
-                log_link_debug(l, "Operational state '%s' is not in range ['%s':'%s']",
-                               link_operstate_to_string(l->operational_state),
-                               link_operstate_to_string(s.min), link_operstate_to_string(s.max));
-                return 0;
-        }
+        if (l->operational_state < s.min || l->operational_state > s.max)
+                return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+                                            "Operational state '%s' is not in range ['%s':'%s']",
+                                            link_operstate_to_string(l->operational_state),
+                                            link_operstate_to_string(s.min), link_operstate_to_string(s.max));
 
         required_family = m->required_family > 0 ? m->required_family : l->required_family;
         needs_ipv4 = required_family & ADDRESS_FAMILY_IPV4;
         needs_ipv6 = required_family & ADDRESS_FAMILY_IPV6;
 
         if (s.min < LINK_OPERSTATE_ROUTABLE) {
-                if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_DEGRADED) {
-                        log_link_debug(l, "No routable or link-local IPv4 address is configured.");
-                        return 0;
-                }
-
-                if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_DEGRADED) {
-                        log_link_debug(l, "No routable or link-local IPv6 address is configured.");
-                        return 0;
-                }
+                if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_DEGRADED)
+                        return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+                                                    "No routable or link-local IPv4 address is configured.");
+
+                if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_DEGRADED)
+                        return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+                                                    "No routable or link-local IPv6 address is configured.");
         } else {
-                if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_ROUTABLE) {
-                        log_link_debug(l, "No routable IPv4 address is configured.");
-                        return 0;
-                }
-
-                if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_ROUTABLE) {
-                        log_link_debug(l, "No routable IPv6 address is configured.");
-                        return 0;
-                }
+                if (needs_ipv4 && l->ipv4_address_state < LINK_ADDRESS_STATE_ROUTABLE)
+                        return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+                                                    "No routable IPv4 address is configured.");
+
+                if (needs_ipv6 && l->ipv6_address_state < LINK_ADDRESS_STATE_ROUTABLE)
+                        return log_link_debug_errno(l, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
+                                                    "No routable IPv6 address is configured.");
         }
 
         log_link_debug(l, "link is configured by networkd and online.");
-        return 1;
+        return true;
 }
 
 bool manager_configured(Manager *m) {
-        bool one_ready = false;
-        const char *ifname;
         Link *l;
         int r;
 
         if (!hashmap_isempty(m->command_line_interfaces_by_name)) {
                 LinkOperationalStateRange *range;
+                const char *ifname;
 
                 /* wait for all the links given on the command line to appear */
                 HASHMAP_FOREACH_KEY(range, ifname, m->command_line_interfaces_by_name) {
 
                         l = hashmap_get(m->links_by_name, ifname);
-                        if (!l && range->min == LINK_OPERSTATE_MISSING) {
-                                one_ready = true;
-                                continue;
-                        }
-
                         if (!l) {
-                                log_debug("still waiting for %s", ifname);
-                                if (!m->any)
-                                        return false;
+                                if (range->min == LINK_OPERSTATE_MISSING) {
+                                        if (m->any)
+                                                return true;
+                                } else {
+                                        log_debug("still waiting for %s", ifname);
+                                        if (!m->any)
+                                                return false;
+                                }
                                 continue;
                         }
 
-                        if (manager_link_is_online(m, l, *range) <= 0) {
-                                if (!m->any)
-                                        return false;
-                                continue;
-                        }
-
-                        one_ready = true;
+                        r = manager_link_is_online(m, l, *range);
+                        if (r <= 0 && !m->any)
+                                return false;
+                        if (r > 0 && m->any)
+                                return true;
                 }
 
-                /* all interfaces given by the command line are online, or
-                 * one of the specified interfaces is online. */
-                return one_ready;
+                /* With '--any'   : no interface is ready    → return false
+                 * Without '--any': all interfaces are ready → return true */
+                return !m->any;
         }
 
-        /* wait for all links networkd manages to be in admin state 'configured'
-         * and at least one link to gain a carrier */
+        /* wait for all links networkd manages */
+        bool has_online = false;
         HASHMAP_FOREACH(l, m->links_by_index) {
                 if (manager_ignore_link(m, l)) {
                         log_link_debug(l, "link is ignored");
@@ -164,15 +158,22 @@
                 r = manager_link_is_online(m, l,
                                            (LinkOperationalStateRange) { _LINK_OPERSTATE_INVALID,
                                                                          _LINK_OPERSTATE_INVALID });
-                if (r < 0 && !m->any)
+                if (r < 0 && !m->any) /* Unlike the above loop, unmanaged interfaces are ignored here. */
                         return false;
-                if (r > 0)
-                        /* we wait for at least one link to be ready,
-                         * regardless of who manages it */
-                        one_ready = true;
+                if (r > 0) {
+                        if (m->any)
+                                return true;
+                        has_online = true;
+                }
         }
 
-        return one_ready;
+        /* With '--any'   : no interface is ready → return false
+         * Without '--any': all interfaces are ready or unmanaged
+         *
+         * In this stage, drivers for interfaces may not be loaded yet, and there may be only lo.
+         * To avoid that wait-online exits earlier than that drivers are loaded, let's request at least one
+         * managed online interface exists. See issue #27822. */
+        return !m->any && has_online;
 }
 
 static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
diff -Nru systemd-252.14/src/oom/oomd-manager.c systemd-252.16/src/oom/oomd-manager.c
--- systemd-252.14/src/oom/oomd-manager.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/oom/oomd-manager.c	2023-09-09 02:21:12.000000000 +0100
@@ -126,6 +126,12 @@
                         ctx->mem_pressure_limit = limit;
         }
 
+        /* Toggle wake-ups for "ManagedOOMSwap" if entries are present. */
+        r = sd_event_source_set_enabled(m->swap_context_event_source,
+                                        hashmap_isempty(m->monitored_swap_cgroup_contexts) ? SD_EVENT_OFF : SD_EVENT_ON);
+        if (r < 0)
+                return log_error_errno(r, "Failed to toggle enabled state of swap context source: %m");
+
         return 0;
 }
 
@@ -347,6 +353,7 @@
         int r;
 
         assert(s);
+        assert(!hashmap_isempty(m->monitored_swap_cgroup_contexts));
 
         /* Reset timer */
         r = sd_event_now(sd_event_source_get_event(s), CLOCK_MONOTONIC, &usec_now);
@@ -367,13 +374,9 @@
         /* We still try to acquire system information for oomctl even if no units want swap monitoring */
         r = oomd_system_context_acquire("/proc/meminfo", &m->system_context);
         /* If there are no units depending on swap actions, the only error we exit on is ENOMEM. */
-        if (r == -ENOMEM || (r < 0 && !hashmap_isempty(m->monitored_swap_cgroup_contexts)))
+        if (r < 0)
                 return log_error_errno(r, "Failed to acquire system context: %m");
 
-        /* Return early if nothing is requesting swap monitoring */
-        if (hashmap_isempty(m->monitored_swap_cgroup_contexts))
-                return 0;
-
         /* Note that m->monitored_swap_cgroup_contexts does not need to be updated every interval because only the
          * system context is used for deciding whether the swap threshold is hit. m->monitored_swap_cgroup_contexts
          * is only used to decide which cgroups to kill (and even then only the resource usages of its descendent
@@ -593,7 +596,7 @@
         if (r < 0)
                 return r;
 
-        r = sd_event_source_set_enabled(s, SD_EVENT_ON);
+        r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
         if (r < 0)
                 return r;
 
diff -Nru systemd-252.14/src/shared/bus-polkit.c systemd-252.16/src/shared/bus-polkit.c
--- systemd-252.14/src/shared/bus-polkit.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/shared/bus-polkit.c	2023-09-09 02:21:12.000000000 +0100
@@ -263,6 +263,7 @@
         assert(call);
         assert(action);
         assert(registry);
+        assert(ret_error);
 
         r = check_good_user(call, good_user);
         if (r != 0)
diff -Nru systemd-252.14/src/shared/copy.c systemd-252.16/src/shared/copy.c
--- systemd-252.14/src/shared/copy.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/shared/copy.c	2023-09-09 02:21:12.000000000 +0100
@@ -263,9 +263,22 @@
                         /* If we're in a hole (current offset is not a data offset), create a hole of the
                          * same size in the target file. */
                         if (e > c) {
-                                r = create_hole(fdt, e - c);
+                                /* Make sure our new hole doesn't go over the maximum size we're allowed to copy. */
+                                n = MIN(max_bytes, (uint64_t) e - c);
+                                r = create_hole(fdt, n);
                                 if (r < 0)
                                         return r;
+
+                                /* Make sure holes are taken into account in the maximum size we're supposed to copy. */
+                                if (max_bytes != UINT64_MAX) {
+                                        max_bytes -= n;
+                                        if (max_bytes <= 0)
+                                                break;
+                                }
+
+                                /* Update the size we're supposed to copy in this iteration if needed. */
+                                if (m > max_bytes)
+                                        m = max_bytes;
                         }
 
                         c = e; /* Set c to the start of the data segment. */
diff -Nru systemd-252.14/src/shared/install.c systemd-252.16/src/shared/install.c
--- systemd-252.14/src/shared/install.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/shared/install.c	2023-09-09 02:21:12.000000000 +0100
@@ -2993,9 +2993,6 @@
                                   &info, NULL, NULL);
         if (r < 0)
                 return r;
-        r = install_info_may_process(info, &lp, NULL, 0);
-        if (r < 0)
-                return r;
 
         n = strdup(info->name);
         if (!n)
diff -Nru systemd-252.14/src/shared/parse-helpers.c systemd-252.16/src/shared/parse-helpers.c
--- systemd-252.14/src/shared/parse-helpers.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/shared/parse-helpers.c	2023-09-09 02:21:12.000000000 +0100
@@ -40,7 +40,7 @@
                                           lvalue, fatal ? "" : ", ignoring", path);
         }
 
-        path_simplify(path);
+        path_simplify_full(path, flag & PATH_KEEP_TRAILING_SLASH ? PATH_SIMPLIFY_KEEP_TRAILING_SLASH : 0);
 
         if (!path_is_valid(path))
                 return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
diff -Nru systemd-252.14/src/shared/parse-helpers.h systemd-252.16/src/shared/parse-helpers.h
--- systemd-252.14/src/shared/parse-helpers.h	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/shared/parse-helpers.h	2023-09-09 02:21:12.000000000 +0100
@@ -4,9 +4,10 @@
 #include <stdint.h>
 
 enum {
-        PATH_CHECK_FATAL    = 1 << 0,  /* If not set, then error message is appended with 'ignoring'. */
-        PATH_CHECK_ABSOLUTE = 1 << 1,
-        PATH_CHECK_RELATIVE = 1 << 2,
+        PATH_CHECK_FATAL    =      1 << 0,  /* If not set, then error message is appended with 'ignoring'. */
+        PATH_CHECK_ABSOLUTE =      1 << 1,
+        PATH_CHECK_RELATIVE =      1 << 2,
+        PATH_KEEP_TRAILING_SLASH = 1 << 3,
 };
 
 int path_simplify_and_warn(
diff -Nru systemd-252.14/src/shared/pkcs11-util.c systemd-252.16/src/shared/pkcs11-util.c
--- systemd-252.14/src/shared/pkcs11-util.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/shared/pkcs11-util.c	2023-09-09 02:21:12.000000000 +0100
@@ -1064,7 +1064,7 @@
          * out. (Note that the user can explicitly specify non-hardware tokens if they like, but during
          * enumeration we'll filter those, since software tokens are typically the system certificate store
          * and such, and it's typically not what people want to bind their home directories to.) */
-        if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT))
+        if (!FLAGS_SET(slot_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT))
                 return -EAGAIN;
 
         token_label = pkcs11_token_label(token_info);
diff -Nru systemd-252.14/src/sleep/sleep.c systemd-252.16/src/sleep/sleep.c
--- systemd-252.14/src/sleep/sleep.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/sleep/sleep.c	2023-09-09 02:21:12.000000000 +0100
@@ -22,6 +22,7 @@
 #include "bus-locator.h"
 #include "bus-util.h"
 #include "def.h"
+#include "efivars.h"
 #include "exec-util.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -224,8 +225,12 @@
                                * do it ourselves then. > 0 means: kernel already had a configured hibernation
                                * location which we shouldn't touch. */
                         r = write_hibernate_location_info(hibernate_location);
-                        if (r < 0)
+                        if (r < 0) {
+                                if (is_efi_boot())
+                                        (void) efi_set_variable(EFI_SYSTEMD_VARIABLE(HibernateLocation), NULL, 0);
+
                                 return log_error_errno(r, "Failed to prepare for hibernation: %m");
+                        }
                 }
 
                 r = write_mode(modes);
diff -Nru systemd-252.14/src/test/test-copy.c systemd-252.16/src/test/test-copy.c
--- systemd-252.14/src/test/test-copy.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/test/test-copy.c	2023-09-09 02:21:12.000000000 +0100
@@ -10,10 +10,12 @@
 #include "fileio.h"
 #include "fs-util.h"
 #include "hexdecoct.h"
+#include "io-util.h"
 #include "log.h"
 #include "macro.h"
 #include "mkdir.h"
 #include "path-util.h"
+#include "random-util.h"
 #include "rm-rf.h"
 #include "string-util.h"
 #include "strv.h"
@@ -446,5 +448,77 @@
 
         return 0;
 }
+
+TEST_RET(copy_holes_with_gaps) {
+        _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
+        _cleanup_close_ int tfd = -EBADF, fd = -EBADF, fd_copy = -EBADF;
+        struct stat st;
+        off_t blksz;
+        char *buf;
+        int r;
+
+        assert_se(mkdtemp_malloc(NULL, &t) >= 0);
+        assert_se((tfd = open(t, O_DIRECTORY | O_CLOEXEC)) >= 0);
+        assert_se((fd = openat(tfd, "src", O_CREAT | O_RDWR, 0600)) >= 0);
+        assert_se((fd_copy = openat(tfd, "dst", O_CREAT | O_WRONLY, 0600)) >= 0);
+
+        assert_se(fstat(fd, &st) >= 0);
+        blksz = st.st_blksize;
+        buf = alloca_safe(blksz);
+        memset(buf, 1, blksz);
+
+        /* Create a file with:
+         *  - hole of 1 block
+         *  - data of 2 block
+         *  - hole of 2 blocks
+         *  - data of 1 block
+         *
+         * Since sparse files are based on blocks and not bytes, we need to make
+         * sure that the holes are aligned to the block size.
+         */
+
+        r = RET_NERRNO(fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, blksz));
+        if (ERRNO_IS_NOT_SUPPORTED(r))
+                return log_tests_skipped("Filesystem doesn't support hole punching");
+
+        assert_se(lseek(fd, blksz, SEEK_CUR) >= 0);
+        assert_se(loop_write(fd, buf, blksz, 0) >= 0);
+        assert_se(loop_write(fd, buf, blksz, 0) >= 0);
+        assert_se(lseek(fd, 2 * blksz, SEEK_CUR) >= 0);
+        assert_se(loop_write(fd, buf, blksz, 0) >= 0);
+        assert_se(lseek(fd, 0, SEEK_SET) >= 0);
+        assert_se(fsync(fd) >= 0);
+
+        /* Copy to the start of the second hole */
+        assert_se(copy_bytes(fd, fd_copy, 3 * blksz, COPY_HOLES) >= 0);
+        assert_se(fstat(fd_copy, &st) >= 0);
+        assert_se(st.st_size == 3 * blksz);
+
+        /* Copy to the middle of the second hole */
+        assert_se(lseek(fd, 0, SEEK_SET) >= 0);
+        assert_se(lseek(fd_copy, 0, SEEK_SET) >= 0);
+        assert_se(ftruncate(fd_copy, 0) >= 0);
+        assert_se(copy_bytes(fd, fd_copy, 4 * blksz, COPY_HOLES) >= 0);
+        assert_se(fstat(fd_copy, &st) >= 0);
+        assert_se(st.st_size == 4 * blksz);
+
+        /* Copy to the end of the second hole */
+        assert_se(lseek(fd, 0, SEEK_SET) >= 0);
+        assert_se(lseek(fd_copy, 0, SEEK_SET) >= 0);
+        assert_se(ftruncate(fd_copy, 0) >= 0);
+        assert_se(copy_bytes(fd, fd_copy, 5 * blksz, COPY_HOLES) >= 0);
+        assert_se(fstat(fd_copy, &st) >= 0);
+        assert_se(st.st_size == 5 * blksz);
+
+        /* Copy everything */
+        assert_se(lseek(fd, 0, SEEK_SET) >= 0);
+        assert_se(lseek(fd_copy, 0, SEEK_SET) >= 0);
+        assert_se(ftruncate(fd_copy, 0) >= 0);
+        assert_se(copy_bytes(fd, fd_copy, UINT64_MAX, COPY_HOLES) >= 0);
+        assert_se(fstat(fd_copy, &st) >= 0);
+        assert_se(st.st_size == 6 * blksz);
+
+        return 0;
+}
 
 DEFINE_TEST_MAIN(LOG_DEBUG);
diff -Nru systemd-252.14/src/test/test-mountpoint-util.c systemd-252.16/src/test/test-mountpoint-util.c
--- systemd-252.14/src/test/test-mountpoint-util.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/test/test-mountpoint-util.c	2023-09-09 02:21:12.000000000 +0100
@@ -276,6 +276,7 @@
 }
 
 TEST(fd_is_mount_point) {
+        _cleanup_(rm_rf_physical_and_freep) char *tmpdir = NULL;
         _cleanup_close_ int fd = -1;
         int r;
 
@@ -298,11 +299,13 @@
         assert_se(fd_is_mount_point(fd, "proc", 0) > 0);
         assert_se(fd_is_mount_point(fd, "proc/", 0) > 0);
 
-        /* /root's entire reason for being is to be on the root file system (i.e. not in /home/ which
-         * might be split off), so that the user can always log in, so it cannot be a mount point unless
-         * the system is borked. Let's allow for it to be missing though. */
-        assert_se(IN_SET(fd_is_mount_point(fd, "root", 0), -ENOENT, 0));
-        assert_se(IN_SET(fd_is_mount_point(fd, "root/", 0), -ENOENT, 0));
+        safe_close(fd);
+        fd = open("/tmp", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
+        assert_se(fd >= 0);
+
+        assert_se(mkdtemp_malloc("/tmp/not-mounted-XXXXXX", &tmpdir) >= 0);
+        assert_se(fd_is_mount_point(fd, basename(tmpdir), 0) == 0);
+        assert_se(fd_is_mount_point(fd, strjoina(basename(tmpdir), "/"), 0) == 0);
 
         safe_close(fd);
         fd = open("/proc", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
diff -Nru systemd-252.14/src/test/test-path-util.c systemd-252.16/src/test/test-path-util.c
--- systemd-252.14/src/test/test-path-util.c	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/src/test/test-path-util.c	2023-09-09 02:21:12.000000000 +0100
@@ -54,11 +54,11 @@
         assert_se(!path_equal_filename("/b", "/c"));
 }
 
-static void test_path_simplify_one(const char *in, const char *out) {
+static void test_path_simplify_one(const char *in, const char *out, PathSimplifyFlags flags) {
         char *p;
 
         p = strdupa_safe(in);
-        path_simplify(p);
+        path_simplify_full(p, flags);
         log_debug("/* test_path_simplify(%s) → %s (expected: %s) */", in, p, out);
         assert_se(streq(p, out));
 }
@@ -67,34 +67,37 @@
         _cleanup_free_ char *hoge = NULL, *hoge_out = NULL;
         char foo[NAME_MAX * 2];
 
-        test_path_simplify_one("", "");
-        test_path_simplify_one("aaa/bbb////ccc", "aaa/bbb/ccc");
-        test_path_simplify_one("//aaa/.////ccc", "/aaa/ccc");
-        test_path_simplify_one("///", "/");
-        test_path_simplify_one("///.//", "/");
-        test_path_simplify_one("///.//.///", "/");
-        test_path_simplify_one("////.././///../.", "/../..");
-        test_path_simplify_one(".", ".");
-        test_path_simplify_one("./", ".");
-        test_path_simplify_one(".///.//./.", ".");
-        test_path_simplify_one(".///.//././/", ".");
+        test_path_simplify_one("", "", 0);
+        test_path_simplify_one("aaa/bbb////ccc", "aaa/bbb/ccc", 0);
+        test_path_simplify_one("//aaa/.////ccc", "/aaa/ccc", 0);
+        test_path_simplify_one("///", "/", 0);
+        test_path_simplify_one("///", "/", PATH_SIMPLIFY_KEEP_TRAILING_SLASH);
+        test_path_simplify_one("///.//", "/", 0);
+        test_path_simplify_one("///.//.///", "/", 0);
+        test_path_simplify_one("////.././///../.", "/../..", 0);
+        test_path_simplify_one(".", ".", 0);
+        test_path_simplify_one("./", ".", 0);
+        test_path_simplify_one("./", "./", PATH_SIMPLIFY_KEEP_TRAILING_SLASH);
+        test_path_simplify_one(".///.//./.", ".", 0);
+        test_path_simplify_one(".///.//././/", ".", 0);
         test_path_simplify_one("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
-                               "/aaa/.bbb/../c./d.dd/..eeee");
+                               "/aaa/.bbb/../c./d.dd/..eeee", 0);
         test_path_simplify_one("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
-                               "/aaa/.bbb/../c./d.dd/..eeee/..");
+                               "/aaa/.bbb/../c./d.dd/..eeee/..", 0);
         test_path_simplify_one(".//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
-                               "aaa/.bbb/../c./d.dd/..eeee/..");
+                               "aaa/.bbb/../c./d.dd/..eeee/..", 0);
         test_path_simplify_one("..//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
-                               "../aaa/.bbb/../c./d.dd/..eeee/..");
+                               "../aaa/.bbb/../c./d.dd/..eeee/..", 0);
+        test_path_simplify_one("abc///", "abc/", PATH_SIMPLIFY_KEEP_TRAILING_SLASH);
 
         memset(foo, 'a', sizeof(foo) -1);
         char_array_0(foo);
 
-        test_path_simplify_one(foo, foo);
+        test_path_simplify_one(foo, foo, 0);
 
         hoge = strjoin("/", foo);
         assert_se(hoge);
-        test_path_simplify_one(hoge, hoge);
+        test_path_simplify_one(hoge, hoge, 0);
         hoge = mfree(hoge);
 
         hoge = strjoin("a////.//././//./b///././/./c/////././//./", foo, "//.//////d/e/.//f/");
@@ -103,7 +106,7 @@
         hoge_out = strjoin("a/b/c/", foo, "//.//////d/e/.//f/");
         assert_se(hoge_out);
 
-        test_path_simplify_one(hoge, hoge_out);
+        test_path_simplify_one(hoge, hoge_out, 0);
 }
 
 static void test_path_compare_one(const char *a, const char *b, int expected) {
diff -Nru systemd-252.14/test/test-network/systemd-networkd-tests.py systemd-252.16/test/test-network/systemd-networkd-tests.py
--- systemd-252.14/test/test-network/systemd-networkd-tests.py	2023-08-10 09:43:05.000000000 +0100
+++ systemd-252.16/test/test-network/systemd-networkd-tests.py	2023-09-09 02:21:12.000000000 +0100
@@ -867,7 +867,7 @@
         This returns if the links reached the requested operstate/setup_state; otherwise it
         raises CalledProcessError or fails test assertion.
         """
-        args = wait_online_cmd + [f'--timeout={timeout}'] + [f'--interface={link}' for link in links_with_operstate]
+        args = wait_online_cmd + [f'--timeout={timeout}'] + [f'--interface={link}' for link in links_with_operstate] + [f'--ignore={link}' for link in protected_links]
         if bool_any:
             args += ['--any']
         if ipv4:
@@ -1095,6 +1095,23 @@
         self.check_link_exists('veth99', expected=False)
         self.check_link_exists('veth-peer', expected=False)
 
+class WaitOnlineTests(unittest.TestCase, Utilities):
+
+    def setUp(self):
+        setup_common()
+
+    def tearDown(self):
+        tear_down_common()
+
+    def test_wait_online_any(self):
+        copy_network_unit('25-bridge.netdev', '25-bridge.network', '11-dummy.netdev', '11-dummy.network')
+        start_networkd()
+
+        self.wait_online(['bridge99', 'test1:degraded'], bool_any=True)
+
+        self.wait_operstate('bridge99', '(off|no-carrier)', setup_state='configuring')
+        self.wait_operstate('test1', 'degraded')
+
 class NetworkdNetDevTests(unittest.TestCase, Utilities):
 
     def setUp(self):
@@ -1122,15 +1139,6 @@
         print(output)
         self.assertRegex(output, 'Network File: /run/systemd/network/14-match-udev-property')
 
-    def test_wait_online_any(self):
-        copy_network_unit('25-bridge.netdev', '25-bridge.network', '11-dummy.netdev', '11-dummy.network')
-        start_networkd()
-
-        self.wait_online(['bridge99', 'test1:degraded'], bool_any=True)
-
-        self.wait_operstate('bridge99', '(off|no-carrier)', setup_state='configuring')
-        self.wait_operstate('test1', 'degraded')
-
     @expectedFailureIfModuleIsNotAvailable('bareudp')
     def test_bareudp(self):
         copy_network_unit('25-bareudp.netdev', '26-netdev-link-local-addressing-yes.network')

Attachment: signature.asc
Description: This is a digitally signed message part


Reply to: