Allow systemd to be built as as single statically-linked binary (#42820)

The idea is that we can build a container by building a single-binary
systemd:
```console
$ meson setup build-static --default-library=static --prefer-static --auto-features=disabled -Dbuild-static=true -Dsystemd-multicall-binary=true && ninja -C build-static systemd
$ mkdir /var/tmp/container/usr/lib -p
$ cp build-static/systemd /var/tmp/container/usr/lib/
$ echo 'ID=quick' >/var/tmp/container/usr/lib/os-release
$ systemd-nspawn --restrict-address-families=af_unix --register=no --private-users=managed -D /var/tmp/container/ /usr/lib/systemd
░ Spawning container container on /var/tmp/container.
░ Press Ctrl-] three times within 1s to kill container; two times followed by r
░ to reboot container; two times followed by p to poweroff container.
Selected user namespace base 1855193088 and range 65536.
systemd 262~devel running in system mode (-PAM -AUDIT +SELINUX -APPARMOR +IMA +IPE +SMACK -SECCOMP -GCRYPT +GNUTLS +OPENSSL -ACL +BLKID +CURL -ELFUTILS -FIDO2 +IDN2 +KMOD +LIBCRYPTSETUP +LIBCRYPTSETUP_PLUGINS +LIBFDISK +PCRE2 -PWQUALITY +P11KIT +QRENCODE +TPM2 -BZIP2 -LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK -BTF -XKBCOMMON +UTMP -LIBARCHIVE)
Detected virtualization systemd-nspawn.
Detected architecture x86-64.
Detected first boot.

Welcome to Linux!

Initializing machine ID from container UUID.
Failed to open netlink, ignoring: Address family not supported by protocol
Applying preset policy.
Populated /etc with preset unit settings.
Unit default.target not found.
Falling back to graphical.target.
Mount unit not supported, skipping *MountsFor= dependencies.
Queued start job for default target graphical.target.
[  OK  ] Reached target sysinit.target.
[  OK  ] Reached target basic.target.
System is tainted: unmerged-bin:var-run-bad
[  OK  ] Reached target multi-user.target.
[  OK  ] Reached target graphical.target.
Startup finished in 61ms.
```
The container can be reloaded with SIGTERM, powered off with SIGRTMIN+4,
etc. SIGRTMIN+5 should cause a reboot but it currently fails:
```
...
Rebooting.
Container container is being rebooted.
Failed to attach root directory: Invalid argument
Failed to receive mount namespace fd from outer child: Input/output error
```
It's a bug … somewhere, but probably not caused by the linking changes
being done here.
This commit is contained in:
Lennart Poettering
2026-07-02 21:56:27 +02:00
committed by GitHub
37 changed files with 1004 additions and 183 deletions
+4 -4
View File
@@ -53,10 +53,10 @@ static int populate_uid_cache(const char *root, Hashmap **ret) {
/* The directory list is hardcoded here: /etc is the standard, and rpm-ostree uses /usr/lib. This
* could be made configurable, but I don't see the point right now. */
FOREACH_STRING(fname, "/etc/passwd", "/usr/lib/passwd") {
STRV_FOREACH(fname, PASSWD_FILES) {
_cleanup_fclose_ FILE *f = NULL;
r = open_passwd_file(root, fname, &f);
r = open_passwd_file(root, *fname, &f);
if (r == -ENOENT)
continue;
if (r < 0)
@@ -93,10 +93,10 @@ static int populate_gid_cache(const char *root, Hashmap **ret) {
if (!cache)
return -ENOMEM;
FOREACH_STRING(fname, "/etc/group", "/usr/lib/group") {
STRV_FOREACH(fname, GROUP_FILES) {
_cleanup_fclose_ FILE *f = NULL;
r = open_passwd_file(root, fname, &f);
r = open_passwd_file(root, *fname, &f);
if (r == -ENOENT)
continue;
if (r < 0)