Commit Graph
4201 Commits
Author SHA1 Message Date
Yu Watanabe 2bdabb167b basic: rename cap-list.c -> capability-list.c
This also renames relevant files in the same way.

Addresses https://github.com/systemd/systemd/pull/37904#discussion_r2191950396
2025-07-11 18:33:43 +09:00
Zbigniew Jędrzejewski-Szmek d2e22fa6f5 sd-device: trivial cleanups (#38162) 2025-07-11 10:07:30 +02:00
Yu Watanabe 4d7851380a Cleanups for missing_xyz.h headers (#37904)
Continuation of #37960.

The same concern as expalined in #37960 exists also in
missing_syscall.h. If we use enough new glibc, a function we want to use
may be already provided by glibc, but our baseline glibc may not. And it
is hard to detect in our daily development.

This moves all prototypes of syscalls to relevant headers, and missing
syscall functions are defined in relevant .c files of libc wrapper. This
way, we can use usual header as is, e.g. when we want to write code with
`move_mount()`, we can simply use sys/mount.h without checking if it is
supported by our baseline glibc.
2025-07-11 15:20:10 +09:00
Yu Watanabe 3fc2a44043 include: move trivial kernel header wrappers to src/include/override/ 2025-07-11 13:05:46 +09:00
Yu Watanabe 543a48b653 libc-wrapper: introduce a tiny libc wrapper
Then, move syscall definitions to the wrapper, and prototypes are moved
to relevant headers.

This also adds checks for add_key() and request_key(), as one day
glibc may be going to add some of them separatedly.

The check for fspick in meson.build is dropped, as it is currently
unused in our code.

This also moves
- basic/missing_bpf.h -> include/override/linux/bpf.h,
- basic/missing_keyctl.h -> include/override/linux/keyctl.h.
2025-07-11 13:05:46 +09:00
Yu Watanabe 2b912d2066 tree-wide: several cleanups for generating symbol lists and gperf files
- pass our system include directories to make generators use our libc
  wrappers and latest kernel headers,
- include relevant headers in generated gperf file,
- use files() rather than find_program(), as the result of
  find_program() cannot be passed to 'input' of custom_target(),
- move generate-bpf-delegate-configs.py to src/core/, as it is only used
  by libcore.
2025-07-11 13:05:42 +09:00
Yu Watanabe 795a9e8c06 sd-device: replace 'type *func()' -> 'type* func()' 2025-07-11 12:23:35 +09:00
Yu Watanabe f5287e7efd sd-device: do not set errno needlessly 2025-07-11 12:22:58 +09:00
Yu Watanabe 1e29a967c7 catalog: do not read catalog files outside of specified root directory 2025-07-11 10:42:08 +09:00
Ubuntu df5b3426f6 journald: support reloading configuration at runtime 2025-07-10 21:38:36 +02:00
Yu Watanabe 83a047fe23 tree-wide: include sys/stat.h where necessary
These source files uses symbols provided by sys/stat.h, e.g. struct stat,
S_IFREG, S_IFBLK, and so on. Let's explicitly include sys/stat.h where
necessary.

Glibc's fcntl.h includes bits/stat.h, which provides these symbols, so
these symbols can be used without explicitly including sys/stat.h. But,
based on the discussion in #37922, we should explicitly include relevant
headers, and should not rely on the indirect inclusion.

Similar to 4f18ff2e29, but for sys/stat.h.
2025-07-07 12:44:10 +09:00
Mike Yuan d75219711f journal-file: const and _pure_'ify journal_file_writable()
Follow-up for 1543c2385c
2025-07-05 11:45:18 +02:00
Luca Boccassi 144ea281f3 sd-event struct typedefs and comments (#37790) 2025-07-03 22:22:40 +01:00
Mike Yuan b68179c072 fd-util: Move RAW_O_LARGEFILE and O_ACCMODE_STRICT definitions to fd-util.h (#38051) 2025-07-03 22:27:39 +02:00
DaanDeMeyer 4a8c395167 tree-wide: Add initrd presets
Currently, when running "systemctl preset-all --root=xxx" in mkosi
to enable/disable units for initrds, the system presets are used.
The problem with this approach is that the system presets are written
for the system, and that is not necessarily ideal for an initrd, but we
still want to use the same packages in the initrd that we install in the
system, so let's introduce a separate directory for initrd presets which
is used to pick up preset files from when we detect that we're configuring
an initrd (by looking for /etc/initrd-release).

We also introduce a systemd preset file for the initrd, which is based on
the system one, except with all the stuff unnecessary for the initrd removed.
2025-07-03 17:43:01 +02:00
Zbigniew Jędrzejewski-Szmek 9f145c2a9a sd-event: extend comment about a flex member
Follow-up for dbef4dd4f2. Everything that that
commit says is true, but — at least for me — it wasn't obvious why the code is
correct and we can do fixed-size allocations like new(struct inotify_data, 1).
2025-07-03 16:35:40 +02:00
Zbigniew Jędrzejewski-Szmek 391b507257 sd-event: typedef struct inotify_data to InotifyData 2025-07-03 16:35:40 +02:00
Zbigniew Jędrzejewski-Szmek 7eb10d69df sd-event: typedef struct inode_data to InodeData
This is an internal definition, so use the usual CamelCase typedef.
2025-07-03 16:35:40 +02:00
Zbigniew Jędrzejewski-Szmek c9ea39689f sd-event: make some more bools non-bitfield
In sd_event_source.child, we have 5 bools. If we make them each take one byte,
the structure size increases. So let's do that for the three of them, and leave
the other two (less frequently used) squished into the last byte. This allows
more efficient code to be generated, without changing the size of the struct:

$ diff -u <(objdump -S build/src/shared/libsystemd-shared-258.so.0|awk '/^static void source_io_unregister/,/^\}/') \
          <(objdump -S build/src/shared/libsystemd-shared-258.so|awk '/^static void source_io_unregister/,/^\}/')

         s->io.registered = false;
-  34d46f:      48 8b 45 d8             mov    -0x28(%rbp),%rax
-  34d473:      0f b6 90 a4 00 00 00    movzbl 0xa4(%rax),%edx
-  34d47a:      83 e2 fe                and    $0xfffffffe,%edx
-  34d47d:      88 90 a4 00 00 00       mov    %dl,0xa4(%rax)
-  34d483:      eb 04                   jmp    34d489 <source_io_unregister+0x1ca>
+  34bffe:      48 8b 45 d8             mov    -0x28(%rbp),%rax
+  34c002:      c6 80 a4 00 00 00 00    movb   $0x0,0xa4(%rax)
+  34c009:      eb 04                   jmp    34c00f <source_io_unregister+0x1be>
                 return;
2025-07-03 16:33:33 +02:00
Zbigniew Jędrzejewski-Szmek ea51623345 sd-event: drop some bitfield specifiers from struct sd_event_source
This does not change the size of the structure, because the size is determined
by .child, which has a 128-byte siginfo_t field. But by dropping the specifiers
we let the compiler generate code that operates on full bytes instead of having
to play with bitmasks, see second diff below.

Also move the bools in .memory_pressure into a gap to save a few bytes on
initialization.

$ diff -U100 <(pahole build/src/shared/libsystemd-shared-258.so.0 | awk '/struct sd_event_source/,/^}/') \
             <(pahole build/src/shared/libsystemd-shared-258.so | awk '/struct sd_event_source/,/^}/')
--- /proc/self/fd/11	2025-06-08 13:16:55.614738334 +0200
+++ /proc/self/fd/12	2025-06-08 13:16:55.615738386 +0200
@@ -1,109 +1,109 @@
 struct sd_event_source {
 	WakeupType                 wakeup;               /*     0     4 */
 	unsigned int               n_ref;                /*     4     4 */
 	sd_event *                 event;                /*     8     8 */
 	void *                     userdata;             /*    16     8 */
 	sd_event_handler_t         prepare;              /*    24     8 */
 	char *                     description;          /*    32     8 */
 	EventSourceType            type;                 /*    40     4 */
        signed int                 enabled:3;            /*    44: 0  4 */
 	_Bool                      pending:1;            /*    44: 3  1 */
 	_Bool                      dispatching:1;        /*    44: 4  1 */
 	_Bool                      floating:1;           /*    44: 5  1 */
 	_Bool                      exit_on_failure:1;    /*    44: 6  1 */
 	_Bool                      ratelimited:1;        /*    44: 7  1 */

 	/* XXX 24 bits hole, try to pack */

 	int64_t                    priority;             /*    48     8 */
 	unsigned int               pending_index;        /*    56     4 */
 	unsigned int               prepare_index;        /*    60     4 */
 	/* --- cacheline 1 boundary (64 bytes) --- */
 	uint64_t                   pending_iteration;    /*    64     8 */
 	uint64_t                   prepare_iteration;    /*    72     8 */
 	sd_event_destroy_t         destroy_callback;     /*    80     8 */
 	sd_event_handler_t         ratelimit_expire_callback; /*    88     8 */
 	sd_event_source *          sources_next;         /*    96     8 */
 	sd_event_source *          sources_prev;         /*   104     8 */
 	RateLimit                  rate_limit;           /*   112    24 */
 	/* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
 	unsigned int               earliest_index;       /*   136     4 */
 	unsigned int               latest_index;         /*   140     4 */
 	union {
 		struct {
 			sd_event_io_handler_t callback;  /*   144     8 */
 			int        fd;                   /*   152     4 */
 			uint32_t   events;               /*   156     4 */
 			uint32_t   revents;              /*   160     4 */
-			_Bool      registered:1;         /*   164: 0  1 */
-			_Bool      owned:1;              /*   164: 1  1 */
+			_Bool      registered;           /*   164     1 */
+			_Bool      owned;                /*   165     1 */
 		} io;                                    /*   144    24 */
 		struct {
 			sd_event_time_handler_t callback; /*   144     8 */
 			usec_t     next;                 /*   152     8 */
 			usec_t     accuracy;             /*   160     8 */
 		} time;                                  /*   144    24 */
 		struct {
 			sd_event_signal_handler_t callback; /*   144     8 */
 			struct signalfd_siginfo siginfo; /*   152   128 */
 			/* --- cacheline 4 boundary (256 bytes) was 24 bytes ago --- */
 			int        sig;                  /*   280     4 */
 			_Bool      unblock;              /*   284     1 */
 		} signal;                                /*   144   144 */
 		struct {
 			sd_event_child_handler_t callback; /*   144     8 */
 			siginfo_t  siginfo;              /*   152   128 */
 			/* --- cacheline 4 boundary (256 bytes) was 24 bytes ago --- */
 			pid_t      pid;                  /*   280     4 */
 			int        options;              /*   284     4 */
 			int        pidfd;                /*   288     4 */
 			_Bool      registered:1;         /*   292: 0  1 */
 			_Bool      pidfd_owned:1;        /*   292: 1  1 */
 			_Bool      process_owned:1;      /*   292: 2  1 */
 			_Bool      exited:1;             /*   292: 3  1 */
 			_Bool      waited:1;             /*   292: 4  1 */
 		} child;                                 /*   144   152 */
 		struct {
 			sd_event_handler_t callback;     /*   144     8 */
 		} defer;                                 /*   144     8 */
 		struct {
 			sd_event_handler_t callback;     /*   144     8 */
 		} post;                                  /*   144     8 */
 		struct {
 			sd_event_handler_t callback;     /*   144     8 */
 			unsigned int prioq_index;        /*   152     4 */
 		} exit;                                  /*   144    16 */
 		struct {
 			sd_event_inotify_handler_t callback; /*   144     8 */
 			uint32_t   mask;                 /*   152     4 */

 			/* XXX 4 bytes hole, try to pack */

 			struct inode_data * inode_data;  /*   160     8 */
 			sd_event_source * by_inode_data_next; /*   168     8 */
 			sd_event_source * by_inode_data_prev; /*   176     8 */
 		} inotify;                               /*   144    40 */
 		struct {
 			int        fd;                   /*   144     4 */
+			_Bool      registered;           /*   148     1 */
+			_Bool      locked;               /*   149     1 */
+			_Bool      in_write_list;        /*   150     1 */

-			/* XXX 4 bytes hole, try to pack */
+			/* XXX 1 byte hole, try to pack */

 			sd_event_handler_t callback;     /*   152     8 */
 			void *     write_buffer;         /*   160     8 */
 			size_t     write_buffer_size;    /*   168     8 */
 			uint32_t   events;               /*   176     4 */
 			uint32_t   revents;              /*   180     4 */
 			sd_event_source * write_list_next; /*   184     8 */
 			/* --- cacheline 3 boundary (192 bytes) --- */
 			sd_event_source * write_list_prev; /*   192     8 */
-			_Bool      registered:1;         /*   200: 0  1 */
-			_Bool      locked:1;             /*   200: 1  1 */
-			_Bool      in_write_list:1;      /*   200: 2  1 */
-		} memory_pressure;                       /*   144    64 */
+		} memory_pressure;                       /*   144    56 */
 	};                                               /*   144   152 */

 	/* size: 296, cachelines: 5, members: 26 */
 	/* sum members: 292 */
 	/* sum bitfield members: 8 bits, bit holes: 1, sum bit holes: 24 bits */
 	/* last cacheline: 40 bytes */
 };

Example diff in assembly:

$ diff -u <(objdump -S build/src/shared/libsystemd-shared-258.so.0|awk '/^static void event_source_time_prioq_reshuffle/,/^\}/') \
          <(objdump -S build/src/shared/libsystemd-shared-258.so|awk '/^static void event_source_time_prioq_reshuffle/,/^\}/')

         d->needs_rearm = true;
-  34d80e:      48 8b 45 f8             mov    -0x8(%rbp),%rax
-  34d812:      0f b6 50 20             movzbl 0x20(%rax),%edx
-  34d816:      83 ca 01                or     $0x1,%edx
-  34d819:      88 50 20                mov    %dl,0x20(%rax)
-  34d81c:      eb 01                   jmp    34d81f <event_source_time_prioq_reshuffle+0x12c>
+  34d7c3:      48 8b 45 f8             mov    -0x8(%rbp),%rax
+  34d7c7:      c6 40 20 01             movb   $0x1,0x20(%rax)
+  34d7cb:      eb 01                   jmp    34d7ce <event_source_time_prioq_reshuffle+0x126>
                 return; /* no-op for an event source which is neither a timer nor ratelimited. */
-  34d81e:      90                      nop
+  34d7cd:      90                      nop
2025-07-03 16:17:42 +02:00
DaanDeMeyer 1543c2385c fd-util: Move O_ACCMODE_STRICT to fd-util.h
We're still discussing whether we want to remove this or not, but
regardless of whether we end up removing it or not, it's something
we add ourselves and as such should not live in our headers that
override glibc headers, so let's move it to fd-util.h.
2025-07-03 14:28:14 +02:00
Yu Watanabe 194a690181 basic: move missing_fcntl.h -> include/fcntl.h 2025-07-01 12:28:12 +09:00
Yu Watanabe bb66c2e480 basic: move missing_mman.h -> include/sys/mman.h
This also makes memfd-util.h include sys/mman.h, as it is necessary for
specifying flags to memfd_create_wrapper() or memfd_new_full().
2025-07-01 12:27:27 +09:00
Yu Watanabe 9a6dcc137c basic: move missing_wait.h -> include/sys/wait.h 2025-07-01 12:27:00 +09:00
Yu Watanabe 4f18ff2e29 tree-wide: include unistd.h where necessary
We use symbols provided by unistd.h without including it. E.g.
open(), close(), read(), write(), access(), symlink(), unlink(), rmdir(),
fsync(), syncfs(), lseek(), ftruncate(), fchown(), dup2(), pipe2(),
getuid(), getgid(), gettid(), getppid(), pipe2(), execv(), _exit(),
environ, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, F_OK, and their
friends and variants, so on.

Currently, unistd.h is indirectly included mainly in the following two paths:
- through missing_syscall.h, which is planned to covert to .c file.
- through signal.h -> bits/sigstksz.h, which is new since glibc-2.34.
  Note, signal.h is included by sd-eevent.h. So, many source files
  indirectly include unistd.h if newer glibc is used.

Currently, our baseline on glibc is 2.31. We need to support glibc older
than 2.34, but unfortunately, we do not have any CI environments with
such old glibc. CIFuzz uses glibc-2.31, but it builds only fuzzers, and
many files are even not compiled.
2025-06-30 09:19:15 +02:00
Yu Watanabe b351ebdc97 Revert "tree-wide: use CONF_FILES_CHASE_BASENAME where root directory is specified"
This reverts commit 6b606f3586.

The commit was mistakenly merged without review, and has several issues.
Let's revert at least now.
2025-06-29 10:15:56 +09:00
Zbigniew Jędrzejewski-Szmek 7d247d3cb8 meson: drop explicit custom_target names
[1] says:
> Since 0.60.0 the name argument is optional and defaults to the basename of
> the first output
We specify >= 0.62 as the supported version, so drop the duplicate name in all cases
where it is the same as outputs[0], i.e. almost all cases.

[1] https://mesonbuild.com/Reference-manual_functions.html#custom_target
2025-06-28 17:14:50 +02:00
Yu Watanabe 6b606f3586 tree-wide: use CONF_FILES_CHASE_BASENAME where root directory is specified
Otherwise, the result may point to outside of the root directory.

This also sets CONF_FILES_REGULAR and CONF_FILES_FILTER_MASKED, as the
callers will call fopen() or friends for the result, thus the enumerated
results must be non-empty regular files.
2025-06-28 04:13:43 +09:00
Lennart Poettering 7620f70464 logind: introduce a proper error if op is blocked by inhibitor lock
We map it client side to EACCES, because that's what systemctl wants for
its logic.

See: #34091
2025-06-26 15:21:01 +02:00
Yu Watanabe abb99d3168 mallinfo-util: assume mallinfo() exists
The check existed for musl. Let's remove it, as we explicitly request glibc.

While removing the check, this also drops generic_mallinfo, introduces
a tiny converter from struct mallinfo to struct mallinfo2 if mallinfo2()
does not exist, and renames mallinfo-util.h to malloc.h.

With this change, we can drop many ifdefs and casts in .c files.
2025-06-18 10:45:27 +02:00
Yu Watanabe 31a1e15ccb sd-bus: coding style cleanups
- replace `type *func()` -> `type* func()`,
- rename arguments for storing results,
- add several missing assertions.
2025-06-18 01:54:07 +09:00
Yu Watanabe 8cec3cbeb1 sd-bus: BusMessageContainer.begin is always zero in sd_bus_message_open_container() 2025-06-18 01:54:07 +09:00
Mike Yuan ed6b7b6ace sd-varlink: hook up fd passing control with SO_PASSRIGHTS
This is a tricky one, because we effectively turn fd passing input
toggle into a tristate: unset, disabled, and enabled; whereas unset
and disabled were identical previously. *Unset* state silently
ignores SCM_RIGHTS passed by invoking recv() instead of recvmsg(),
and for disabled we now disable SO_PASSRIGHTS completely.

The plot thickens when it comes to the server, since we want to
turn off the SO_PASSRIGHTS already on the listening socket so that
there's no race between accept() and recvmsg() wrt SO_PASSRIGHTS state.
However, if we do this unconditionally, the existing use case of
creating a custom connection callback and enabling fd passing there
would be broken.

Hence, let's introduce a new flag,
SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT, which when set
ties the enablement of fd passing to SO_PASSRIGHTS in server,
and set it for all our varlink servers.

Refer to the previous commit for the rationale behind return value
change in sd_varlink_set_allow_fd_passing_input().
2025-06-17 13:16:44 +02:00
Mike Yuan 72098df843 sd-varlink: unify AF_UNIX check in sd_varlink_set_allow_fd_passing_output()
Currently, the socket type is only checked if the fd passing is
being enabled. The special handling seems unnecessary though,
as in the disable case, either fd passing is already false and
would be caught by the (... == !!b) shortcut at the beginning,
or the AF_UNIX check wouldn't have succeeded in the first place,
for the initial toggle to true. Hence, just uniformly check
AF_UNIX.

While at it, sd_varlink_set_allow_fd_passing_*() oddly return 1
iff changed and !b, which doesn't fit into our coding style and
I can't come up with any use case for such behavior. Let's
return 1 on changed and 0 otherwise.

sd_varlink_set_allow_fd_passing_input() will be fixed in the later
commits with other enhancements.
2025-06-17 13:16:43 +02:00
Mike Yuan 60483ea14c sd-varlink: remove unneeded strdup() 2025-06-17 13:16:43 +02:00
Arkadiusz Bokowy 998aa62a21 sd-bus: Preserve interfaces addition order
When adding a new interface to the object add it at the end of the list.
This way, when iterating over the list, e.g., during handling introspect
call, the order of returned interfaces will mach the order in which they
were added.
2025-06-17 17:28:35 +09:00
Mike Yuan 6fdb6c73ae sd-bus: port to machine_spec_valid() 2025-06-17 01:39:57 +02:00
Yu Watanabe 169d270e81 meson: update generating lists
- config.h is not necessary when generating lists, hence drop it.
- linux/audit.h and libaudit.h are included by missing_audit.h,
  hence not necessary to include them explicitly.
2025-06-09 16:29:49 +01:00
Luca Boccassi f245fa0058 test: do not fail when lacking privs to create sysfs directory
4109s /* test_mdio_bus */
4109s src/libsystemd/sd-device/test-sd-device.c:55: Assertion failed: Expected "mkdir_p(syspath, 0755)" to succeed, but got error: Permission denied
4109s (mdio_bus) terminated by signal ABRT.
4109s src/libsystemd/sd-device/test-sd-device.c:37: Assertion failed: Expected "r = safe_fork("(mdio_bus)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL)" to succeed, but got error: Protocol error

Follow-up for 687a92a1b6
2025-06-09 15:11:30 +09:00
Yu Watanabe 6c2558a2fc tree-wide: allow building with -Wgnu-variable-sized-type-not-at-end option for clang (#37499)
Follow-up for #36993.
Closes #37497.
2025-06-07 01:02:38 +09:00
Yu Watanabe 687a92a1b6 sd-device: replace '!' with '/' before calling sd_device_new_from_subsystem_sysname()
Device ID uses device directory name as is, hence may contain '!', but
sd_device_new_from_subsystem_sysname() expects that the input is sysname.
So, we need to replace '!' with '/'.

Follow-up for 1393c5a2a4.
Fixes #37711.
2025-06-06 23:59:02 +09:00
A. Wilcox 6b783209a8 tree-wide: basename -> path_extract_filename 2025-06-06 19:06:48 +09:00
Lennart Poettering 5ee8b3edb3 journal: replace a bunch of assert() with friendlier checks
We should not rely that data stored in the journal files remains
entirely untouched at all times. Because we unallocate files, data might
go away any time. Hence, never assert() on any expectations on what the
file contains. Instead, handle it more gracefully as a corruption issue,
and return EBADMSG.

Fixes: #35229 #32436
2025-06-05 22:31:41 +02:00
Lennart Poettering 813facd3ba journal: add 'const' at one more place 2025-06-05 22:31:40 +02:00
Lennart Poettering b16cb30edd journal: determine compression once, not twice
This is just paranoia: let's determine the compression to use once,
instead of twice, after all te data is in journal files which might be
corrupted any time, and it would be weird if we came to different
results here each time.
2025-06-05 22:31:39 +02:00
Lennart Poettering 7d52a60843 journal: use EBADMSG for invalid data in file mmap
We must assume that any data in the mmap can change anytime because the
file is deallocated or similar. Let's strictly use EBADMSG for reporting
invalid file contents though (as opposed to using EINVAL if our own code
passes a wrong parameter somwhere).
2025-06-05 22:31:21 +02:00
Lennart Poettering a589e1bd9e varlink-util: format system errors via %m in varlink_call_and_log()
This kinda does what bee59ab901 did for
varlinkctl also for the generic varlink_call_and_log() handler.
2025-06-05 14:28:14 +02:00
Lennart Poettering 79226d797d sd-bus: treat '@' as equivalent to '@.host'
We allow omission of the part before and the part after the @. But so
far we didn't allow omitting both. There's no real reason for
disallowing that, hence be systematic and allow it.
2025-06-05 12:49:42 +02:00
Lennart Poettering 2ae32e9d8f sd-bus: port to split_user_at_host() 2025-06-05 12:49:35 +02:00
Mike Yuan 46b0844743 sd-daemon: add sd_pidfd_get_inode_id()
We nowadays expose pidfdid at various places, e.g. envvars
and dbus properties. Also the sd_notify() MAINPID= message
has been complemented with MAINPIDFDID=. But acquiring
pidfdid is actually non-trivial especially considering
the 32-bit case, hence let's introduce a public helper
in sd-daemon specifically for that purpose.
2025-06-05 01:35:08 +02:00