dracut-module: add DRACUT_FORCE_DRIVERS

Message ID 20261019084817.399159-1-quirin.gylstorff@siemens.com
State Under Review
Headers show
Series dracut-module: add DRACUT_FORCE_DRIVERS | expand

Commit Message

Quirin Gylstorff Oct. 19, 2026, 8:48 a.m. UTC
Some drivers are not loaded by udev in the initrd, e.g. watchdog drivers
which have to be serviced by systemd before the root file system is
mounted. dracut provides force_drivers for this, but it is a global
option.

Add DRACUT_FORCE_DRIVERS to the dracut-module class. The listed drivers
are installed regardless of hostonly mode and loaded early via
rd.driver.pre, same as dracut's force_drivers, but only if the module
is part of the initrd. The module depends on kernel-modules, which
evaluates rd.driver.pre.

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 doc/user_manual.md                                 |  5 +++++
 meta/classes-recipe/dracut-module.bbclass          | 14 ++++++++++++++
 .../dracut-module/files/module-setup.sh.tmpl       | 10 ++++++++++
 3 files changed, 29 insertions(+)

Patch

diff --git a/doc/user_manual.md b/doc/user_manual.md
index a134903d..09ac080b 100644
--- a/doc/user_manual.md
+++ b/doc/user_manual.md
@@ -1877,6 +1877,11 @@  It is controlled by following variables:
 
 - `DRACUT_REQUIRED_BINARIES` defines the binaries required by the module.
 - `DRACUT_MODULE_DEPENDENCIES` defines dependencies to other dracut modules.
+- `DRACUT_FORCE_DRIVERS` defines kernel drivers which are installed into the
+initrd regardless of hostonly mode and loaded early via `rd.driver.pre`,
+like dracut's `force_drivers` option. It adds a dependency to the dracut
+module `kernel-modules`. A machine can set it with
+`DRACUT_FORCE_DRIVERS:pn-<recipe> = "lpc_ich iTCO_wdt"`.
 - `DRACUT_MODULE_NO` defines the module number which prefixes the module name
 to determine the execution order. The default is `50`.
 - `DRACUT_MODULE_NAME` defines the name of the module which is used to install the
diff --git a/meta/classes-recipe/dracut-module.bbclass b/meta/classes-recipe/dracut-module.bbclass
index 6fce979a..6d32a4ac 100644
--- a/meta/classes-recipe/dracut-module.bbclass
+++ b/meta/classes-recipe/dracut-module.bbclass
@@ -22,6 +22,9 @@  DRACUT_MODULE_PATH = "${D}/usr/lib/dracut/modules.d/${DRACUT_MODULE_NO}${DRACUT_
 
 DRACUT_REQUIRED_BINARIES ??= ""
 DRACUT_MODULE_DEPENDENCIES ??= ""
+# Kernel drivers installed regardless of hostonly and loaded early via
+# rd.driver.pre (same semantics as dracut's force_drivers)
+DRACUT_FORCE_DRIVERS ??= ""
 DRACUT_CHECK_CONTENT_FILE_NAME ??= ""
 DRACUT_DEPENDS_CONTENT_FILE_NAME ??= ""
 DRACUT_CMDLINE_CONTENT_FILE_NAME ??= ""
@@ -71,7 +74,18 @@  TEMPLATE_FILES:append = " \
 TEMPLATE_VARS:append = " \
     DRACUT_REQUIRED_BINARIES \
     DRACUT_MODULE_DEPENDENCIES \
+    DRACUT_FORCE_DRIVERS \
+    DRACUT_MODULE_NAME \
     "
+
+python do_validate_dracut_force_drivers() {
+    import re
+    for drv in (d.getVar('DRACUT_FORCE_DRIVERS') or '').split():
+        if not re.fullmatch(r'[A-Za-z0-9_-]+', drv):
+            bb.fatal(f"Invalid driver name '{drv}' in DRACUT_FORCE_DRIVERS")
+}
+addtask validate_dracut_force_drivers before do_transform_template after do_patch
+
 python do_add_additional_dracut_configuration() {
     workdir = os.path.normpath(d.getVar('WORKDIR'))
     module_setup = d.getVar('DRACUT_MODULE_SETUP')
diff --git a/meta/recipes-initramfs/dracut-module/files/module-setup.sh.tmpl b/meta/recipes-initramfs/dracut-module/files/module-setup.sh.tmpl
index b38ae50c..9fc5af93 100644
--- a/meta/recipes-initramfs/dracut-module/files/module-setup.sh.tmpl
+++ b/meta/recipes-initramfs/dracut-module/files/module-setup.sh.tmpl
@@ -15,11 +15,16 @@  check() {
 # Module dependency requirements.
 depends() {
     echo "${DRACUT_MODULE_DEPENDENCIES}"
+    # rd.driver.pre is evaluated by the kernel-modules module
+    [ -z "${DRACUT_FORCE_DRIVERS}" ] || echo "kernel-modules"
     # ISAR_DRACUT_DEPENDS
     return 0
 
 }
 installkernel() {
+    if [ -n "${DRACUT_FORCE_DRIVERS}" ]; then
+        hostonly='' instmods -c ${DRACUT_FORCE_DRIVERS} || return 1
+    fi
     # ISAR_DRACUT_KERNELINSTALL
     return 0
 }
@@ -38,5 +43,10 @@  install() {
             exit 1
         fi
     done
+    for driver in ${DRACUT_FORCE_DRIVERS}; do
+        mkdir -p "$initdir/etc/cmdline.d"
+        echo "rd.driver.pre=$driver" >> \
+            "$initdir/etc/cmdline.d/20-force-drivers-${DRACUT_MODULE_NAME}.conf"
+    done
     # ISAR_DRACUT_INSTALL
 }