Luca Boccassi [Sun, 31 May 2026 14:29:50 +0000 (15:29 +0100)]
fix(systemd-networkd): get DHCP options values from networkctl
The internal lease is no longer saved to the private /run/ directory
of networkd since v261, so it cannot be read from there. It was always
clearly marked as private anyway.
Use the new 'dhcp-lease' networkctl verb to print it instead.
fix(iscsi): handle empty URI in firmware boot mode
When rd.iscsi.firmware=1 is set, netroot is either 'iscsi' or 'iscsi:'
with no real URI. parse_iscsi_root() was called with these values causing
'shift count out of range' errors as shift was called on empty positional
parameters.
Add two guards in parse_iscsi_root() to return early when there are no
parameters left to parse, and skip handle_netroot() in iscsiroot.sh when
netroot has no real target.
fix(kernel-modules): add Mediatek MTU3 USB controller
This is the USB dual-role controller used by some MediaTek SoCs.
Adding it fixes booting from USB storage on Lenovo Chromebook Duet EDU
G2 (mt8188-geralt-ciri). That device does not have any SD slot, so USB
storage is the only usable external storage.
Benjamin Drung [Wed, 6 May 2026 16:36:43 +0000 (18:36 +0200)]
test: exit after create-root.sh has been run
The `create-root.sh` scripts are installed as initqueue hook and soured
by it. So just having an exit hook is not enough. The script needs to
exit explicitly to shutdown the boot.
Fixes: 39e4b0a37bb5 ("test: drop poweroff call where poweroff is called by EXIT trap")
Mewt R [Mon, 20 Apr 2026 00:37:27 +0000 (20:37 -0400)]
refactor(dracut): remove unnecessary 'realpath' call if -k/--kmoddir specified
No need to use 'realpath' to resolve a default directory to look for modules
if one has already been specified. 'realpath' will complain if the directory doesn't exist
which can lead a user to think that something went wrong.
According to https://github.com/systemd/systemd/issues/40159#issuecomment-3760597003
the initramfs is expected to include the nvpcr definition files from systemd for
v259 compatibility.
test(SYSTEMD-SYSEXT): introduce tests for systemd-sysext
- A confext creates a marker in /etc/dracut-confext with the content
"dracut-sysext-success".
- A sysext creates a script in
/usr/lib/dracut/hooks/initqueue/finished/dracut-sysext.sh that simply checks if
/etc/dracut-confext exists and prints a message with its content. If this
initqueue script does not succeed, the initqueue main loop will not exit and the
system will not boot.
- Also, check in the QEMU log that "dracut-sysext-success" was printed.
Note:
- systemd-repart creates erofs partitions by default. If it is not supported by
the running distribution, override it to use squashfs.
fix(systemd-sysext): add dependency to systemd-veritysetup
The common use case is a bootloader or a UEFI boot stub (e.g. systemd-stub(7))
that follows the BLS adding extensions found in the ESP to the /.extra directory
in the initrd. In this case, it's used by default a strict
"root=signed+absent:usr=signed+absent" image policy (see
systemd.image-policy(7)). This means, Verity authentication and a PKCS#7
signature of the Verity root hash.
fix(systemd-veritysetup): validate dm-verity signatures in userspace
Since [1], if the validation against the kernel does not work, systemd searches
for PKCS#7 certificates in `/{etc,usr/lib}/verity.d` as a fallback mechanism to
validate dm-verity signatures.
perf(systemd-sysext): do not attempt to install extension metadata
Files under /usr/lib/extension-release.d/extension-release.* and
/etc/extension-release.d/extension-release.* are self contained in sysexts and
confexts respectively. The important file to check if an extension can be
installed is the os-release.
fix(functions): prevent find_binary from dropping last PATH element
When `read` encounters EOF before the delimiter, it returns a non-zero
exit status, causing the while loop to terminate immediately. As a result,
if the PATH string doesn't end with a colon, the very last directory in
PATH is ignored by find_binary().
This caused regressions on split-usr architectures where critical
binaries reside exclusively in /bin, and /bin happens to be
appended at the very end of the PATH by dracut.sh.
Appending a virtual colon to the Here-String ensures the loop processes
all directories correctly.
Jo Zzsi [Sat, 25 Apr 2026 11:12:33 +0000 (07:12 -0400)]
fix(shutdown): warning printed unconditionally
The shutdown dracut module unconditionally warns
"Killing all remaining processes" on every shutdown, even when
no processes need to be killed.
This produces unnecessary warning noise on the console during clean shutdowns.
The warning was introduced in commit 551c2dd (Jan 2013) and was
historically invisible because older dracut versions (e.g. 048) had a less
reliable console redirect. Since version 051,
the improved console redirect logic (echo </dev/console subshell check)
makes the warning reliably visible.
Nowa Ammerlaan [Fri, 24 Apr 2026 08:35:26 +0000 (10:35 +0200)]
fix: disable hostonly_cmdline for Gentoo by default
Our new users are stumbling over a check we added that prevents
accidentally including a cmdline for the live system in the initramfs
for the new install. Since the overall majority of our new users will
be setting a cmdline via the bootloader or system firmware anyway this
setting is not really useful for our users and only creates confusion
because there are now two knobs which control the same thing.
For that reason we would like to disable the hostonly_cmdline by
default (like Fedora does as well).
See-also: https://bugs.gentoo.org/971572 Signed-off-by: Nowa Ammerlaan <nowa@gentoo.org>
Nowa Ammerlaan [Sun, 19 Apr 2026 12:39:00 +0000 (14:39 +0200)]
fix: explicitly set and document Gentoo defaults
Explicitly set Gentoo configuration defaults that we have been
controlling implicitly via other packages. By documenting this
explicitly I hope that users reading this configuration file will
have an (even) easier time finding "the Gentoo way" of doing things
like including microcode or building an UKI. We control these things
outside the scope of Dracut since optional external dependencies are
required for these functions.
(linux-firmware, intel-microcode systemd-stub, ukify, etc).
See-also: https://bugs.gentoo.org/971572 Signed-off-by: Nowa Ammerlaan <nowa@gentoo.org>
feat(dracut-catimages.sh): move images directory from /boot to /var/lib
/boot/dracut in not the right place to save images for multiple reasons, the
most obvious is that it can be a different partition with size constraints, but
also in transactional systems /boot is mounted read-only. Replace this default
directory with /var/lib/dracut/images.
fix(dracut-catimages.sh): do not create overlay image without image directory
Images created using the content of the overlay directory are saved in the image
directory, ignoring --noimagedir, and then not appending it to the base image
either.
```
$ dracut-catimages -v --noimagedir -f test-cat.img test-base.img
Creating image /boot/dracut/90-overlay.img from directory /var/lib/dracut/overlay
Using base image test-base.img
Created test-cat.img
```
So, skip creation of overlay image with `--noimagedir`.
fix(systemd-cryptsetup): load libcryptsetup via dlopen
The `systemd-cryptsetup` binary no longer depends on `libcryptsetup`, and there
is no other binary installed with the `systemd-cryptsetup` or `crypt` modules
that installs it.
```
switch_root:/root# systemd-cryptsetup --version | head -1
systemd 261 (261~devel+git20260423.43dab5ea8)
switch_root:/root# systemd-cryptsetup help
Shared library 'libcryptsetup.so.12' is not available: libcryptsetup.so.12: cannot open shared object file: No such file or directory
switch_root:/root# echo $?
1
```
Benjamin Drung [Mon, 13 Apr 2026 11:15:14 +0000 (13:15 +0200)]
fix(overlayfs): unmount NEWROOT before mounting overlay
When using `rd.overlay` the mount point `/run/rootfsbase` is not
accessible any more, because `LiveOS_rootfs` is mounted over it. This is
`/proc/mounts` from the `tmpfs overlay (rd.overlay)` test case:
feat(systemd-sysext): include systemd-{sys,conf}ext-sysroot services
systemd v261 introduces a pair of new systemd-{sys,conf}ext-sysroot services
that are used to merge system and configuration extensions for the main system
from the initramfs. This allows the extensions to update any part of the main
system, including services that run during early boot.
Include these services in the initramfs. systemd enables them by
default (through 90-systemd-initrd.preset), but dracut does not yet support
systemd presets, so these services are enabled manually. If the newly
introduced logic is undesirable for any reason, systemd provides the
'systemd.{sys,conf}ext=' kernel command-line options, meaning dracut does not
need its own.
Hans de Goede [Sun, 1 Mar 2026 18:28:41 +0000 (19:28 +0100)]
feat(dracut): add module to add fw files from DT firmware-name properties
Devicetree based platforms may need board / model specific firmwares in
the initrd.
E.g. on Qualcomm Snapdragon X1e Windows (WoA) laptops the qcom_q6v5_pas
ADSP driver gets added to the initrd because dracut includes all pinctrl
drivers in the initrd and the 6e80000.pinctrl lpass-lpi-pinctrl device
has a supplier:platform:6800000.remoteproc symlink, dragging the ADSP
driver into the initrd.
The ADSP driver tries to load model-specific firmware files with the
filenames to use specified in a devicetree firmware-name properties.
This module adds support for retrieving the firmware-names from these
devicetree properties and adding the firmware files to the initrd.
The ADSP driver, being a remoteproc driver does bind even without the
firmware files, operating in a degraded mode. This means e.g. no battery
readings and no working audio, since both depend on the ADSP. These
firmware files need to be in the initrd to avoid this degraded mode.
The ADSP driver getting brought into the initrd is actually a good thing,
since the ADSP also controls the Type-C PD-controller(s) and when the
firmware is present and loaded this results in a reset of all Type-C USB
ports, so this needs to happen early on, to e.g. avoid USB-storage devices
getting disconnected and filesystems on top getting in a broken state.
Resolves: #722
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2275920
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2455055 Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
---
Changes in v3:
- Move the `"$DRACUT_ARCH" = "aarch64"` check to the generic/non-hostonly path in `check()`
- Drop the `/lib/firmware/qcom` check from the generic/non-hostonly path in `check()`
- Make _fw_names and _fw_files arrays and drop the shellcheck disable=SC2086
- Refererence issue #722 and 2 Red Hat bugzillas in commit message
Changes in v2:
- Iterate over $fw_dir dirs to pickup firmwares from /lib/firmware/updates
- Directly use $DRACUT_ARCH instead of defining _arch local var
- Add the new module to labeler.yml and core.adoc
- Rename module from devicetree-fw to devicetree-firmware
Jo Zzsi [Fri, 10 Apr 2026 13:21:51 +0000 (09:21 -0400)]
feat(dracut): add a DRACUT_EXTRA_ARGS environment variable
Some build tools (e.g. autopkgtest-build-qemu) invoke dracut indirectly
through update-initramfs via dpkg triggers, making it impossible to pass
extra flags directly on the command line.
Add a DRACUT_EXTRA_ARGS environment variable whose contents are
word-split and prepended to the dracut argument list before option
parsing. This allows callers to inject arbitrary flags without modifying
the configuration on disk:
Jo Zzsi [Sat, 11 Apr 2026 21:44:17 +0000 (17:44 -0400)]
ci(gentoo): enable daily network-legacy testing for Gentoo
It seems Gentoo community is interested in helping to maintain
network-legacy, see
https://github.com/gentoo/gentoo/commit/edce3a9b8cba345ad645502ec3c534b86060030c.
feat(overlayfs-crypt): add new encrypted persistent overlay support
Add a new overlayfs-crypt dracut module that supports LUKS-encrypted
persistent overlay devices via the rd.overlay.crypt kernel parameter,
similar to the overlayroot=crypt in cloud-initramfs-tools.
If the device already contains a LUKS volume, the user is prompted for
the passphrase interactively (via Plymouth if available, otherwise
TTY). Otherwise, the device is wiped, formatted with LUKS using a
randomly generated passphrase, and a new filesystem is created on it.
The overlayfs-crypt module depends on the overlayfs module and signals
mount-overlayfs.sh to proceed via a shared marker file
(/run/overlayfs-crypt-ready).
Benjamin Drung [Fri, 10 Apr 2026 21:22:47 +0000 (23:22 +0200)]
fix(dracut): do not record parameters that do not change the initrd
`dracut --reproducible` encodes the command line in the output. This is
a bit of a hindrance to reproducibility, because it can encode a random
strings. Of all the things, the `--tmpdir` should matter the least for
the generated image(s).
So do not record parameters that do not change the initrd. These
parameters are:
Benjamin Drung [Fri, 10 Apr 2026 10:13:47 +0000 (12:13 +0200)]
test: run all tests with --no-hostonly-cmdline
Several tests fail in a Ubuntu VM after commit 04af3c097797 enabled
`hostonly_cmdline` in hostonly mode again, because the host disks leak
into the `cmdline` config stored in the initrd. See 8c70c5bf99ea
("test(sysroot): run with --no-hostonly-cmdline") for a more detailed
explanation.
fix(squash-lib): inst_libdir_file() does not have a -o option
So it tries to find a file named "-o". Spotted while debugging:
```
/usr/lib/dracut/modules.d/88squash-lib/module-setup.sh@56(squash_install): inst_libdir_file -o 'libgcc_s.so*'
/usr/lib/dracut/dracut-functions.sh@1434(inst_libdir_file): _files=()
/usr/lib/dracut/dracut-functions.sh@1434(inst_libdir_file): local -a _files
/usr/lib/dracut/dracut-functions.sh@1435(inst_libdir_file): local _path
/usr/lib/dracut/dracut-functions.sh@1440(inst_libdir_file): declare -p _libdir_file_cache
/usr/lib/dracut/dracut-functions.sh@1440(inst_libdir_file): grep -q 'declare -A'
/usr/lib/dracut/dracut-functions.sh@1447(inst_libdir_file): [[ -o == \-n ]]
/usr/lib/dracut/dracut-functions.sh@1463(inst_libdir_file): for _dir in $libdirs
/usr/lib/dracut/dracut-functions.sh@1464(inst_libdir_file): for _i in "$@"
/usr/lib/dracut/dracut-functions.sh@1465(inst_libdir_file): for _f in "${dracutsysrootdir-}$_dir"/$_i
/usr/lib/dracut/dracut-functions.sh@1466(inst_libdir_file): _path=/lib64/-o
/usr/lib/dracut/dracut-functions.sh@1467(inst_libdir_file): [[ -e /lib64/-o ]]
/usr/lib/dracut/dracut-functions.sh@1464(inst_libdir_file): for _i in "$@"
/usr/lib/dracut/dracut-functions.sh@1465(inst_libdir_file): for _f in "${dracutsysrootdir-}$_dir"/$_i
/usr/lib/dracut/dracut-functions.sh@1466(inst_libdir_file): _path=/lib64/libgcc_s.so.1
/usr/lib/dracut/dracut-functions.sh@1467(inst_libdir_file): [[ -e /lib64/libgcc_s.so.1 ]]
/usr/lib/dracut/dracut-functions.sh@1467(inst_libdir_file): [[ '' != 1 ]]
/usr/lib/dracut/dracut-functions.sh@1468(inst_libdir_file): _files+=("$_path")
/usr/lib/dracut/dracut-functions.sh@1469(inst_libdir_file): _libdir_file_cache[$_path]=1
/usr/lib/dracut/dracut-functions.sh@1463(inst_libdir_file): for _dir in $libdirs
/usr/lib/dracut/dracut-functions.sh@1464(inst_libdir_file): for _i in "$@"
/usr/lib/dracut/dracut-functions.sh@1465(inst_libdir_file): for _f in "${dracutsysrootdir-}$_dir"/$_i
/usr/lib/dracut/dracut-functions.sh@1466(inst_libdir_file): _path=/usr/lib64/-o
/usr/lib/dracut/dracut-functions.sh@1467(inst_libdir_file): [[ -e /usr/lib64/-o ]]
/usr/lib/dracut/dracut-functions.sh@1464(inst_libdir_file): for _i in "$@"
/usr/lib/dracut/dracut-functions.sh@1465(inst_libdir_file): for _f in "${dracutsysrootdir-}$_dir"/$_i
/usr/lib/dracut/dracut-functions.sh@1466(inst_libdir_file): _path=/usr/lib64/libgcc_s.so.1
/usr/lib/dracut/dracut-functions.sh@1467(inst_libdir_file): [[ -e /usr/lib64/libgcc_s.so.1 ]]
/usr/lib/dracut/dracut-functions.sh@1467(inst_libdir_file): [[ '' != 1 ]]
/usr/lib/dracut/dracut-functions.sh@1468(inst_libdir_file): _files+=("$_path")
/usr/lib/dracut/dracut-functions.sh@1469(inst_libdir_file): _libdir_file_cache[$_path]=1
/usr/lib/dracut/dracut-functions.sh@1463(inst_libdir_file): for _dir in $libdirs
/usr/lib/dracut/dracut-functions.sh@1464(inst_libdir_file): for _i in "$@"
/usr/lib/dracut/dracut-functions.sh@1465(inst_libdir_file): for _f in "${dracutsysrootdir-}$_dir"/$_i
/usr/lib/dracut/dracut-functions.sh@1466(inst_libdir_file): _path=/lib/-o
/usr/lib/dracut/dracut-functions.sh@1467(inst_libdir_file): [[ -e /lib/-o ]]
/usr/lib/dracut/dracut-functions.sh@1464(inst_libdir_file): for _i in "$@"
/usr/lib/dracut/dracut-functions.sh@1465(inst_libdir_file): for _f in "${dracutsysrootdir-}$_dir"/$_i
/usr/lib/dracut/dracut-functions.sh@1466(inst_libdir_file): _path='/lib/libgcc_s.so*'
/usr/lib/dracut/dracut-functions.sh@1467(inst_libdir_file): [[ -e /lib/libgcc_s.so* ]]
/usr/lib/dracut/dracut-functions.sh@1463(inst_libdir_file): for _dir in $libdirs
/usr/lib/dracut/dracut-functions.sh@1464(inst_libdir_file): for _i in "$@"
/usr/lib/dracut/dracut-functions.sh@1465(inst_libdir_file): for _f in "${dracutsysrootdir-}$_dir"/$_i
/usr/lib/dracut/dracut-functions.sh@1466(inst_libdir_file): _path=/usr/lib/-o
/usr/lib/dracut/dracut-functions.sh@1467(inst_libdir_file): [[ -e /usr/lib/-o ]]
```
Benjamin Drung [Tue, 7 Apr 2026 09:55:18 +0000 (11:55 +0200)]
fix(dracut): determine hostonly_cmdline after hostonly setting
Commit 04af3c097797 enabled `hostonly_cmdline` in host-only mode again,
but determining that was done too early. In case `/dev` is not mounted,
the host-only mode is turned off. At that point `hostonly_cmdline` has
already be enabled.
So determine the default for `hostonly_cmdline` after the final check
for `hostonly`.
Benjamin Drung [Wed, 25 Mar 2026 18:44:54 +0000 (19:44 +0100)]
fix(SYSTEMD-IMPORT): remount /sysroot with dev and suid flags
When using `systemd-import` combined with a tarball, the resulting root
filesystem retains the `nosuid` mount flag. This breaks any `setuid`
binaries in the booted OS, causing critical utilities like sudo to fail
with:
```
sudo: sudo must be owned by uid 0 and have the setuid bit set
```
Apply a workaround to remount `/sysroot` with the `dev` and `suid`
flags. This workaround can be dropped when systemd is fixed or made
conditional to only the affected systemd versions.
Usually `DRACUT_ARCH` is not set, so we are calling `uname -m` multiple times to
get always the same value. Hence, get its external value at the beginning and
export it globally, in the same way we do with other global variables.
Jo Zzsi [Mon, 30 Mar 2026 13:52:05 +0000 (09:52 -0400)]
ci: temporary remove Fedora Rawhide CI
There is an acknoledged unresolved regression on the Fedora Rawhide CI
container with no workaround.
Since this container generation fails, attempting to run this
CI does not actually increases the code coverage for the dracut project
and removing this container does not actually decreases the code
coverage for dracut.
`parse-crypt.sh` calls `set_systemd_timeout_for_dev /dev/nbd0` which
correctly creates the `timeout.conf` config. But for this configuration
to take action, the systemd daemon needs to be reloaded. This call is
added to the initqueue. Because the system is slow, `dev-nbd0.device`
times out before the systemd daemon is reloaded.
Move the systemd config generating code into a systemd generator. Then
calling `systemctl daemon-reload` is not needed.
Benjamin Drung [Sat, 28 Mar 2026 00:38:49 +0000 (01:38 +0100)]
ci(debian): use a single RUN to install packages
Installing Debian packages in multiple runs will keep layers for each
run which include the package cache. Merge all package installation
commands into one single `RUN` statement to reduce the container size.
Benjamin Drung [Thu, 19 Mar 2026 16:17:09 +0000 (17:17 +0100)]
fix(kernel-modules): install mmc drivers on all architectures
Some systems with Intel Atom CPUs (like Amston Lake, Alder Lake-N, Twin
Lake) have onboard eMMC as a default storage. These eMMC drivers are
missing in the initrd.
On Ubuntu 26.04 "resolute" with linux 7.0.0-7.7 on amd64 the generic
images increases by 0.5 MB (increase from 30.8 MB to 31.3 MB):
Benjamin Drung [Fri, 27 Mar 2026 21:08:44 +0000 (22:08 +0100)]
test(FULL-SYSTEMD): increase device timeout to infinity
Test 41 fails to boot on arm64 on Debian in the autopkgtest because the
service waiting for `/dev/disk/by-label/dracutusr` times out after 90
seconds. This is just caused by the arm64 runner being slow.
So increase the device timeout to infinity to make the test succeed on
slow systems.
See also: d62de66d35d ("test(SYSTEMD-INITRD): increase device timeout to infinity")