]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #32708 from DaanDeMeyer/fix-race
authorLuca Boccassi <bluca@debian.org>
Wed, 8 May 2024 12:21:37 +0000 (14:21 +0200)
committerGitHub <noreply@github.com>
Wed, 8 May 2024 12:21:37 +0000 (14:21 +0200)
Fix race conditions in tests

34 files changed:
docs/ELF_DLOPEN_METADATA.md [new file with mode: 0644]
hwdb.d/70-mouse.hwdb
man/run0.xml
man/systemctl.xml
man/systemd-pcrlock.xml
man/systemd-pcrphase.service.xml
man/systemd.pcrlock.xml
meson.build
src/basic/compress.c
src/basic/dlfcn-util.h
src/basic/gcrypt-util.c
src/debug-generator/debug-generator.c
src/locale/xkbcommon-util.c
src/login/logind-dbus.c
src/shared/bpf-dlopen.c
src/shared/cryptsetup-util.c
src/shared/elf-util.c
src/shared/firewall-util-iptables.c
src/shared/hibernate-util.c
src/shared/idn-util.c
src/shared/install.c
src/shared/libarchive-util.c
src/shared/libfido2-util.c
src/shared/module-util.c
src/shared/password-quality-util-passwdqc.c
src/shared/password-quality-util-pwquality.c
src/shared/pcre2-util.c
src/shared/pkcs11-util.c
src/shared/qrcode-util.c
src/shared/sleep-config.c
src/shared/sleep-config.h
src/shared/tpm2-util.c
src/ssh-generator/ssh-generator.c
src/systemctl/systemctl-start-special.c

diff --git a/docs/ELF_DLOPEN_METADATA.md b/docs/ELF_DLOPEN_METADATA.md
new file mode 100644 (file)
index 0000000..5c3bf1e
--- /dev/null
@@ -0,0 +1,89 @@
+---
+title: Dlopen Metadata for ELF Files
+category: Interfaces
+layout: default
+SPDX-License-Identifier: LGPL-2.1-or-later
+---
+
+# `dlopen()` Metadata for ELF Files
+
+*Intended audience: hackers working on packaging ELF files that use dlopen to load libraries.*
+
+## Motivation
+
+Using `dlopen()` to load optional dependencies brings several advantages: programs can gracefully downgrade
+a feature when a library is not available, and the shared library is only loaded into the process (and its
+ELF constructors are run) only when the requested feature is actually used. But it also has some drawbacks,
+and the main one is that it is harder to track a program's dependencies, since unlike build-time dynamic
+linking there will not be a mention in the ELF metadata. This specification aims to solve this problem by
+providing a standardized specification for a custom ELF note that can be used to list `dlopen()`
+dependencies.
+
+## Implementation
+
+This document will attempt to define a common metadata format specification, so that multiple implementers
+might use it when coding upstream software, and packagers might use it when building packages and setting
+dependencies.
+
+The metadata will be embedded in a series of new, 4-byte-aligned, allocated, 0-padded, read-only ELF header
+sections, in a JSON array containing name-value objects, either one ELF note per dependency or as a single
+note listing multiple dependencies in the top-level array. Implementers working on parsing ELF files should
+not assume a specific list of names, but parse anything that is included in the section, and should look for
+the note using the `note type`. Implementers working on build tools should strive to use the same names, for
+consistency. The most common will be listed here.
+
+* Section header
+
+```
+SECTION: `.note.dlopen`
+note type: `0x407c0c0a`
+Owner: `FDO` (FreeDesktop.org)
+Value: an array of JSON objects encoded as a zero-terminated UTF-8 string
+```
+
+* JSON payload
+
+```json
+[
+    {
+        "soname":      ["libfoo.so.1"],
+        "feature":     "foo",
+        "description": "Enables the foo feature",
+        "priority":    "recommended"
+    }
+]
+```
+
+The format is a single JSON array containing objects, encoded as a zero-terminated `UTF-8` string. Each key
+in each object shall be unique as per recommendations of [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259#section-4).
+Strings shall not contain any control characters or use `\uXXX` escaping.
+
+Reference implementations of [packaging tools for `.deb` and `.rpm`](https://github.com/systemd/package-notes)
+are available, and provide macros/helpers to parse the note when building packages and adding dependencies.
+
+## Well-known keys
+
+The metadata format is intentionally extensible, so that upstreams and later revisions of this spec can add
+their own information. The 'soname' array is required, with at least one element, everything else is
+optional. If alternative soname versions for the same library are supported at the same time, an array can
+be used, listing the most preferred first, and parsers are expected to select only the first one that is
+available on the system, as it is a mechanism to specify alternatives. If the `priority` field is used, it
+must follow the specification and use one of the values specified in the table. If it is not specified, a
+parser should assume 'recommended' if a priority is needed. If the `feature` field is used, it will identify
+an individual feature, and multiple entries using the same `feature` denote functionality that requires all
+of the libraries they specify in order to be enabled.
+
+| Key name    | Key type                   | Mandatory | Key description                                                          | Example value                    |
+|-------------|----------------------------|-----------|--------------------------------------------------------------------------|----------------------------------|
+| soname      | array of strings           | yes       | The library names loaded by `dlopen()`                                   | [ "libfoo.so.1", "libfoo.so.0" ] |
+| feature     | string                     | no        | A keyword identifying the feature that the library contributes to enable | "foo"                            |
+| description | string                     | no        | A human-readable text string describing the feature                      | "Enables the foo feature"        |
+| priority    | string                     | no        | The priority of the feature, one of: required, recommended, suggested    | "recommended"                    |
+
+### Priority definition
+
+| Priority    | Semantics                                                                                                                            |
+|-------------|--------------------------------------------------------------------------------------------------------------------------------------|
+| required    | Core functionality needs the dependency, the binary will not work if it cannot be found                                              |
+| recommended | Important functionality needs the dependency, the binary will work but in most cases the dependency should be provided               |
+| suggested   | Secondary functionality needs the dependency, the binary will work and the dependency is only needed for full-featured installations |
index c29c13494281a27b32f12c6d6c8cfb5ba524a02c..6264268e371f3eb84da42c2981a437d7f880a3b0 100644 (file)
@@ -540,6 +540,10 @@ mouse:bluetooth:v046dpb019:name:MX Master 2S Mouse:*
  MOUSE_WHEEL_CLICK_COUNT=24
  MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL=14
 
+# Logitech MX Master 3S (via Bolt Receiver)
+mouse:usb:v046dpc548:name:Logitech USB Receiver Mouse:*
+ MOUSE_DPI=1000@142
+
 # Logitech MX Ergo
 mouse:usb:v046dp406f:name:Logitech MX Ergo:*
 mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:406f:*
index c9be24da98031d0ffe34747477642c7807530d69..3c3d5622168de5c1f98c13927125b5a608d8dd33 100644 (file)
         </listitem>
       </varlistentry>
 
-      <xi:include href="user-system-options.xml" xpointer="machine" />
+      <varlistentry>
+        <term><option>-M</option></term>
+        <term><option>--machine=</option></term>
+
+        <listitem>
+          <para>Execute operation on a local container. Specify a container name to connect to, optionally
+          prefixed by a user name to connect as and a separating <literal>@</literal> character. If the special
+          string <literal>.host</literal> is used in place of the container name, a connection to the local
+          system is made. If the <literal>@</literal> syntax is not used, the connection is made as root user.
+          If the <literal>@</literal> syntax is used either the left hand side or the right hand side may be
+          omitted (but not both) in which case the local user name and <literal>.host</literal> are implied.
+          </para>
+
+          <xi:include href="version-info.xml" xpointer="v256"/>
+        </listitem>
+      </varlistentry>
+
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
index 287decffb219b0952caf04b313dccd4aaeeb48ac..def2f8e01113e8c755e2b44d89512c80b6033731 100644 (file)
@@ -1843,6 +1843,10 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
             <para>Suspend the system. This will trigger activation of the special target unit
             <filename>suspend.target</filename>. This command is asynchronous, and will return after the suspend
             operation is successfully enqueued. It will not wait for the suspend/resume cycle to complete.</para>
+
+            <para>If <option>--force</option> is specified, and <command>systemd-logind</command> returned
+            error for the operation, the error will be ignored and the operation will be tried again directly
+            through starting the target unit.</para>
           </listitem>
         </varlistentry>
 
@@ -1853,6 +1857,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
             <para>Hibernate the system. This will trigger activation of the special target unit
             <filename>hibernate.target</filename>. This command is asynchronous, and will return after the hibernation
             operation is successfully enqueued. It will not wait for the hibernate/thaw cycle to complete.</para>
+
+            <para>This command honors <option>--force</option> in the same way as <command>suspend</command>.</para>
           </listitem>
         </varlistentry>
 
@@ -1864,6 +1870,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
             <filename>hybrid-sleep.target</filename>. This command is asynchronous, and will return after the hybrid
             sleep operation is successfully enqueued. It will not wait for the sleep/wake-up cycle to complete.</para>
 
+            <para>This command honors <option>--force</option> in the same way as <command>suspend</command>.</para>
+
             <xi:include href="version-info.xml" xpointer="v196"/>
           </listitem>
         </varlistentry>
@@ -1872,12 +1880,15 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
           <term><command>suspend-then-hibernate</command></term>
 
           <listitem>
-            <para>Suspend the system and hibernate it after the delay specified in <filename>systemd-sleep.conf</filename>.
-            This will trigger activation of the special target unit <filename>suspend-then-hibernate.target</filename>.
-            This command is asynchronous, and will return after the hybrid sleep operation is successfully enqueued.
+            <para>Suspend the system and hibernate it when the battery is low, or when the delay specified
+            in <filename>systemd-sleep.conf</filename> elapsed. This will trigger activation of the special
+            target unit <filename>suspend-then-hibernate.target</filename>. This command is asynchronous,
+            and will return after the hybrid sleep operation is successfully enqueued.
             It will not wait for the sleep/wake-up or hibernate/thaw cycle to complete.</para>
 
-          <xi:include href="version-info.xml" xpointer="v240"/>
+            <para>This command honors <option>--force</option> in the same way as <command>suspend</command>.</para>
+
+            <xi:include href="version-info.xml" xpointer="v240"/>
           </listitem>
         </varlistentry>
       </variablelist>
@@ -2531,25 +2542,27 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
         <term><option>--force</option></term>
 
         <listitem>
-          <para>When used with <command>enable</command>, overwrite
-          any existing conflicting symlinks.</para>
+          <para>When used with <command>enable</command>, overwrite any existing conflicting symlinks.</para>
+
+          <para>When used with <command>edit</command>, create all of the specified units which do not already exist.</para>
 
-          <para>When used with <command>edit</command>, create all of the
-          specified units which do not already exist.</para>
+          <para>When used with <command>suspend</command>, <command>hibernate</command>, <command>hybrid-sleep</command>,
+          or <command>suspend-then-hibernate</command>, the error returned by <command>systemd-logind</command>
+          will be ignored, and the operation will be performed directly through starting the corresponding units.
+          </para>
 
-          <para>When used with <command>halt</command>, <command>poweroff</command>, <command>reboot</command> or
-          <command>kexec</command>, execute the selected operation without shutting down all units. However, all
-          processes will be killed forcibly and all file systems are unmounted or remounted read-only. This is hence a
-          drastic but relatively safe option to request an immediate reboot. If <option>--force</option> is specified
-          twice for these operations (with the exception of <command>kexec</command>), they will be executed
-          immediately, without terminating any processes or unmounting any file systems.</para>
+          <para>When used with <command>halt</command>, <command>poweroff</command>, <command>reboot</command>,
+          or <command>kexec</command>, execute the selected operation without shutting down all units. However,
+          all processes will be killed forcibly and all file systems are unmounted or remounted read-only.
+          This is hence a drastic but relatively safe option to request an immediate reboot. If <option>--force</option>
+          is specified twice for these operations (with the exception of <command>kexec</command>), they will
+          be executed immediately, without terminating any processes or unmounting any file systems.</para>
 
           <warning>
-            <para>Specifying
-            <option>--force</option> twice with any of these operations might result in data loss. Note that when
-            <option>--force</option> is specified twice the selected operation is executed by
-            <command>systemctl</command> itself, and the system manager is not contacted. This means the command should
-            succeed even when the system manager has crashed.</para>
+            <para>Specifying <option>--force</option> twice with any of these operations might result in data loss.
+            Note that when <option>--force</option> is specified twice the selected operation is executed by
+            <command>systemctl</command> itself, and the system manager is not contacted. This means the command
+            should succeed even when the system manager has crashed.</para>
           </warning>
         </listitem>
       </varlistentry>
index 4af7f13c5db6dbcad4bb007ddeb95065ff4ff9be..19ba4c4b170abd85fef952e4420091b9a6e72dce 100644 (file)
         <term><command>cel</command></term>
 
         <listitem><para>This reads the combined TPM2 event log and writes it to STDOUT in <ulink
-        url="https://trustedcomputinggroup.org/resource/canonical-event-log-format/">TCG Common Event Log
+        url="https://trustedcomputinggroup.org/resource/canonical-event-log-format/">TCG Canonical Event Log
         Format (CEL-JSON)</ulink> format.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
index 9c54663d3eb56b1217bab3ae354020c6a6ab4e3f..2dc9c8ada09cc3c0c7a89065f86708f8e1d4bf53 100644 (file)
         <filename>/run/log/systemd/tpm2-measure.log</filename>, which contains a <ulink
         url="https://www.rfc-editor.org/rfc/rfc7464.html">JSON-SEQ</ulink> series of objects that follow the
         general structure of the <ulink
-        url="https://trustedcomputinggroup.org/resource/canonical-event-log-format/">TCG Common Event Log
+        url="https://trustedcomputinggroup.org/resource/canonical-event-log-format/">TCG Canonical Event Log
         Format (CEL-JSON)</ulink> event objects (but lack the <literal>recnum</literal>
         field).</para>
 
index 27ceb48652f4a61f25a1271f6e21646e51a16e3a..6f07dc8159395872e004ee6c1af0f48b5e674590 100644 (file)
@@ -43,7 +43,7 @@
     process. <citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     uses such pcrlock files to analyze and predict TPM2 PCR measurements. The pcrlock files are JSON arrays
     that follow a subset of the <ulink
-    url="https://trustedcomputinggroup.org/resource/canonical-event-log-format/">TCG Common Event Log Format
+    url="https://trustedcomputinggroup.org/resource/canonical-event-log-format/">TCG Canonical Event Log Format
     (CEL-JSON)</ulink> specification. Specifically the <literal>recnum</literal>, <literal>content</literal>,
     and <literal>content_type</literal> record fields are not used and ignored if present. Each pcrlock file
     defines one set of expected, ordered PCR measurements of a specific component of the boot.</para>
index 63c358194d82a4812d3777bd826058379d75ef2c..6ea9fce85ad9ac5581711711dce1c070534f475c 100644 (file)
@@ -1418,6 +1418,15 @@ elif compression == 'lz4' and not liblz4.found()
 elif compression == 'xz' and not libxz.found()
         error('default-compression=xz requires xz')
 endif
+# In the dlopen ELF note we save the default compression library with a
+# higher priority, so that packages can give it priority over the
+# secondary libraries.
+conf.set_quoted('COMPRESSION_PRIORITY_ZSTD',
+                compression == 'zstd' ? 'recommended' : 'suggested')
+conf.set_quoted('COMPRESSION_PRIORITY_LZ4',
+                compression == 'lz4' ? 'recommended' : 'suggested')
+conf.set_quoted('COMPRESSION_PRIORITY_XZ',
+                compression == 'xz' ? 'recommended' : 'suggested')
 conf.set('DEFAULT_COMPRESSION', 'COMPRESSION_@0@'.format(compression.to_upper()))
 
 libarchive = dependency('libarchive',
index 5a4293fa81497c83110a579c37a99aac3c43c1ab..33b27d3b99cfb8c95f46ba8f5d6119f6a034a737 100644 (file)
@@ -129,6 +129,11 @@ bool compression_supported(Compression c) {
 
 #if HAVE_XZ
 int dlopen_lzma(void) {
+        ELF_NOTE_DLOPEN("lzma",
+                        "Support lzma compression in journal and coredump files",
+                        COMPRESSION_PRIORITY_XZ,
+                        "liblzma.so.5");
+
         return dlopen_many_sym_or_warn(
                         &lzma_dl,
                         "liblzma.so.5", LOG_DEBUG,
@@ -186,6 +191,11 @@ int compress_blob_xz(const void *src, uint64_t src_size,
 
 #if HAVE_LZ4
 int dlopen_lz4(void) {
+        ELF_NOTE_DLOPEN("lz4",
+                        "Support lz4 compression in journal and coredump files",
+                        COMPRESSION_PRIORITY_LZ4,
+                        "liblz4.so.1");
+
         return dlopen_many_sym_or_warn(
                         &lz4_dl,
                         "liblz4.so.1", LOG_DEBUG,
@@ -242,6 +252,11 @@ int compress_blob_lz4(const void *src, uint64_t src_size,
 
 #if HAVE_ZSTD
 int dlopen_zstd(void) {
+        ELF_NOTE_DLOPEN("zstd",
+                        "Support zstd compression in journal and coredump files",
+                        COMPRESSION_PRIORITY_ZSTD,
+                        "libzstd.so.1");
+
         return dlopen_many_sym_or_warn(
                         &zstd_dl,
                         "libzstd.so.1", LOG_DEBUG,
index 050f1e2da748a9047aef34136e0cb50e4e9c60cd..b395d4ca04c9c410b34f7f2c70f5604b29f18cb7 100644 (file)
@@ -39,3 +39,44 @@ int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_l
 /* libbpf is a bit confused about type-safety and API compatibility. Provide a macro that can tape over that mess. Sad. */
 #define DLSYM_ARG_FORCE(arg) \
         &sym_##arg, STRINGIFY(arg)
+
+#define ELF_NOTE_DLOPEN_VENDOR "FDO"
+#define ELF_NOTE_DLOPEN_TYPE UINT32_C(0x407c0c0a)
+#define ELF_NOTE_DLOPEN_PRIORITY_REQUIRED "required"
+#define ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED "recommended"
+#define ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED "suggested"
+
+/* Add an ".note.dlopen" ELF note to our binary that declares our weak dlopen() dependency. This
+ * information can be read from an ELF file via "readelf -p .note.dlopen" or an equivalent command. */
+#define _ELF_NOTE_DLOPEN(json, variable_name)                              \
+        __attribute__((used, section(".note.dlopen"))) _Alignas(sizeof(uint32_t)) static const struct { \
+                struct {                                                   \
+                        uint32_t n_namesz, n_descsz, n_type;               \
+                } nhdr;                                                    \
+                char name[sizeof(ELF_NOTE_DLOPEN_VENDOR)];                 \
+                _Alignas(sizeof(uint32_t)) char dlopen_json[sizeof(json)]; \
+        } variable_name = {                                                \
+                .nhdr = {                                                  \
+                        .n_namesz = sizeof(ELF_NOTE_DLOPEN_VENDOR),        \
+                        .n_descsz = sizeof(json),                          \
+                        .n_type   = ELF_NOTE_DLOPEN_TYPE,                  \
+                },                                                         \
+                .name = ELF_NOTE_DLOPEN_VENDOR,                            \
+                .dlopen_json = json,                                       \
+        }
+
+#define _SONAME_ARRAY1(a) "[\""a"\"]"
+#define _SONAME_ARRAY2(a, b) "[\""a"\",\""b"\"]"
+#define _SONAME_ARRAY3(a, b, c) "[\""a"\",\""b"\",\""c"\"]"
+#define _SONAME_ARRAY4(a, b, c, d) "[\""a"\",\""b"\",\""c"\"",\""d"\"]"
+#define _SONAME_ARRAY5(a, b, c, d, e) "[\""a"\",\""b"\",\""c"\"",\""d"\",\""e"\"]"
+#define _SONAME_ARRAY_GET(_1,_2,_3,_4,_5,NAME,...) NAME
+#define _SONAME_ARRAY(...) _SONAME_ARRAY_GET(__VA_ARGS__, _SONAME_ARRAY5, _SONAME_ARRAY4, _SONAME_ARRAY3, _SONAME_ARRAY2, _SONAME_ARRAY1)(__VA_ARGS__)
+
+/* The 'priority' must be one of 'required', 'recommended' or 'suggested' as per specification, use the
+ * macro defined above to specify it.
+ * Multiple sonames can be passed and they will be automatically contructed into a json array (but note that
+ * due to preprocessor language limitations if more than the limit defined above is used, a new
+ * _SONAME_ARRAY<X+1> will need to be added). */
+#define ELF_NOTE_DLOPEN(feature, description, priority, ...) \
+        _ELF_NOTE_DLOPEN("[{\"feature\":\"" feature "\",\"description\":\"" description "\",\"priority\":\"" priority "\",\"soname\":" _SONAME_ARRAY(__VA_ARGS__) "}]", UNIQ_T(s, UNIQ))
index 081866537c40eb4e7c8c02745e0cc5845b787055..4d68d2c22b4dd876ea59732d8223fe18e57c75b0 100644 (file)
@@ -41,6 +41,11 @@ DLSYM_FUNCTION(gcry_randomize);
 DLSYM_FUNCTION(gcry_strerror);
 
 static int dlopen_gcrypt(void) {
+        ELF_NOTE_DLOPEN("gcrypt",
+                        "Support for journald forward-sealing",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libgcrypt.so.20");
+
         return dlopen_many_sym_or_warn(
                         &gcrypt_dl,
                         "libgcrypt.so.20", LOG_DEBUG,
index 3526b84dee8ed181ee64eb56bb6136aafba54e61..1b14f1222abd1d9b80c9455918067850c0c18b2c 100644 (file)
@@ -49,8 +49,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                 if (r < 0)
                         return log_error_errno(r, "Failed to glob unit name: %m");
 
-                r = strv_consume(&arg_mask, n);
-                if (r < 0)
+                if (strv_consume(&arg_mask, n) < 0)
                         return log_oom();
 
         } else if (streq(key, "systemd.wants")) {
@@ -63,11 +62,11 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                 if (r < 0)
                         return log_error_errno(r, "Failed to glob unit name: %m");
 
-                r = strv_consume(&arg_wants, n);
-                if (r < 0)
+                if (strv_consume(&arg_wants, n) < 0)
                         return log_oom();
 
         } else if (proc_cmdline_key_streq(key, "systemd.debug_shell")) {
+
                 r = value ? parse_boolean(value) : 1;
                 arg_debug_shell = r != 0;
                 if (r >= 0)
@@ -76,6 +75,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                 return free_and_strdup_warn(&arg_debug_tty, skip_dev_prefix(value));
 
         } else if (proc_cmdline_key_streq(key, "systemd.default_debug_tty")) {
+
                 if (proc_cmdline_value_missing(key, value))
                         return 0;
 
@@ -105,14 +105,12 @@ static int generate_mask_symlinks(void) {
         STRV_FOREACH(u, arg_mask) {
                 _cleanup_free_ char *p = NULL;
 
-                p = path_join(empty_to_root(arg_dest), *u);
+                p = path_join(arg_dest, *u);
                 if (!p)
                         return log_oom();
 
                 if (symlink("/dev/null", p) < 0)
-                        r = log_error_errno(errno,
-                                            "Failed to create mask symlink %s: %m",
-                                            p);
+                        RET_GATHER(r, log_error_errno(errno, "Failed to create mask symlink '%s': %m", p));
         }
 
         return r;
@@ -137,44 +135,44 @@ static int generate_wants_symlinks(void) {
                 if (!f)
                         return log_oom();
 
-                r = generator_add_symlink(arg_dest, target, "wants", f);
-                if (r < 0)
-                        return r;
+                RET_GATHER(r, generator_add_symlink(arg_dest, target, "wants", f));
         }
 
         return r;
 }
 
-static void install_debug_shell_dropin(void) {
+static int install_debug_shell_dropin(void) {
         const char *tty = arg_debug_tty ?: arg_default_debug_tty;
         int r;
 
         if (!tty || path_equal(tty, skip_dev_prefix(DEBUGTTY)))
-                return;
+                return 0;
 
         r = write_drop_in_format(arg_dest, "debug-shell.service", 50, "tty",
-                        "[Unit]\n"
-                        "Description=Early root shell on /dev/%s FOR DEBUGGING ONLY\n"
-                        "ConditionPathExists=\n"
-                        "[Service]\n"
-                        "TTYPath=/dev/%s",
-                        tty, tty);
+                                 "# Automatically generated by systemd-debug-generator\n\n"
+                                 "[Unit]\n"
+                                 "Description=Early root shell on /dev/%s FOR DEBUGGING ONLY\n"
+                                 "ConditionPathExists=\n"
+                                 "\n[Service]\n"
+                                 "TTYPath=/dev/%s\n",
+                                 tty, tty);
         if (r < 0)
-                log_warning_errno(r, "Failed to write drop-in for debug-shell.service, ignoring: %m");
+                return log_warning_errno(r, "Failed to write drop-in for debug-shell.service: %m");
+
+        return 1;
 }
 
 static int process_unit_credentials(const char *credentials_dir) {
+        _cleanup_free_ DirectoryEntries *des = NULL;
         int r;
 
         assert(credentials_dir);
 
-        _cleanup_free_ DirectoryEntries *des = NULL;
         r = readdir_all_at(AT_FDCWD, credentials_dir, RECURSE_DIR_SORT|RECURSE_DIR_IGNORE_DOT|RECURSE_DIR_ENSURE_TYPE, &des);
         if (r < 0)
                 return log_error_errno(r, "Failed to enumerate credentials from credentials directory '%s': %m", credentials_dir);
 
         FOREACH_ARRAY(i, des->entries, des->n_entries) {
-                _cleanup_free_ void *d = NULL;
                 struct dirent *de = *i;
                 const char *unit, *dropin;
 
@@ -193,9 +191,13 @@ static int process_unit_credentials(const char *credentials_dir) {
                         continue;
                 }
 
-                r = read_credential_with_decryption(de->d_name, &d, NULL);
-                if (r < 0)
+                _cleanup_free_ char *d = NULL;
+
+                r = read_credential_with_decryption(de->d_name, (void**) &d, NULL);
+                if (r < 0) {
+                        log_warning_errno(r, "Failed to read credential '%s', ignoring: %m", de->d_name);
                         continue;
+                }
 
                 if (unit) {
                         _cleanup_free_ char *p = NULL;
@@ -213,7 +215,7 @@ static int process_unit_credentials(const char *credentials_dir) {
 
                         log_debug("Wrote unit file '%s' from credential '%s'", unit, de->d_name);
 
-                } else {
+                } else if (dropin) {
                         r = write_drop_in(arg_dest, dropin, 50, "credential", d);
                         if (r < 0) {
                                 log_warning_errno(r, "Failed to write drop-in for unit '%s' from credential '%s', ignoring: %m",
@@ -222,7 +224,8 @@ static int process_unit_credentials(const char *credentials_dir) {
                         }
 
                         log_debug("Wrote drop-in for unit '%s' from credential '%s'", dropin, de->d_name);
-                }
+                } else
+                        assert_not_reached();
         }
 
         return 0;
@@ -230,7 +233,7 @@ static int process_unit_credentials(const char *credentials_dir) {
 
 static int run(const char *dest, const char *dest_early, const char *dest_late) {
         const char *credentials_dir;
-        int r = 0;
+        int r;
 
         assert_se(arg_dest = dest_early);
 
@@ -239,11 +242,10 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
                 log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
 
         if (arg_debug_shell) {
-                r = strv_extend(&arg_wants, "debug-shell.service");
-                if (r < 0)
+                if (strv_extend(&arg_wants, "debug-shell.service") < 0)
                         return log_oom();
 
-                install_debug_shell_dropin();
+                RET_GATHER(r, install_debug_shell_dropin());
         }
 
         if (get_credentials_dir(&credentials_dir) >= 0)
index 468452f8afd1c057f807a1df4f67667c1c86267b..d4e24cd0dd28bc273db016706315fef66554d673 100644 (file)
@@ -16,6 +16,10 @@ DLSYM_FUNCTION(xkb_keymap_new_from_names);
 DLSYM_FUNCTION(xkb_keymap_unref);
 
 static int dlopen_xkbcommon(void) {
+        ELF_NOTE_DLOPEN("xkbcommon",
+                        "Support for keyboard locale descriptions",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, "libxkbcommon.so.0");
+
         return dlopen_many_sym_or_warn(
                         &xkbcommon_dl, "libxkbcommon.so.0", LOG_DEBUG,
                         DLSYM_ARG(xkb_context_new),
index 38bfaa56be259c25d744ea1fc05e52629cb951da..53e966562e6c41115a6089d03bbc00e8b67e71fa 100644 (file)
@@ -2156,6 +2156,14 @@ static int method_do_shutdown_or_sleep(
                                 return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED,
                                                         "Not running on EFI and resume= is not set, or noresume is set. No available method to resume from hibernation");
 
+                        case SLEEP_RESUME_DEVICE_MISSING:
+                                return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED,
+                                                        "Specified resume device is missing or is not an active swap device");
+
+                        case SLEEP_RESUME_MISCONFIGURED:
+                                return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED,
+                                                        "Invalid resume config: resume= is not populated yet resume_offset= is");
+
                         case SLEEP_NOT_ENOUGH_SWAP_SPACE:
                                 return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED,
                                                         "Not enough suitable swap space for hibernation available on compatible block devices and file systems");
index de3e40516ebba3a3cd5774d519660ec704b0d08c..d4ae24053eb6a7545232a8e61ecfcef1448a702a 100644 (file)
@@ -76,6 +76,11 @@ int dlopen_bpf(void) {
         void *dl;
         int r;
 
+        ELF_NOTE_DLOPEN("bpf",
+                        "Support firewalling and sandboxing with BPF",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libbpf.so.1", "libbpf.so.0");
+
         DISABLE_WARNING_DEPRECATED_DECLARATIONS;
 
         dl = dlopen("libbpf.so.1", RTLD_LAZY);
index cbbc85a5cc52a8f5f41dc904088a7f91bcf41b7f..288e6e89425ecf69a17235d9e010d5ddc65115a2 100644 (file)
@@ -252,6 +252,11 @@ int dlopen_cryptsetup(void) {
 
         DISABLE_WARNING_DEPRECATED_DECLARATIONS;
 
+        ELF_NOTE_DLOPEN("cryptsetup",
+                        "Support for disk encryption, integrity, and authentication",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libcryptsetup.so.12");
+
         r = dlopen_many_sym_or_warn(
                         &cryptsetup_dl, "libcryptsetup.so.12", LOG_DEBUG,
                         DLSYM_ARG(crypt_activate_by_passphrase),
index 85f3c173db1f21d3bd74809ad49fb3de3a7542f6..9d1f4946718050078b1fd76d83b62e5f62a20afe 100644 (file)
@@ -87,6 +87,11 @@ static DLSYM_FUNCTION(gelf_getnote);
 int dlopen_dw(void) {
         int r;
 
+        ELF_NOTE_DLOPEN("dw",
+                        "Support for backtrace and ELF package metadata decoding from core files",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libdw.so.1");
+
         r = dlopen_many_sym_or_warn(
                         &dw_dl, "libdw.so.1", LOG_DEBUG,
                         DLSYM_ARG(dwarf_getscopes),
@@ -130,6 +135,11 @@ int dlopen_dw(void) {
 int dlopen_elf(void) {
         int r;
 
+        ELF_NOTE_DLOPEN("elf",
+                        "Support for backtraces and reading ELF package metadata from core files",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libelf.so.1");
+
         r = dlopen_many_sym_or_warn(
                         &elf_dl, "libelf.so.1", LOG_DEBUG,
                         DLSYM_ARG(elf_begin),
index 044d2d074474c91891e4458e075c19477908a4aa..b0abccc26bdb2077954be21788bbc47ca1fd894c 100644 (file)
@@ -354,6 +354,11 @@ int fw_iptables_add_local_dnat(
 }
 
 static int dlopen_iptc(void) {
+        ELF_NOTE_DLOPEN("ip4tc",
+                        "Support for firewall rules",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libip4tc.so.2");
+
         return dlopen_many_sym_or_warn(
                         &iptc_dl,
                         "libip4tc.so.2", LOG_DEBUG,
index cb26a9ab272ec798e718b974a1e165e0a3bcc928..7c21157580f5e4bb3115935e834481fb0e7b366e 100644 (file)
@@ -159,7 +159,7 @@ static int read_resume_config(dev_t *ret_devno, uint64_t *ret_offset) {
         }
 
         if (devno == 0 && offset > 0 && offset != UINT64_MAX)
-                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                return log_debug_errno(SYNTHETIC_ERRNO(ENOMEDIUM),
                                        "Found populated /sys/power/resume_offset (%" PRIu64 ") but /sys/power/resume is not set, refusing.",
                                        offset);
 
@@ -394,7 +394,7 @@ int find_suitable_hibernation_device_full(HibernationDevice *ret_device, uint64_
         if (!entry) {
                 /* No need to check n_swaps == 0, since it's rejected early */
                 assert(resume_config_devno > 0);
-                return log_debug_errno(SYNTHETIC_ERRNO(ENOSPC), "Cannot find swap entry corresponding to /sys/power/resume.");
+                return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Cannot find swap entry corresponding to /sys/power/resume.");
         }
 
         if (ret_device) {
@@ -452,11 +452,11 @@ int hibernation_is_safe(void) {
         bypass_space_check = getenv_bool("SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK") > 0;
 
         r = find_suitable_hibernation_device_full(NULL, &size, &used);
-        if (r == -ENOSPC && bypass_space_check)
-                /* If we don't have any available swap space at all, and SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK
-                 * is set, skip all remaining checks since we can't do that properly anyway. It is quite
-                 * possible that the user is using a setup similar to #30083. When we actually perform
-                 * hibernation in sleep.c we'll check everything again. */
+        if (IN_SET(r, -ENOSPC, -ESTALE) && bypass_space_check)
+                /* If we don't have any available swap space at all, or the specified resume device is missing,
+                 * and $SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK is set, skip all remaining checks since
+                 * we can't do that properly anyway. It is quite possible that the user is using a setup
+                 * similar to #30083. When we actually perform hibernation in sleep.c we'll check everything again. */
                 return 0;
         if (r < 0)
                 return r;
index 6b26f2064a1bd20a494855e2a0e04823428e4e57..aa88e11221701a95fc0589065477e8891fecb70a 100644 (file)
@@ -21,6 +21,11 @@ const char *(*sym_idn2_strerror)(int rc) _const_ = NULL;
 DLSYM_FUNCTION(idn2_to_unicode_8z8z);
 
 int dlopen_idn(void) {
+        ELF_NOTE_DLOPEN("idn",
+                        "Support for internationalized domain names",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libidn2.so.0");
+
         return dlopen_many_sym_or_warn(
                         &idn_dl, "libidn2.so.0", LOG_DEBUG,
                         DLSYM_ARG(idn2_lookup_u8),
@@ -39,6 +44,11 @@ int dlopen_idn(void) {
         _cleanup_(dlclosep) void *dl = NULL;
         int r;
 
+        ELF_NOTE_DLOPEN("idn",
+                        "Support for internationalized domain names",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libidn.so.12", "libidn.so.11");
+
         if (idn_dl)
                 return 0; /* Already loaded */
 
index 48860c7129d3703a227c9e1364d5a26b515bdde6..dd2bd5c94847dcb8076501c143b5d263c4b2797b 100644 (file)
@@ -440,6 +440,11 @@ int install_change_dump_error(const InstallChange *change, char **ret_errmsg, co
                 bus_error = BUS_ERROR_NO_SUCH_UNIT;
                 break;
 
+        case -ENOLINK:
+                m = strjoin("Unit ", change->path, " is an unresolvable alias");
+                bus_error = BUS_ERROR_NO_SUCH_UNIT;
+                break;
+
         case -EUNATCH:
                 m = strjoin("Cannot resolve specifiers in unit ", change->path);
                 bus_error = BUS_ERROR_BAD_UNIT_SETTING;
@@ -3658,18 +3663,19 @@ int unit_file_preset_all(
         if (r < 0)
                 return r;
 
+        r = 0;
         STRV_FOREACH(i, lp.search_path) {
                 _cleanup_closedir_ DIR *d = NULL;
 
                 d = opendir(*i);
                 if (!d) {
-                        if (errno == ENOENT)
-                                continue;
-
-                        return -errno;
+                        if (errno != ENOENT)
+                                RET_GATHER(r, -errno);
+                        continue;
                 }
 
-                FOREACH_DIRENT(de, d, return -errno) {
+                FOREACH_DIRENT(de, d, RET_GATHER(r, -errno)) {
+                        int k;
 
                         if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
                                 continue;
@@ -3677,12 +3683,23 @@ int unit_file_preset_all(
                         if (!IN_SET(de->d_type, DT_LNK, DT_REG))
                                 continue;
 
-                        r = preset_prepare_one(scope, &plus, &minus, &lp, de->d_name, &presets, changes, n_changes);
-                        if (r < 0 &&
-                            !IN_SET(r, -EEXIST, -ERFKILL, -EADDRNOTAVAIL, -EBADSLT, -EIDRM, -EUCLEAN, -ELOOP, -ENOENT, -EUNATCH, -EXDEV))
+                        k = preset_prepare_one(scope, &plus, &minus, &lp, de->d_name, &presets, changes, n_changes);
+                        if (k < 0 &&
+                            !IN_SET(k, -EEXIST,
+                                       -ERFKILL,
+                                       -EADDRNOTAVAIL,
+                                       -ETXTBSY,
+                                       -EBADSLT,
+                                       -EIDRM,
+                                       -EUCLEAN,
+                                       -ELOOP,
+                                       -EXDEV,
+                                       -ENOENT,
+                                       -ENOLINK,
+                                       -EUNATCH))
                                 /* Ignore generated/transient/missing/invalid units when applying preset, propagate other errors.
-                                 * Coordinate with install_changes_dump() above. */
-                                return r;
+                                 * Coordinate with install_change_dump_error() above. */
+                                RET_GATHER(r, k);
                 }
         }
 
index e6d6581597083224b80a4db5199bf4e5dbd69c33..58f6554da275938051a438fde53c7e71d8827313 100644 (file)
@@ -30,6 +30,11 @@ DLSYM_FUNCTION(archive_write_set_format_filter_by_ext);
 DLSYM_FUNCTION(archive_write_set_format_gnutar);
 
 int dlopen_libarchive(void) {
+        ELF_NOTE_DLOPEN("archive",
+                        "Support for decompressing archive files",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libarchive.so.13");
+
         return dlopen_many_sym_or_warn(
                         &libarchive_dl,
                         "libarchive.so.13",
index 17fb019ffcecf8373cb9b2da94fd19cfa8d31661..37f689892551a29f4d16955ae68e51c72037dfbe 100644 (file)
@@ -72,6 +72,11 @@ static void fido_log_propagate_handler(const char *s) {
 int dlopen_libfido2(void) {
         int r;
 
+        ELF_NOTE_DLOPEN("fido2",
+                        "Support fido2 for encryption and authentication",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libfido2.so.1");
+
         r = dlopen_many_sym_or_warn(
                         &libfido2_dl, "libfido2.so.1", LOG_DEBUG,
                         DLSYM_ARG(fido_assert_allow_cred),
index 612ab9c9c5f4bfac816cb478a728fd5f80b561fd..fa1e0f82bb03a4b6c6ec2df832d3a6e0f5d91bac 100644 (file)
@@ -25,6 +25,11 @@ DLSYM_FUNCTION(kmod_unref);
 DLSYM_FUNCTION(kmod_validate_resources);
 
 int dlopen_libkmod(void) {
+        ELF_NOTE_DLOPEN("kmod",
+                        "Support for loading kernel modules",
+                        ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
+                        "libkmod.so.2");
+
         return dlopen_many_sym_or_warn(
                         &libkmod_dl,
                         "libkmod.so.2",
index c32b4935345ba433586f9c289d450351f4ac96ce..764b7724b006a38929427274f94dc32882b8b19e 100644 (file)
@@ -20,6 +20,11 @@ DLSYM_FUNCTION(passwdqc_check);
 DLSYM_FUNCTION(passwdqc_random);
 
 int dlopen_passwdqc(void) {
+        ELF_NOTE_DLOPEN("passwdqc",
+                        "Support for password quality checks",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libpasswdqc.so.1");
+
         return dlopen_many_sym_or_warn(
                         &passwdqc_dl, "libpasswdqc.so.1", LOG_DEBUG,
                         DLSYM_ARG(passwdqc_params_reset),
index e070f9636c66cd54f8f589c6529efd30b71a1d3c..7456469c86e8025c271903773779a0638c237fad 100644 (file)
@@ -24,6 +24,11 @@ DLSYM_FUNCTION(pwquality_set_int_value);
 DLSYM_FUNCTION(pwquality_strerror);
 
 int dlopen_pwquality(void) {
+        ELF_NOTE_DLOPEN("pwquality",
+                        "Support for password quality checks",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libpwquality.so.1");
+
         return dlopen_many_sym_or_warn(
                         &pwquality_dl, "libpwquality.so.1", LOG_DEBUG,
                         DLSYM_ARG(pwquality_check),
index 4f33efc5fc94489c36e0dcc0189f2b0a768fa9ec..7deb64fd49864966398112b6a68c95ad31b7f83d 100644 (file)
@@ -27,6 +27,11 @@ const struct hash_ops pcre2_code_hash_ops_free = {};
 
 int dlopen_pcre2(void) {
 #if HAVE_PCRE2
+        ELF_NOTE_DLOPEN("pcre2",
+                        "Support for regular expressions",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libpcre2-8.so.0");
+
         /* So here's something weird: PCRE2 actually renames the symbols exported by the library via C
          * macros, so that the exported symbols carry a suffix "_8" but when used from C the suffix is
          * gone. In the argument list below we ignore this mangling. Surprisingly (at least to me), we
index 8077ec3019d1a7df05219761e479f3f977485129..b5cd9a35bb2ad4a1c6d8205f8e127b2b94ebb920 100644 (file)
@@ -61,6 +61,11 @@ DLSYM_FUNCTION(p11_kit_uri_new);
 DLSYM_FUNCTION(p11_kit_uri_parse);
 
 int dlopen_p11kit(void) {
+        ELF_NOTE_DLOPEN("p11-kit",
+                        "Support for PKCS11 hardware tokens",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libp11-kit.so.0");
+
         return dlopen_many_sym_or_warn(
                         &p11kit_dl,
                         "libp11-kit.so.0", LOG_DEBUG,
index c087136bd2b3d7857138371a8d9650b0e8c59c4c..e62a5a863581b8adb776d9ee1aa548e16d19f998 100644 (file)
@@ -24,6 +24,11 @@ static DLSYM_FUNCTION(QRcode_free);
 int dlopen_qrencode(void) {
         int r;
 
+        ELF_NOTE_DLOPEN("qrencode",
+                        "Support for generating QR codes",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libqrencode.so.4", "libqrencode.so.3");
+
         FOREACH_STRING(s, "libqrencode.so.4", "libqrencode.so.3") {
                 r = dlopen_many_sym_or_warn(
                         &qrcode_dl, s, LOG_DEBUG,
index aac145836b6c9f62072ef6476b5f71016836398d..3d4d3317109d76d82005204f4651595d87597112 100644 (file)
@@ -368,16 +368,28 @@ static int sleep_supported_internal(
                 }
 
                 r = hibernation_is_safe();
-                if (r == -ENOTRECOVERABLE) {
+                switch (r) {
+
+                case -ENOTRECOVERABLE:
                         *ret_support = SLEEP_RESUME_NOT_SUPPORTED;
                         return false;
-                }
-                if (r == -ENOSPC) {
+
+                case -ESTALE:
+                        *ret_support = SLEEP_RESUME_DEVICE_MISSING;
+                        return false;
+
+                case -ENOMEDIUM:
+                        *ret_support = SLEEP_RESUME_MISCONFIGURED;
+                        return false;
+
+                case -ENOSPC:
                         *ret_support = SLEEP_NOT_ENOUGH_SWAP_SPACE;
                         return false;
+
+                default:
+                        if (r < 0)
+                                return r;
                 }
-                if (r < 0)
-                        return r;
         } else
                 assert(!sleep_config->modes[operation]);
 
index 75d9c4a6221efdda50733993875a2a0392a3393e..b59bce8fc4e052bbbb3823277b77184665249ee6 100644 (file)
@@ -59,6 +59,8 @@ typedef enum SleepSupport {
         SLEEP_NOT_CONFIGURED,              /* SleepConfig.states is not configured */
         SLEEP_STATE_OR_MODE_NOT_SUPPORTED, /* SleepConfig.states/modes are not supported by kernel */
         SLEEP_RESUME_NOT_SUPPORTED,
+        SLEEP_RESUME_DEVICE_MISSING,       /* resume= is specified, but the device cannot be found in /proc/swaps */
+        SLEEP_RESUME_MISCONFIGURED,        /* resume= is not set yet resume_offset= is configured */
         SLEEP_NOT_ENOUGH_SWAP_SPACE,
         SLEEP_ALARM_NOT_SUPPORTED,         /* CLOCK_BOOTTIME_ALARM is unsupported by kernel (only used by s2h) */
 } SleepSupport;
index 3afeb09516904546b1979a1e87ab871df78cd12d..a64c2738bf215a40bea5c02be0010600fa20fd41 100644 (file)
@@ -113,6 +113,11 @@ static DLSYM_FUNCTION(Tss2_RC_Decode);
 int dlopen_tpm2(void) {
         int r;
 
+        ELF_NOTE_DLOPEN("tpm",
+                        "Support for TPM",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libtss2-esys.so.0");
+
         r = dlopen_many_sym_or_warn(
                         &libtss2_esys_dl, "libtss2-esys.so.0", LOG_DEBUG,
                         DLSYM_ARG(Esys_Create),
@@ -164,12 +169,22 @@ int dlopen_tpm2(void) {
         if (r < 0)
                 log_debug("libtss2-esys too old, does not include Esys_TR_GetTpmHandle.");
 
+        ELF_NOTE_DLOPEN("tpm",
+                        "Support for TPM",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libtss2-rc.so.0");
+
         r = dlopen_many_sym_or_warn(
                         &libtss2_rc_dl, "libtss2-rc.so.0", LOG_DEBUG,
                         DLSYM_ARG(Tss2_RC_Decode));
         if (r < 0)
                 return r;
 
+        ELF_NOTE_DLOPEN("tpm",
+                        "Support for TPM",
+                        ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libtss2-mu.so.0");
+
         return dlopen_many_sym_or_warn(
                         &libtss2_mu_dl, "libtss2-mu.so.0", LOG_DEBUG,
                         DLSYM_ARG(Tss2_MU_TPM2_CC_Marshal),
index 3b9987b581f65210f73bf5e7ef556a1c0da34cf3..c671b4170336686da48741375090035329ddd5b8 100644 (file)
@@ -400,7 +400,7 @@ static int parse_credentials(void) {
         size_t sz = 0;
         int r;
 
-        r = read_credential_with_decryption("ssh.listen", (void*) &b, &sz);
+        r = read_credential_with_decryption("ssh.listen", (void**) &b, &sz);
         if (r <= 0)
                 return r;
 
index 4b99d0c62940d6d1518297668312482cfe4f3af6..95cf00fc81bbf9f40bc749600841586ecff02498 100644 (file)
@@ -223,8 +223,11 @@ int verb_start_special(int argc, char *argv[], void *userdata) {
                 case ACTION_HYBRID_SLEEP:
                 case ACTION_SUSPEND_THEN_HIBERNATE:
 
+                        /* For sleep operations, do not automatically fall back to low-level operation for
+                         * errors other than logind not available. There's a high chance that logind did
+                         * some extra sanity check and that didn't pass. */
                         r = logind_reboot(a);
-                        if (r >= 0 || IN_SET(r, -EACCES, -EOPNOTSUPP, -EINPROGRESS))
+                        if (r >= 0 || (r != -ENOSYS && arg_force == 0))
                                 return r;
 
                         arg_no_block = true;