Jo Zzsi [Wed, 16 Jul 2025 14:21:01 +0000 (10:21 -0400)]
fix(dracut.sh): do not use uname to detect kernel version in a container
A big general papercut with dracut right now in that it always assumes
the kernel it's running on is the kernel to target.
This commit lets dracut to detect that it's in a container (e.g. systemd-detect-virt -c),
and check for a single /usr/lib/modules/$kver directory and automatically use that kernel.
Currently this kernel version detection has three copies in the source
(dracut.sh, lsinitrd.sh,test-functions). This commit keeps the
logic for the three copies the same. As a follow-up commit, we should
try to actually share the code for this logic instead of copying it.
Karel Zak [Thu, 19 Jun 2025 16:32:13 +0000 (12:32 -0400)]
fix(dmsquash-live): erofs collision with latest util-linux
This PR fixes the issue that recent kernels can mount EROFS
directly without loop devices, and this feature is enabled in Fedora
kernels (>=6.12; CONFIG_EROFS_FS_BACKED_BY_FILE=y).
This feature is now supported by mount/libmount, too.
I think the best approach would be to avoid the second mount altogether,
independently of the util-linux version.
It is more robust to use a bind mount there than to attempt to create
a second instance of the same file system.
Jo Zzsi [Tue, 15 Jul 2025 02:06:42 +0000 (22:06 -0400)]
chore: eliminate overlapping functions
In its current form inst_library function executes the same set of
commands as the inst function.
Copying (instead of reusing code) is usually preferred, especially
in this particular case where inst_library function is not used by
dracut, so it is not tested by dracut CI.
After this commit, inst_library would just call inst, and inst
is being used and as such tested by dracut CI, so it makes it
less likely to egress out-of tree coide depending on dracut.
Chris Riches [Wed, 9 Jul 2025 16:40:18 +0000 (16:40 +0000)]
fix(dracut): ensure hardlink deduplication is reproducible
By default, hardlink will only deduplicate files with identical mtimes,
down to one-second granularity. If a dracut module rapidly generates
multiple identical files, it is completely up to chance as to whether
their mtimes cross a second boundary or not, and thus whether they get
deduplicated or not. This results in non-reproducible output.
Re-order hardlink with respect to clamping to avoid this problem.
Jo Zzsi [Tue, 15 Jul 2025 02:55:31 +0000 (22:55 -0400)]
test(SYSTEMD): convert test to run without initqueue
Systemd itself provides similar functionality to the
dracut initqueue module. It has been a long-standing
criticism of dracut systemd integration that
initqueue should not be necessary for most system boot scenarios.
While there is still a long way to go, we can start testing some of
the common systemd boot scenarios without initqueue.
See https://github.com/dracut-ng/dracut-ng/issues/1191
Jo Zzsi [Sat, 12 Jul 2025 17:08:20 +0000 (13:08 -0400)]
fix(dracut.conf.d): reserve namespace 50 to out-of-tree configurations
50 should be reserved for out-of-tree dracut configurations, just like
50 is reserved for out-of-tree dracut modules. This policy makes dracut
more consistent and easier to reason about.
Change the built-in dracut configurations from namespace 50 to namespace 10.
Document that the recommended ordering for distribution or user provided
configuration files is in the range of 50-59.
Jo Zzsi [Sat, 12 Jul 2025 16:58:08 +0000 (12:58 -0400)]
ci(gentoo): remove workaround for forcing hostonly mode
Forcing hostonly mode for Gentoo was introduced in commit 9fc9128, as a step towards enabling hostonly mode by default
for all distributions.
After 62fdf59 this workaround for Gentoo is no longer needed to
be maintained as now hostonly is the default for all Linux
installation (set in configure).
Jo Zzsi [Sun, 13 Jul 2025 22:36:56 +0000 (18:36 -0400)]
ci: install NetworkManager into the Void CI container
Previously dracut network-manager package only worked with systemd.
Now after 58baf86, network-manager dracut package should work in
non-systemd Linux distributions as well, such as Void Linux.
Install NetworkManager into the Void CI container to enable
testing it on the CI.
Jo Zzsi [Sat, 12 Jul 2025 16:34:33 +0000 (12:34 -0400)]
fix(fips): make sha512hmac an optional requirement
sha512hmac binary is not available on most Linux distributions,
including openSUSE and it is not a hard requirement for the
fips dracut module to function.
Install sha512hmac with an optional flag to not regress
distributions that have sha512hmac installed and also
enable distributions without sha512hmac to not fail.
Jo Zzsi [Thu, 3 Jul 2025 17:37:35 +0000 (13:37 -0400)]
fix(base): dracut-lib.sh soft depends on poweroff/reboot/halt
Currently base module does not include poweroff/reboot/halt
even though dracut-lib.sh could call these binaries. Dracut
should make it easier to create an initramfs that has all
the dependent libraries.
After this change we can remove poweroff - which was a workaround
for the base module bug - from test modules.
systemd-repart is capable not only of creating a partition, but also of
formatting it. According with repart.d, it is able to create the
following filesystems: ext4, btrfs, xfs, vfat, erofs and squashfs.
Add support in the systemd-repart module for the underlying tools to
allow systemd-repart to format the partition.
Failure to do so would make systemd-repart initramfs unit fail, if
Format= option is provided in a repart.d config file.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Benjamin Drung [Wed, 9 Jul 2025 10:28:51 +0000 (12:28 +0200)]
fix(dracut-install): sort output of --modalias
Calling `dracut-install --modalias` will print kernel modules in an
unstable order. This breaks reproducible builds, because the output is
stored inside the initrd as `lib/dracut/hostonly-kernel-modules.txt`.
So sort the output of `--modalias` to be reproducible and easier to
diff.
Arguments:
dracut modules:
Warning : /boot/initrd.img is a symbolic link, ignoring
Warning : /boot/initrd.img is a symbolic link, ignoring
========================================================================
========================================================================
cpio: premature end of archive
dracut cmdline:
Warning : /boot/initrd.img is a symbolic link, ignoring
```
The `CAT` variable is `zstd -d -c`. The zstd man page says about the
`--force` parameter: "disable input and output checks. Allows [...]
operating on links". So this zstd behavior is intentional.
Resolve the initrd path to the real path. Then `lsinitrd` prints the
correct content and image size:
fix(network-manager): depend on dbus only when using systemd
network-manager does not require dbus to function when using the
--configure-and-quit=initrd option. This should be guaranteed as it is
documented behavior in the NetworkManager.conf(5) manpage and
specifically mentions dracut's use case.
With this change, initramfs images that don't or can't use systemd can
use network-manager instead of the old network-legacy module.
Fixes: #1422 Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Vitaly Kuznetsov [Mon, 23 Jun 2025 13:29:12 +0000 (15:29 +0200)]
fix(systemd-sysext): install the required kernel modules
'systemd-repart' tool is commonly used to produce Discoverable Disk Image
(DDI) ("--make-ddi=TYPE" option) and by default the tool creates 'erofs'
root volume for sysext/confext. Include 'erofs' kernel module into
initramfs if present.
While on in, include 'loop' module as well as this one is an absolute must.
Benjamin Drung [Fri, 27 Jun 2025 13:47:52 +0000 (15:47 +0200)]
test(GETARGS): set NEWROOT and PREFIX for dracut-lib.sh
Set `NEWROOT` to an existing directory to make sourcing `dracut-lib.sh`
work with `set -u`. Also set `PREFIX` to avoid creating `/run/initramfs`
which requires root permission.
See https://www.freedesktop.org/software/systemd/man/latest/systemd-volatile-root.service.html
> This service is only enabled if full volatile mode is selected,
> for example by specifying "systemd.volatile=yes" on the kernel command line.
> This service runs only in the initrd, before the system transitions to the host's root directory.
> Note that this service is not used if "systemd.volatile=state" is used, as in that mode the root
> directory is non-volatile.
Support for this systemd feature has been added in systemd v242 .
https://github.com/systemd/systemd/pull/11243
Coiby Xu [Mon, 26 May 2025 07:34:30 +0000 (15:34 +0800)]
fix: let check_vol_slaves_all return 1 when checks on all slaves fail
Currently check_vol_slaves_all return 0 even after checks on all slaves
fail. And this leads to an issue that "dracut -hostonly-mode strict"
gets stuck forever because instmods keeps waiting for user input when
it's passed empty argument in the kernel-modules module.
Fixes: c7c8c498 ("dracut-functions.sh: catch all lvm slaves") Reported-by: Tomáš Bžatek <tbzatek@redhat.com> Signed-off-by: Coiby Xu <coxu@redhat.com>
Jo Zzsi [Mon, 26 May 2025 00:21:42 +0000 (20:21 -0400)]
fix(systemd): make checking for systemd availability consistent
The best way to check if systemd is available is to check for the
systemd dracut module. Most of the existing code does this already,
fix the remaining few places where it does not.
Replace confusing libsystemd error messages (version < 257 or missing development files) during ./configure
with a message clearly indicating that sd-json support is disabled, as it is optional. Previously, users
saw:
```
$ ./configure
Package dependency requirement 'libsystemd >= 257' could not be satisfied.
Package 'libsystemd' has version '252', required version is '>= 257'
Package dependency requirement 'libsystemd >= 257' could not be satisfied.
Package 'libsystemd' has version '252', required version is '>= 257'
```
```
$ ./configure
Package libsystemd was not found in the pkg-config search path.
Perhaps you should add the directory containing `libsystemd.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libsystemd', required by 'virtual:world', not found
Package libsystemd was not found in the pkg-config search path.
Perhaps you should add the directory containing `libsystemd.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libsystemd', required by 'virtual:world', not found
```
fix(dracut-install): install all suppliers of a supplier's module
After installing a module, we get its dependencies and suppliers' paths,
and recurse into two functions that handle installing those. The code
handling a supplier path tries to also handle suppliers-of-suppliers
relations. But when installing a supplier's module, it only recurses to
suppliers for that specific device provided by the module.
Having a subset of its suppliers might not be enough for a module to
work correctly. Recurse into all suppliers of the supplier modules we
are installing.
fix(dracut-install): do not limit supplier handling to platform bus
The code that explores a sysfs node for suppliers looks for directories
with a "supplier:platform" prefix. Only the "supplier:" prefix refers to
the devlink relation itself here, the rest is the bus and device name of
the supplier. The bus is not necessarily "platform", but can be "phy",
"regulator", etc.
Correct the searched prefix for sysfs supplier relations to "supplier:"
so we can handle all supplier dependencies to devices, not just those
under the platform bus.
The initial device search is still limited to "/sys/devices/platform".
It theoretically limits the dependencies we check to that directory, but
on device-tree systems it looks like all devices are available there and
we don't miss anything.
fix(dracut-install): add sysfs node parents' modules as dependencies
While searching a sysfs node for suppliers to add as dependencies, we
also consider suppliers of its parent nodes as dependencies. The code
doing so doesn't explore suppliers-of-suppliers chains, which is meant
to be handled elsewhere. More importantly it misses the parent nodes of
the devices themselves, parents-of-suppliers chains, and their
dependencies; all of which is necessary to get a device working.
Consider the parent nodes of a sysfs node as a supplier dependency when
building the `module_suppliers` hashmap. So the suppliers-of-suppliers
handling elsewhere can work with any combination of parent/supplier
relation.
James Le Cuirot [Thu, 27 Mar 2025 19:20:35 +0000 (19:20 +0000)]
test: extend TEST-40-SYSTEMD to cover add_dlopen_features
Use systemd's fido2 feature because nothing else is likely to pull in
libfido2.so.1. Not all of the containers currently have a new enough
systemd version for this to work. The test will effectively be skipped
until the container includes a new enough systemd-devel and libfido2.
Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
James Le Cuirot [Wed, 26 Mar 2025 13:02:35 +0000 (13:02 +0000)]
feat(dracut): allow users to choose which dlopen dependencies they want
Handling dlopen dependencies is nice, but installing these
unconditionally will install more than before rather than less, leading
to bigger images and unhappy users.
This introduces the add_dlopen_features and omit_dlopen_features
configuration options. Modules that are successfully loaded set the
default set of features to add_dlopen_features in the config() function.
Users can request additional features by appending to this variable.
They can also omit features by appending to omit_dlopen_features, which
takes precedence.
Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
James Le Cuirot [Wed, 5 Mar 2025 11:53:18 +0000 (11:53 +0000)]
feat(dracut): replace ldd with dracut-install --dry-run or header check
One instance checks whether */lib64/* is used by /bin/sh and another
checks whether libusb is used by scdaemon. These can be handled by the
new dracut-install --dry-run option.
find_binary currently uses ldd to check whether a given *.so* is a valid
ELF. ldd exits successfully even when libraries are missing, so it is
sufficient to replace this check with one that looks at the first 4
bytes.
Closes: https://github.com/dracut-ng/dracut-ng/issues/338 Closes: https://github.com/dracut-ng/dracut-ng/issues/1257 Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
James Le Cuirot [Tue, 4 Mar 2025 17:21:27 +0000 (17:21 +0000)]
feat(dracut-install): add --dry-run option to replace external ldd usage
To remove the remaining use of ldd, we need a way to show which
libraries a binary requires. I initially considered adding another small
tool, sharing code with dracut-install, but then I realised that adding
a --dry-run option to dracut-install would also meet that need with a
lot less effort.
It simply shows what would be installed and doesn't require you to
specify a destination directory. It is similar to the existing --logdir
option, but that cannot log to stdout and includes additional output.
Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
James Le Cuirot [Tue, 4 Mar 2025 11:09:32 +0000 (11:09 +0000)]
feat(dracut-install): extend new ELF parsing code to replace ldd calls
Now that dracut-install has its own ELF parsing code to handle dlopen
dependencies, it is only a small additional step to also handle
traditional DT_NEEDED dependencies, removing the need to call ldd, which
is not cross-friendly.
This avoids the earlier issue seen with musl in #1087.
We should no longer directly install libsystemd*.so because
libsystemd-core does not have the RUNPATH to find libsystemd-shared by
itself. Both get pulled in by the main systemd binary anyway. ldd had
the same issue, dracut-install silently ignored the failure.
Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
James Le Cuirot [Tue, 18 Feb 2025 17:24:05 +0000 (17:24 +0000)]
feat(dracut-install): parse ELF .note.dlopen entries for extra deps
Unlike traditional DT_NEEDED dependencies, there has not been a way to
determine what libraries an ELF may dlopen until recently. systemd has
documented a convention to declare such dependencies using JSON in the
ELF metadata. See https://systemd.io/ELF_DLOPEN_METADATA/ for details.
This metadata references sonames rather than full paths, so Dracut needs
to determine the full paths by itself. It cannot use ldd to do this as
that relies on DT_NEEDED. ldconfig can show the paths for all sonames in
the cache, but that relies on the cache having already been generated,
it isn't cross-friendly, and musl doesn't even have ldconfig. It
therefore makes sense for Dracut to parse the ELF headers directly. This
also paves the way for removing the dependency on ldd entirely, making
Dracut more cross-friendly as a whole.
To avoid adding an entirely new dependency, the JSON parsing is done by
libsystemd's sd-json API. This has been exposed since systemd v257. If
libsystemd is too old or not present at all, then this dlopen handling
is simply skipped. This is currently not an issue for non-systemd
distributions as systemd is the only project using this convention. If
that were to change, libsystemd can still be used without the rest of
systemd, as demonstrated by Gentoo.
The metadata itself has only been included by systemd since v256. If an
earlier version is detected, Dracut will unconditionally install the
same libraries that it did before.
There are different structs for 32-bit and 64-bit ELF headers, so this
new code makes heavy use of C macros to avoid a lot of code duplication.
One macro is also used heavily for endian conversion, as almost every
field needs to be adjusted.
See the code comments for the remaining details.
Closes: https://github.com/dracut-ng/dracut-ng/issues/154 Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>