Blame 0048-Use-dracut-install-to-install-kernel-modules.patch

Harald Hoyer b38677
From 794b2d2c753489635b922457a5ccb06669f37268 Mon Sep 17 00:00:00 2001
Harald Hoyer b38677
From: Harald Hoyer <harald@redhat.com>
Harald Hoyer b38677
Date: Thu, 23 Jul 2015 10:35:06 +0200
Harald Hoyer b38677
Subject: [PATCH] Use dracut-install to install kernel modules
Harald Hoyer b38677
Harald Hoyer b38677
dracut-install can now install kernel modules and their corresponding
Harald Hoyer b38677
firmware files.
Harald Hoyer b38677
---
Harald Hoyer b38677
 Makefile                                           |   1 +
Harald Hoyer b38677
 dracut-init.sh                                     | 178 +------
Harald Hoyer b38677
 dracut.sh                                          |   8 +-
Harald Hoyer b38677
 install/dracut-install.c                           | 536 +++++++++++++++++++--
Harald Hoyer b38677
 modules.d/50drm/module-setup.sh                    |  63 +--
Harald Hoyer b38677
 modules.d/90crypt/module-setup.sh                  |   4 +-
Harald Hoyer b38677
 modules.d/90dm/module-setup.sh                     |   3 +-
Harald Hoyer b38677
 modules.d/90kernel-modules/module-setup.sh         |  53 +-
Harald Hoyer b38677
 modules.d/90kernel-network-modules/module-setup.sh |  45 +-
Harald Hoyer b38677
 modules.d/90multipath/module-setup.sh              |  39 +-
Harald Hoyer b38677
 modules.d/95iscsi/module-setup.sh                  |  41 +-
Harald Hoyer b38677
 modules.d/95nfs/module-setup.sh                    |   2 +-
Harald Hoyer b38677
 12 files changed, 580 insertions(+), 393 deletions(-)
Harald Hoyer b38677
Harald Hoyer b38677
diff --git a/Makefile b/Makefile
Harald Hoyer b38677
index 8281f90..0a1ae6c 100644
Harald Hoyer b38677
--- a/Makefile
Harald Hoyer b38677
+++ b/Makefile
Harald Hoyer b38677
@@ -61,6 +61,7 @@ install/util.o: install/util.c install/util.h install/macro.h install/log.h
Harald Hoyer b38677
 install/strv.o: install/strv.c install/strv.h install/util.h install/macro.h install/log.h
Harald Hoyer b38677
 
Harald Hoyer b38677
 install/dracut-install: $(DRACUT_INSTALL_OBJECTS)
Harald Hoyer b38677
+	$(CC) $(LDFLAGS) -o $@ $(DRACUT_INSTALL_OBJECTS) $(LDLIBS) -lkmod
Harald Hoyer b38677
 
Harald Hoyer b38677
 dracut-install: install/dracut-install
Harald Hoyer b38677
 	ln -fs $< $@
Harald Hoyer b38677
diff --git a/dracut-init.sh b/dracut-init.sh
Harald Hoyer b38677
index a8b78ce..e26d97a 100644
Harald Hoyer b38677
--- a/dracut-init.sh
Harald Hoyer b38677
+++ b/dracut-init.sh
Harald Hoyer b38677
@@ -218,6 +218,13 @@ dracut_install() {
Harald Hoyer b38677
     inst_multiple "$@"
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
+dracut_instmods() {
Harald Hoyer b38677
+    [[ $no_kernel = yes ]] && return
Harald Hoyer b38677
+    $DRACUT_INSTALL \
Harald Hoyer b38677
+        ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${srcmods:+--kerneldir "$srcmods"} -m "$@"
Harald Hoyer b38677
+    (($? != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${srcmods:+--kerneldir "$srcmods"} -m "$@" || :
Harald Hoyer b38677
+}
Harald Hoyer b38677
+
Harald Hoyer b38677
 inst_library() {
Harald Hoyer b38677
     local _hostonly_install
Harald Hoyer b38677
     if [[ "$1" == "-H" ]]; then
Harald Hoyer b38677
@@ -847,11 +854,6 @@ install_kmod_with_fw() {
Harald Hoyer b38677
     [[ -e "${initdir}/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" ]] \
Harald Hoyer b38677
         && return 0
Harald Hoyer b38677
 
Harald Hoyer b38677
-    if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -e "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}" ]]; then
Harald Hoyer b38677
-        read ret < "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
Harald Hoyer b38677
-        return $ret
Harald Hoyer b38677
-    fi
Harald Hoyer b38677
-
Harald Hoyer b38677
     if [[ $omit_drivers ]]; then
Harald Hoyer b38677
         local _kmod=${1##*/}
Harald Hoyer b38677
         _kmod=${_kmod%.ko*}
Harald Hoyer b38677
@@ -876,9 +878,6 @@ install_kmod_with_fw() {
Harald Hoyer b38677
 
Harald Hoyer b38677
     inst_simple "$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}"
Harald Hoyer b38677
     ret=$?
Harald Hoyer b38677
-    [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
Harald Hoyer b38677
-        [[ -d "$DRACUT_KERNEL_LAZY_HASHDIR" ]] && \
Harald Hoyer b38677
-        echo $ret > "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
Harald Hoyer b38677
     (($ret != 0)) && return $ret
Harald Hoyer b38677
 
Harald Hoyer b38677
     local _modname=${1##*/} _fwdir _found _fw
Harald Hoyer b38677
@@ -925,51 +924,6 @@ dracut_kernel_post() {
Harald Hoyer b38677
     local _moddirname=${srcmods%%/lib/modules/*}
Harald Hoyer b38677
     local _pid
Harald Hoyer b38677
 
Harald Hoyer b38677
-    if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" ]]; then
Harald Hoyer b38677
-        xargs -r modprobe -a ${_moddirname:+-d ${_moddirname}/} \
Harald Hoyer b38677
-            --ignore-install --show-depends --set-version $kernel \
Harald Hoyer b38677
-            < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" 2>/dev/null \
Harald Hoyer b38677
-            | sort -u \
Harald Hoyer b38677
-            | while read _cmd _modpath _options || [ -n "$_cmd" ]; do
Harald Hoyer b38677
-            [[ $_cmd = insmod ]] || continue
Harald Hoyer b38677
-            echo "$_modpath"
Harald Hoyer b38677
-        done > "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
Harald Hoyer b38677
-
Harald Hoyer b38677
-        (
Harald Hoyer b38677
-            if [[ $DRACUT_INSTALL ]] && [[ -z $_moddirname ]]; then
Harald Hoyer b38677
-                xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} -a < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
Harald Hoyer b38677
-            else
Harald Hoyer b38677
-                while read _modpath || [ -n "$_modpath" ]; do
Harald Hoyer b38677
-                    local _destpath=$_modpath
Harald Hoyer b38677
-                    [[ $_moddirname ]] && _destpath=${_destpath##$_moddirname/}
Harald Hoyer b38677
-                    _destpath=${_destpath##*/lib/modules/$kernel/}
Harald Hoyer b38677
-                    inst_simple "$_modpath" "/lib/modules/$kernel/${_destpath}" || exit $?
Harald Hoyer b38677
-                done < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
Harald Hoyer b38677
-            fi
Harald Hoyer b38677
-        ) &
Harald Hoyer b38677
-        _pid=$(jobs -p | while read a  || [ -n "$a" ]; do printf ":$a";done)
Harald Hoyer b38677
-        _pid=${_pid##*:}
Harald Hoyer b38677
-
Harald Hoyer b38677
-        if [[ $DRACUT_INSTALL ]]; then
Harald Hoyer b38677
-            xargs -r modinfo -k $kernel -F firmware < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep" \
Harald Hoyer b38677
-                | while read line || [ -n "$line" ]; do
Harald Hoyer b38677
-                for _fwdir in $fw_dir; do
Harald Hoyer b38677
-                    echo $_fwdir/$line;
Harald Hoyer b38677
-                done;
Harald Hoyer b38677
-            done | xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} -a -o
Harald Hoyer b38677
-        else
Harald Hoyer b38677
-            for _fw in $(xargs -r modinfo -k $kernel -F firmware < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"); do
Harald Hoyer b38677
-                for _fwdir in $fw_dir; do
Harald Hoyer b38677
-                    [[ -d $_fwdir && -f $_fwdir/$_fw ]] || continue
Harald Hoyer b38677
-                    inst_simple "$_fwdir/$_fw" "/lib/firmware/$_fw"
Harald Hoyer b38677
-                    break
Harald Hoyer b38677
-                done
Harald Hoyer b38677
-            done
Harald Hoyer b38677
-        fi
Harald Hoyer b38677
-
Harald Hoyer b38677
-        wait $_pid
Harald Hoyer b38677
-    fi
Harald Hoyer b38677
-
Harald Hoyer b38677
     for _f in modules.builtin.bin modules.builtin modules.order; do
Harald Hoyer b38677
         [[ $srcmods/$_f ]] && inst_simple "$srcmods/$_f" "/lib/modules/$kernel/$_f"
Harald Hoyer b38677
     done
Harald Hoyer b38677
@@ -981,7 +935,6 @@ dracut_kernel_post() {
Harald Hoyer b38677
         exit 1
Harald Hoyer b38677
     fi
Harald Hoyer b38677
 
Harald Hoyer b38677
-    [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && rm -fr -- "$DRACUT_KERNEL_LAZY_HASHDIR"
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
 [[ "$kernel_current" ]] || export kernel_current=$(uname -r)
Harald Hoyer b38677
@@ -1038,113 +991,32 @@ find_kernel_modules () {
Harald Hoyer b38677
     find_kernel_modules_by_path  drivers
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
-# instmods [-c [-s]] <kernel module> [<kernel module> ... ]
Harald Hoyer b38677
-# instmods [-c [-s]] <kernel subsystem>
Harald Hoyer b38677
-# install kernel modules along with all their dependencies.
Harald Hoyer b38677
-# <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
Harald Hoyer b38677
 instmods() {
Harald Hoyer b38677
+    # instmods [-c [-s]] <kernel module> [<kernel module> ... ]
Harald Hoyer b38677
+    # instmods [-c [-s]] <kernel subsystem>
Harald Hoyer b38677
+    # install kernel modules along with all their dependencies.
Harald Hoyer b38677
+    # <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
Harald Hoyer b38677
+    # -c check
Harald Hoyer b38677
+    # -s silent
Harald Hoyer b38677
+    local _optional="-o"
Harald Hoyer b38677
+    local _silent
Harald Hoyer b38677
+    local _ret
Harald Hoyer b38677
     [[ $no_kernel = yes ]] && return
Harald Hoyer b38677
-    # called [sub]functions inherit _fderr
Harald Hoyer b38677
-    local _fderr=9
Harald Hoyer b38677
-    local _check=no
Harald Hoyer b38677
-    local _silent=no
Harald Hoyer b38677
     if [[ $1 = '-c' ]]; then
Harald Hoyer b38677
-        _check=yes
Harald Hoyer b38677
+        _optional=""
Harald Hoyer b38677
         shift
Harald Hoyer b38677
     fi
Harald Hoyer b38677
-
Harald Hoyer b38677
     if [[ $1 = '-s' ]]; then
Harald Hoyer b38677
-        _silent=yes
Harald Hoyer b38677
+        _silent=1
Harald Hoyer b38677
         shift
Harald Hoyer b38677
     fi
Harald Hoyer b38677
-
Harald Hoyer b38677
-    function inst1mod() {
Harald Hoyer b38677
-        local _ret=0 _mod="$1"
Harald Hoyer b38677
-        case $_mod in
Harald Hoyer b38677
-            =*)
Harald Hoyer b38677
-                ( [[ "$_mpargs" ]] && echo $_mpargs
Harald Hoyer b38677
-                    find_kernel_modules_by_path "${_mod#=}" ) \
Harald Hoyer b38677
-                        | instmods
Harald Hoyer b38677
-                ((_ret+=$?))
Harald Hoyer b38677
-                ;;
Harald Hoyer b38677
-            --*) _mpargs+=" $_mod" ;;
Harald Hoyer b38677
-            *)
Harald Hoyer b38677
-                _mod=${_mod##*/}
Harald Hoyer b38677
-                # Check for aliased modules
Harald Hoyer b38677
-                _modalias=$(modinfo -k $kernel -F filename $_mod 2> /dev/null)
Harald Hoyer b38677
-                _modalias=${_modalias%.ko*}
Harald Hoyer b38677
-                if [[ $_modalias ]] && [ "${_modalias##*/}" != "${_mod%.ko*}" ] ; then
Harald Hoyer b38677
-                    _mod=${_modalias##*/}
Harald Hoyer b38677
-                fi
Harald Hoyer b38677
-
Harald Hoyer b38677
-                # if we are already installed, skip this module and go on
Harald Hoyer b38677
-                # to the next one.
Harald Hoyer b38677
-                if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
Harald Hoyer b38677
-                    [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko*}" ]]; then
Harald Hoyer b38677
-                    read _ret <"$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko*}"
Harald Hoyer b38677
-                    return $_ret
Harald Hoyer b38677
-                fi
Harald Hoyer b38677
-
Harald Hoyer b38677
-                _mod=${_mod/-/_}
Harald Hoyer b38677
-                if [[ $omit_drivers ]] && [[ "$_mod" =~ $omit_drivers ]]; then
Harald Hoyer b38677
-                    dinfo "Omitting driver ${_mod##$srcmods}"
Harald Hoyer b38677
-                    return 0
Harald Hoyer b38677
-                fi
Harald Hoyer b38677
-
Harald Hoyer b38677
-                # If we are building a host-specific initramfs and this
Harald Hoyer b38677
-                # module is not already loaded, move on to the next one.
Harald Hoyer b38677
-                [[ $hostonly ]] \
Harald Hoyer b38677
-                    && ! module_is_host_only "$_mod" \
Harald Hoyer b38677
-                    && return 0
Harald Hoyer b38677
-
Harald Hoyer b38677
-                if [[ "$_check" = "yes" ]] || ! [[ $DRACUT_KERNEL_LAZY_HASHDIR ]]; then
Harald Hoyer b38677
-                    # We use '-d' option in modprobe only if modules prefix path
Harald Hoyer b38677
-                    # differs from default '/'.  This allows us to use dracut with
Harald Hoyer b38677
-                    # old version of modprobe which doesn't have '-d' option.
Harald Hoyer b38677
-                    local _moddirname=${srcmods%%/lib/modules/*}
Harald Hoyer b38677
-                    [[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/"
Harald Hoyer b38677
-
Harald Hoyer b38677
-                    # ok, load the module, all its dependencies, and any firmware
Harald Hoyer b38677
-                    # it may require
Harald Hoyer b38677
-                    for_each_kmod_dep install_kmod_with_fw $_mod \
Harald Hoyer b38677
-                        --set-version $kernel ${_moddirname} $_mpargs
Harald Hoyer b38677
-                    ((_ret+=$?))
Harald Hoyer b38677
-                else
Harald Hoyer b38677
-                    [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
Harald Hoyer b38677
-                        echo ${_mod%.ko*} >> "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist"
Harald Hoyer b38677
-                fi
Harald Hoyer b38677
-                ;;
Harald Hoyer b38677
-        esac
Harald Hoyer b38677
-        return $_ret
Harald Hoyer b38677
-    }
Harald Hoyer b38677
-
Harald Hoyer b38677
-    function instmods_1() {
Harald Hoyer b38677
-        local _mod _mpargs
Harald Hoyer b38677
-        if (($# == 0)); then  # filenames from stdin
Harald Hoyer b38677
-            while read _mod || [ -n "$_mod" ]; do
Harald Hoyer b38677
-                inst1mod "${_mod%.ko*}" || {
Harald Hoyer b38677
-                    if [[ "$_check" == "yes" ]] && [[ "$_silent" == "no" ]]; then
Harald Hoyer b38677
-                        dfatal "Failed to install module $_mod"
Harald Hoyer b38677
-                    fi
Harald Hoyer b38677
-                }
Harald Hoyer b38677
-            done
Harald Hoyer b38677
-        fi
Harald Hoyer b38677
-        while (($# > 0)); do  # filenames as arguments
Harald Hoyer b38677
-            inst1mod ${1%.ko*} || {
Harald Hoyer b38677
-                if [[ "$_check" == "yes" ]] && [[ "$_silent" == "no" ]]; then
Harald Hoyer b38677
-                    dfatal "Failed to install module $1"
Harald Hoyer b38677
-                fi
Harald Hoyer b38677
-            }
Harald Hoyer b38677
-            shift
Harald Hoyer b38677
-        done
Harald Hoyer b38677
-        return 0
Harald Hoyer b38677
-    }
Harald Hoyer b38677
-
Harald Hoyer b38677
-    local _ret _filter_not_found='FATAL: Module .* not found.'
Harald Hoyer b38677
-    # Capture all stderr from modprobe to _fderr. We could use {var}>...
Harald Hoyer b38677
-    # redirections, but that would make dracut require bash4 at least.
Harald Hoyer b38677
-    eval "( instmods_1 \"\$@\" ) ${_fderr}>&1" \
Harald Hoyer b38677
-        | while read line || [ -n "$line" ]; do [[ "$line" =~ $_filter_not_found ]] || echo $line;done | derror
Harald Hoyer b38677
+    if (($# == 0)); then
Harald Hoyer b38677
+        read -r -d '' -a args
Harald Hoyer b38677
+        set -- "${args[@]}"
Harald Hoyer b38677
+    fi
Harald Hoyer b38677
+    $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"}  ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${_optional:+-o} ${_silent:+--silent} ${srcmods:+--kerneldir "$srcmods"} -m "$@"
Harald Hoyer b38677
     _ret=$?
Harald Hoyer b38677
+    (($_ret != 0)) && [[ -z "$_silent" ]] && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${_optional:+-o} ${_silent:+--silent} ${srcmods:+--kerneldir "$srcmods"} -m "$@" || :
Harald Hoyer b38677
+    [[ "$optional" ]] && return 0
Harald Hoyer b38677
     return $_ret
Harald Hoyer b38677
 }
Harald Hoyer b38677
diff --git a/dracut.sh b/dracut.sh
Harald Hoyer b38677
index 37ae350..f6d0439 100755
Harald Hoyer b38677
--- a/dracut.sh
Harald Hoyer b38677
+++ b/dracut.sh
Harald Hoyer b38677
@@ -733,7 +733,7 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
Harald Hoyer b38677
 [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
Harald Hoyer b38677
 [[ $lvmconf_l ]] && lvmconf=$lvmconf_l
Harald Hoyer b38677
 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
Harald Hoyer b38677
-[[ $fw_dir ]] || fw_dir="/lib/firmware/updates /lib/firmware /lib/firmware/$kernel"
Harald Hoyer b38677
+[[ $fw_dir ]] || fw_dir="/lib/firmware/updates:/lib/firmware:/lib/firmware/$kernel"
Harald Hoyer b38677
 [[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
Harald Hoyer b38677
 [[ $tmpdir ]] || tmpdir=/var/tmp
Harald Hoyer b38677
 [[ $INITRD_COMPRESS ]] && compress=$INITRD_COMPRESS
Harald Hoyer b38677
@@ -750,6 +750,7 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
Harald Hoyer b38677
 [[ $kernel_image_l ]] && kernel_image="$kernel_image_l"
Harald Hoyer b38677
 
Harald Hoyer b38677
 # eliminate IFS hackery when messing with fw_dir
Harald Hoyer b38677
+export DRACUT_FIRMWARE_PATH=${fw_dir// /:}
Harald Hoyer b38677
 fw_dir=${fw_dir//:/ }
Harald Hoyer b38677
 
Harald Hoyer b38677
 # check for logfile and try to create one if it doesn't exist
Harald Hoyer b38677
@@ -839,7 +840,6 @@ trap '
Harald Hoyer b38677
 # clean up after ourselves no matter how we die.
Harald Hoyer b38677
 trap 'exit 1;' SIGINT
Harald Hoyer b38677
 
Harald Hoyer b38677
-export DRACUT_KERNEL_LAZY="1"
Harald Hoyer b38677
 export DRACUT_RESOLVE_LAZY="1"
Harald Hoyer b38677
 
Harald Hoyer b38677
 if [[ $print_cmdline ]]; then
Harald Hoyer b38677
@@ -1436,9 +1436,9 @@ if [[ $no_kernel != yes ]]; then
Harald Hoyer b38677
         hostonly='' instmods -c $filesystems
Harald Hoyer b38677
     fi
Harald Hoyer b38677
 
Harald Hoyer b38677
-    dinfo "*** Installing kernel module dependencies and firmware ***"
Harald Hoyer b38677
+    dinfo "*** Installing kernel module dependencies ***"
Harald Hoyer b38677
     dracut_kernel_post
Harald Hoyer b38677
-    dinfo "*** Installing kernel module dependencies and firmware done ***"
Harald Hoyer b38677
+    dinfo "*** Installing kernel module dependencies done ***"
Harald Hoyer b38677
 
Harald Hoyer b38677
     if [[ $noimageifnotneeded == yes ]] && [[ $hostonly ]]; then
Harald Hoyer b38677
         if [[ ! -f "$initdir/lib/dracut/need-initqueue" ]] && \
Harald Hoyer b38677
diff --git a/install/dracut-install.c b/install/dracut-install.c
Harald Hoyer b38677
index 3b48ba8..a20e06c 100644
Harald Hoyer b38677
--- a/install/dracut-install.c
Harald Hoyer b38677
+++ b/install/dracut-install.c
Harald Hoyer b38677
@@ -22,7 +22,7 @@
Harald Hoyer b38677
 #ifndef _GNU_SOURCE
Harald Hoyer b38677
 #define _GNU_SOURCE
Harald Hoyer b38677
 #endif
Harald Hoyer b38677
-
Harald Hoyer b38677
+#undef _FILE_OFFSET_BITS
Harald Hoyer b38677
 #include <ctype.h>
Harald Hoyer b38677
 #include <errno.h>
Harald Hoyer b38677
 #include <fcntl.h>
Harald Hoyer b38677
@@ -38,6 +38,9 @@
Harald Hoyer b38677
 #include <sys/wait.h>
Harald Hoyer b38677
 #include <unistd.h>
Harald Hoyer b38677
 #include <sys/ioctl.h>
Harald Hoyer b38677
+#include <libkmod.h>
Harald Hoyer b38677
+#include <fts.h>
Harald Hoyer b38677
+#include <regex.h>
Harald Hoyer b38677
 
Harald Hoyer b38677
 #include "log.h"
Harald Hoyer b38677
 #include "hashmap.h"
Harald Hoyer b38677
@@ -48,16 +51,31 @@ static bool arg_hmac = false;
Harald Hoyer b38677
 static bool arg_createdir = false;
Harald Hoyer b38677
 static int arg_loglevel = -1;
Harald Hoyer b38677
 static bool arg_optional = false;
Harald Hoyer b38677
+static bool arg_silent = false;
Harald Hoyer b38677
 static bool arg_all = false;
Harald Hoyer b38677
+static bool arg_module = false;
Harald Hoyer b38677
 static bool arg_resolvelazy = false;
Harald Hoyer b38677
 static bool arg_resolvedeps = false;
Harald Hoyer b38677
 static bool arg_hostonly = false;
Harald Hoyer b38677
 static char *destrootdir = NULL;
Harald Hoyer b38677
+static char *kerneldir = NULL;
Harald Hoyer b38677
+static char **firmwaredirs = NULL;
Harald Hoyer b38677
+static char **pathdirs;
Harald Hoyer b38677
 static char *logdir = NULL;
Harald Hoyer b38677
 static char *logfile = NULL;
Harald Hoyer b38677
 FILE *logfile_f = NULL;
Harald Hoyer b38677
 static Hashmap *items = NULL;
Harald Hoyer b38677
 static Hashmap *items_failed = NULL;
Harald Hoyer b38677
+static regex_t mod_filter_path;
Harald Hoyer b38677
+static regex_t mod_filter_nopath;
Harald Hoyer b38677
+static regex_t mod_filter_symbol;
Harald Hoyer b38677
+static regex_t mod_filter_nosymbol;
Harald Hoyer b38677
+static regex_t mod_filter_noname;
Harald Hoyer b38677
+static bool arg_mod_filter_path = false;
Harald Hoyer b38677
+static bool arg_mod_filter_nopath = false;
Harald Hoyer b38677
+static bool arg_mod_filter_symbol = false;
Harald Hoyer b38677
+static bool arg_mod_filter_nosymbol = false;
Harald Hoyer b38677
+static bool arg_mod_filter_noname = false;
Harald Hoyer b38677
 
Harald Hoyer b38677
 static int dracut_install(const char *src, const char *dst, bool isdir, bool resolvedeps, bool hashdst);
Harald Hoyer b38677
 
Harald Hoyer b38677
@@ -516,6 +534,18 @@ void dracut_log_cp(const char *path)
Harald Hoyer b38677
                 log_error("Could not append '%s' to logfile '%s': %m", path, logfile);
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
+static bool check_hashmap(Hashmap *hm, const char *item)
Harald Hoyer b38677
+{
Harald Hoyer b38677
+        char *existing;
Harald Hoyer b38677
+        existing = hashmap_get(hm, item);
Harald Hoyer b38677
+        if (existing) {
Harald Hoyer b38677
+                if (strcmp(existing, item) == 0) {
Harald Hoyer b38677
+                        return true;
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+        return false;
Harald Hoyer b38677
+}
Harald Hoyer b38677
+
Harald Hoyer b38677
 static int dracut_install(const char *src, const char *dst, bool isdir, bool resolvedeps, bool hashdst)
Harald Hoyer b38677
 {
Harald Hoyer b38677
         struct stat sb, db;
Harald Hoyer b38677
@@ -524,26 +554,17 @@ static int dracut_install(const char *src, const char *dst, bool isdir, bool res
Harald Hoyer b38677
         int ret;
Harald Hoyer b38677
         bool src_exists = true;
Harald Hoyer b38677
         char *i = NULL;
Harald Hoyer b38677
-        char *existing;
Harald Hoyer b38677
 
Harald Hoyer b38677
         log_debug("dracut_install('%s', '%s')", src, dst);
Harald Hoyer b38677
 
Harald Hoyer b38677
-        existing = hashmap_get(items_failed, src);
Harald Hoyer b38677
-        if (existing) {
Harald Hoyer b38677
-                if (strcmp(existing, src) == 0) {
Harald Hoyer b38677
-                        log_debug("hash hit items_failed for '%s'", src);
Harald Hoyer b38677
-                        return 1;
Harald Hoyer b38677
-                }
Harald Hoyer b38677
+        if (check_hashmap(items_failed, src)) {
Harald Hoyer b38677
+                log_debug("hash hit items_failed for '%s'", src);
Harald Hoyer b38677
+                return 1;
Harald Hoyer b38677
         }
Harald Hoyer b38677
 
Harald Hoyer b38677
-        if (hashdst) {
Harald Hoyer b38677
-                existing = hashmap_get(items, dst);
Harald Hoyer b38677
-                if (existing) {
Harald Hoyer b38677
-                        if (strcmp(existing, dst) == 0) {
Harald Hoyer b38677
-                                log_debug("hash hit items for '%s'", dst);
Harald Hoyer b38677
-                                return 0;
Harald Hoyer b38677
-                        }
Harald Hoyer b38677
-                }
Harald Hoyer b38677
+        if (hashdst && check_hashmap(items, dst)) {
Harald Hoyer b38677
+                log_debug("hash hit items for '%s'", dst);
Harald Hoyer b38677
+                return 0;
Harald Hoyer b38677
         }
Harald Hoyer b38677
 
Harald Hoyer b38677
         if (lstat(src, &sb) < 0) {
Harald Hoyer b38677
@@ -678,7 +699,7 @@ static int dracut_install(const char *src, const char *dst, bool isdir, bool res
Harald Hoyer b38677
         log_debug("dracut_install ret = %d", ret);
Harald Hoyer b38677
         log_info("cp '%s' '%s'", src, fulldstpath);
Harald Hoyer b38677
 
Harald Hoyer b38677
-        if (arg_hostonly)
Harald Hoyer b38677
+        if (arg_hostonly && !arg_module)
Harald Hoyer b38677
                 mark_hostonly(dst);
Harald Hoyer b38677
 
Harald Hoyer b38677
         ret += cp(src, fulldstpath);
Harald Hoyer b38677
@@ -751,6 +772,9 @@ static int parse_argv(int argc, char *argv[])
Harald Hoyer b38677
 
Harald Hoyer b38677
         enum {
Harald Hoyer b38677
                 ARG_VERSION = 0x100,
Harald Hoyer b38677
+                ARG_SILENT,
Harald Hoyer b38677
+                ARG_KERNELDIR,
Harald Hoyer b38677
+                ARG_FIRMWAREDIRS,
Harald Hoyer b38677
                 ARG_DEBUG
Harald Hoyer b38677
         };
Harald Hoyer b38677
 
Harald Hoyer b38677
@@ -765,13 +789,22 @@ static int parse_argv(int argc, char *argv[])
Harald Hoyer b38677
                 {"optional", no_argument, NULL, 'o'},
Harald Hoyer b38677
                 {"hostonly", no_argument, NULL, 'H'},
Harald Hoyer b38677
                 {"all", no_argument, NULL, 'a'},
Harald Hoyer b38677
+                {"module", no_argument, NULL, 'm'},
Harald Hoyer b38677
                 {"fips", no_argument, NULL, 'f'},
Harald Hoyer b38677
                 {"destrootdir", required_argument, NULL, 'D'},
Harald Hoyer b38677
                 {"logdir", required_argument, NULL, 'L'},
Harald Hoyer b38677
+                {"mod-filter-path", required_argument, NULL, 'p'},
Harald Hoyer b38677
+                {"mod-filter-nopath", required_argument, NULL, 'P'},
Harald Hoyer b38677
+                {"mod-filter-symbol", required_argument, NULL, 's'},
Harald Hoyer b38677
+                {"mod-filter-nosymbol", required_argument, NULL, 'S'},
Harald Hoyer b38677
+                {"mod-filter-noname", required_argument, NULL, 'N'},
Harald Hoyer b38677
+                {"silent", no_argument, NULL, ARG_SILENT},
Harald Hoyer b38677
+                {"kerneldir", required_argument, NULL, ARG_KERNELDIR},
Harald Hoyer b38677
+                {"firmwaredirs", required_argument, NULL, ARG_FIRMWAREDIRS},
Harald Hoyer b38677
                 {NULL, 0, NULL, 0}
Harald Hoyer b38677
         };
Harald Hoyer b38677
 
Harald Hoyer b38677
-        while ((c = getopt_long(argc, argv, "adfhlL:oD:HR", options, NULL)) != -1) {
Harald Hoyer b38677
+        while ((c = getopt_long(argc, argv, "madfhlL:oD:HRp:P:s:S:N:", options, NULL)) != -1) {
Harald Hoyer b38677
                 switch (c) {
Harald Hoyer b38677
                 case ARG_VERSION:
Harald Hoyer b38677
                         puts(PROGRAM_VERSION_STRING);
Harald Hoyer b38677
@@ -782,6 +815,9 @@ static int parse_argv(int argc, char *argv[])
Harald Hoyer b38677
                 case ARG_DEBUG:
Harald Hoyer b38677
                         arg_loglevel = LOG_DEBUG;
Harald Hoyer b38677
                         break;
Harald Hoyer b38677
+                case ARG_SILENT:
Harald Hoyer b38677
+                        arg_silent = true;
Harald Hoyer b38677
+                        break;
Harald Hoyer b38677
                 case 'v':
Harald Hoyer b38677
                         arg_loglevel = LOG_INFO;
Harald Hoyer b38677
                         break;
Harald Hoyer b38677
@@ -797,12 +833,56 @@ static int parse_argv(int argc, char *argv[])
Harald Hoyer b38677
                 case 'a':
Harald Hoyer b38677
                         arg_all = true;
Harald Hoyer b38677
                         break;
Harald Hoyer b38677
+                case 'm':
Harald Hoyer b38677
+                        arg_module = true;
Harald Hoyer b38677
+                        break;
Harald Hoyer b38677
                 case 'D':
Harald Hoyer b38677
                         destrootdir = strdup(optarg);
Harald Hoyer b38677
                         break;
Harald Hoyer b38677
+                case 'p':
Harald Hoyer b38677
+                        if (regcomp(&mod_filter_path, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
Harald Hoyer b38677
+                                log_error("Module path filter %s is not a regular expression", optarg);
Harald Hoyer b38677
+                                exit(EXIT_FAILURE);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        arg_mod_filter_path = true;
Harald Hoyer b38677
+                        break;
Harald Hoyer b38677
+                case 'P':
Harald Hoyer b38677
+                        if (regcomp(&mod_filter_nopath, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
Harald Hoyer b38677
+                                log_error("Module path filter %s is not a regular expression", optarg);
Harald Hoyer b38677
+                                exit(EXIT_FAILURE);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        arg_mod_filter_nopath = true;
Harald Hoyer b38677
+                        break;
Harald Hoyer b38677
+                case 's':
Harald Hoyer b38677
+                        if (regcomp(&mod_filter_symbol, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
Harald Hoyer b38677
+                                log_error("Module symbol filter %s is not a regular expression", optarg);
Harald Hoyer b38677
+                                exit(EXIT_FAILURE);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        arg_mod_filter_symbol = true;
Harald Hoyer b38677
+                        break;
Harald Hoyer b38677
+                case 'S':
Harald Hoyer b38677
+                        if (regcomp(&mod_filter_nosymbol, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
Harald Hoyer b38677
+                                log_error("Module symbol filter %s is not a regular expression", optarg);
Harald Hoyer b38677
+                                exit(EXIT_FAILURE);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        arg_mod_filter_nosymbol = true;
Harald Hoyer b38677
+                        break;
Harald Hoyer b38677
+                case 'N':
Harald Hoyer b38677
+                        if (regcomp(&mod_filter_noname, optarg, REG_NOSUB|REG_EXTENDED) != 0) {
Harald Hoyer b38677
+                                log_error("Module symbol filter %s is not a regular expression", optarg);
Harald Hoyer b38677
+                                exit(EXIT_FAILURE);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        arg_mod_filter_noname = true;
Harald Hoyer b38677
+                        break;
Harald Hoyer b38677
                 case 'L':
Harald Hoyer b38677
                         logdir = strdup(optarg);
Harald Hoyer b38677
                         break;
Harald Hoyer b38677
+                case ARG_KERNELDIR:
Harald Hoyer b38677
+                        kerneldir = strdup(optarg);
Harald Hoyer b38677
+                        break;
Harald Hoyer b38677
+                case ARG_FIRMWAREDIRS:
Harald Hoyer b38677
+                        firmwaredirs = strv_split(optarg, ":");
Harald Hoyer b38677
+                        break;
Harald Hoyer b38677
                 case 'f':
Harald Hoyer b38677
                         arg_hmac = true;
Harald Hoyer b38677
                         break;
Harald Hoyer b38677
@@ -817,6 +897,22 @@ static int parse_argv(int argc, char *argv[])
Harald Hoyer b38677
                 }
Harald Hoyer b38677
         }
Harald Hoyer b38677
 
Harald Hoyer b38677
+        if (arg_module) {
Harald Hoyer b38677
+                if (!firmwaredirs) {
Harald Hoyer b38677
+                        char *path = NULL;
Harald Hoyer b38677
+
Harald Hoyer b38677
+                        path = getenv("DRACUT_FIRMWARE_PATH");
Harald Hoyer b38677
+
Harald Hoyer b38677
+                        if (path == NULL) {
Harald Hoyer b38677
+                                log_error("Environment variable DRACUT_FIRMWARE_PATH is not set");
Harald Hoyer b38677
+                                exit(EXIT_FAILURE);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+                        log_debug("DRACUT_FIRMWARE_PATH=%s", path);
Harald Hoyer b38677
+
Harald Hoyer b38677
+                        firmwaredirs = strv_split(path, ":");
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+        }
Harald Hoyer b38677
         if (!optind || optind == argc) {
Harald Hoyer b38677
                 log_error("No SOURCE argument given");
Harald Hoyer b38677
                 usage(EXIT_FAILURE);
Harald Hoyer b38677
@@ -858,24 +954,11 @@ static int resolve_lazy(int argc, char **argv)
Harald Hoyer b38677
 
Harald Hoyer b38677
 static char **find_binary(const char *src)
Harald Hoyer b38677
 {
Harald Hoyer b38677
-        char *path = NULL;
Harald Hoyer b38677
-        _cleanup_strv_free_ char **p = NULL;
Harald Hoyer b38677
         char **ret = NULL;
Harald Hoyer b38677
         char **q;
Harald Hoyer b38677
         char *newsrc = NULL;
Harald Hoyer b38677
 
Harald Hoyer b38677
-        path = getenv("PATH");
Harald Hoyer b38677
-
Harald Hoyer b38677
-        if (path == NULL) {
Harald Hoyer b38677
-                log_error("PATH is not set");
Harald Hoyer b38677
-                exit(EXIT_FAILURE);
Harald Hoyer b38677
-        }
Harald Hoyer b38677
-
Harald Hoyer b38677
-        log_debug("PATH=%s", path);
Harald Hoyer b38677
-
Harald Hoyer b38677
-        p = strv_split(path, ":");
Harald Hoyer b38677
-
Harald Hoyer b38677
-        STRV_FOREACH(q, p) {
Harald Hoyer b38677
+        STRV_FOREACH(q, pathdirs) {
Harald Hoyer b38677
                 struct stat sb;
Harald Hoyer b38677
                 int r;
Harald Hoyer b38677
 
Harald Hoyer b38677
@@ -976,10 +1059,381 @@ static int install_all(int argc, char **argv)
Harald Hoyer b38677
         return r;
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
+static int install_firmware(struct kmod_module *mod)
Harald Hoyer b38677
+{
Harald Hoyer b38677
+        struct kmod_list *l, *list = NULL;
Harald Hoyer b38677
+        int ret;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        char **q;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        ret = kmod_module_get_info(mod, &list);
Harald Hoyer b38677
+        if (ret < 0) {
Harald Hoyer b38677
+                log_error("could not get modinfo from '%s': %s\n",
Harald Hoyer b38677
+                          kmod_module_get_name(mod), strerror(-ret));
Harald Hoyer b38677
+                return ret;
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+        kmod_list_foreach(l, list) {
Harald Hoyer b38677
+                const char *key = kmod_module_info_get_key(l);
Harald Hoyer b38677
+                const char *value = NULL;
Harald Hoyer b38677
+                char *fwpath = NULL;
Harald Hoyer b38677
+
Harald Hoyer b38677
+                if (!streq("firmware", key))
Harald Hoyer b38677
+                        continue;
Harald Hoyer b38677
+
Harald Hoyer b38677
+                value = kmod_module_info_get_value(l);
Harald Hoyer b38677
+                log_debug("Firmware %s", value);
Harald Hoyer b38677
+                ret = -1;
Harald Hoyer b38677
+                STRV_FOREACH(q, firmwaredirs) {
Harald Hoyer b38677
+                        struct stat sb;
Harald Hoyer b38677
+                        int r;
Harald Hoyer b38677
+
Harald Hoyer b38677
+                        r = asprintf(&fwpath, "%s/%s", *q, value);
Harald Hoyer b38677
+                        if (r < 0) {
Harald Hoyer b38677
+                                log_error("Out of memory!");
Harald Hoyer b38677
+                                exit(EXIT_FAILURE);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+                        if (stat(fwpath, &sb) != 0) {
Harald Hoyer b38677
+                                log_debug("stat(%s) != 0", fwpath);
Harald Hoyer b38677
+                                free(fwpath);
Harald Hoyer b38677
+                                fwpath = NULL;
Harald Hoyer b38677
+                                continue;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+                        ret = dracut_install(fwpath, fwpath, false, false, true);
Harald Hoyer b38677
+                        if (ret == 0)
Harald Hoyer b38677
+                                log_debug("dracut_install '%s' OK", fwpath);
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+
Harald Hoyer b38677
+                if (ret != 0) {
Harald Hoyer b38677
+                        log_info("Possible missing firmware %s for kernel module %s", value, kmod_module_get_name(mod));
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+        return 0;
Harald Hoyer b38677
+}
Harald Hoyer b38677
+
Harald Hoyer b38677
+static bool check_module_symbols(struct kmod_module *mod)
Harald Hoyer b38677
+{
Harald Hoyer b38677
+        struct kmod_list *itr, *deplist = NULL;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (!arg_mod_filter_symbol && !arg_mod_filter_nosymbol)
Harald Hoyer b38677
+                return true;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (kmod_module_get_dependency_symbols(mod, &deplist) < 0) {
Harald Hoyer b38677
+                log_debug("kmod_module_get_dependency_symbols failed");
Harald Hoyer b38677
+                if (arg_mod_filter_symbol)
Harald Hoyer b38677
+                        return false;
Harald Hoyer b38677
+                return true;
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (arg_mod_filter_nosymbol) {
Harald Hoyer b38677
+                kmod_list_foreach(itr, deplist) {
Harald Hoyer b38677
+                        const char *symbol = kmod_module_symbol_get_symbol(itr);
Harald Hoyer b38677
+                        // log_debug("Checking symbol %s", symbol);
Harald Hoyer b38677
+                        if (regexec(&mod_filter_nosymbol, symbol, 0, NULL, 0) == 0) {
Harald Hoyer b38677
+                                kmod_module_dependency_symbols_free_list(deplist);
Harald Hoyer b38677
+                                log_debug("Module %s: symbol %s matched exclusion filter", kmod_module_get_name(mod), symbol);
Harald Hoyer b38677
+                                return false;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (arg_mod_filter_symbol) {
Harald Hoyer b38677
+                kmod_list_foreach(itr, deplist) {
Harald Hoyer b38677
+                        const char *symbol = kmod_module_dependency_symbol_get_symbol(itr);
Harald Hoyer b38677
+                        // log_debug("Checking symbol %s", symbol);
Harald Hoyer b38677
+                        if (regexec(&mod_filter_symbol, symbol, 0, NULL, 0) == 0) {
Harald Hoyer b38677
+                                kmod_module_dependency_symbols_free_list(deplist);
Harald Hoyer b38677
+                                log_debug("Module %s: symbol %s matched inclusion filter", kmod_module_get_name(mod), symbol);
Harald Hoyer b38677
+                                return true;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+                kmod_module_dependency_symbols_free_list(deplist);
Harald Hoyer b38677
+                return false;
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+        kmod_module_dependency_symbols_free_list(deplist);
Harald Hoyer b38677
+        return true;
Harald Hoyer b38677
+}
Harald Hoyer b38677
+
Harald Hoyer b38677
+
Harald Hoyer b38677
+static bool check_module_path(const char *path)
Harald Hoyer b38677
+{
Harald Hoyer b38677
+        if (arg_mod_filter_nopath && (regexec(&mod_filter_nopath, path, 0, NULL, 0) == 0)) {
Harald Hoyer b38677
+                log_debug("Path %s matched exclusion filter", path);
Harald Hoyer b38677
+                return false;
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (arg_mod_filter_path && (regexec(&mod_filter_path, path, 0, NULL, 0) != 0)) {
Harald Hoyer b38677
+                log_debug("Path %s matched inclusion filter", path);
Harald Hoyer b38677
+                return false;
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+        return true;
Harald Hoyer b38677
+}
Harald Hoyer b38677
+
Harald Hoyer b38677
+static int install_module(struct kmod_module *mod)
Harald Hoyer b38677
+{
Harald Hoyer b38677
+        int ret = 0;
Harald Hoyer b38677
+        int state;
Harald Hoyer b38677
+        struct kmod_list *itr, *modlist = NULL;
Harald Hoyer b38677
+        const char *path = NULL;
Harald Hoyer b38677
+        const char *name = NULL;
Harald Hoyer b38677
+        state = kmod_module_get_initstate(mod);
Harald Hoyer b38677
+
Harald Hoyer b38677
+        name = kmod_module_get_name(mod);
Harald Hoyer b38677
+        if (arg_mod_filter_noname && (regexec(&mod_filter_noname, name, 0, NULL, 0) == 0))
Harald Hoyer b38677
+                return 0;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (arg_hostonly && (state != KMOD_MODULE_BUILTIN) && (state != KMOD_MODULE_LIVE)) {
Harald Hoyer b38677
+                log_debug("dracut_install '%s' not hostonly", name);
Harald Hoyer b38677
+                return 0;
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+        path = kmod_module_get_path(mod);
Harald Hoyer b38677
+        if (!path)
Harald Hoyer b38677
+                return -ENOENT;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (check_hashmap(items_failed, path))
Harald Hoyer b38677
+                return 1;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (check_hashmap(items, path))
Harald Hoyer b38677
+                return 0;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (!check_module_path(path) || !check_module_symbols(mod)) {
Harald Hoyer b38677
+                log_debug("No symbol or patch match for '%s'", path);
Harald Hoyer b38677
+                return 0;
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+        log_debug("dracut_install '%s'", path);
Harald Hoyer b38677
+        ret = dracut_install(path, path, false, false, true);
Harald Hoyer b38677
+        if (ret == 0) {
Harald Hoyer b38677
+                log_debug("dracut_install '%s' OK", kmod_module_get_name(mod));
Harald Hoyer b38677
+        } else if (!arg_optional) {
Harald Hoyer b38677
+                if (!arg_silent)
Harald Hoyer b38677
+                        log_error("dracut_install '%s' ERROR", kmod_module_get_name(mod));
Harald Hoyer b38677
+                return ret;
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+        install_firmware(mod);
Harald Hoyer b38677
+
Harald Hoyer b38677
+        modlist = kmod_module_get_dependencies(mod);
Harald Hoyer b38677
+        kmod_list_foreach(itr, modlist) {
Harald Hoyer b38677
+                mod = kmod_module_get_module(itr);
Harald Hoyer b38677
+                path = kmod_module_get_path(mod);
Harald Hoyer b38677
+                name = kmod_module_get_name(mod);
Harald Hoyer b38677
+                if (arg_mod_filter_noname && (regexec(&mod_filter_noname, name, 0, NULL, 0) == 0)) {
Harald Hoyer b38677
+                        kmod_module_unref(mod);
Harald Hoyer b38677
+                        continue;
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+                ret = dracut_install(path, path, false, false, true);
Harald Hoyer b38677
+                if (ret == 0) {
Harald Hoyer b38677
+                        log_debug("dracut_install '%s' OK", kmod_module_get_name(mod));
Harald Hoyer b38677
+                        install_firmware(mod);
Harald Hoyer b38677
+                } else {
Harald Hoyer b38677
+                        log_error("dracut_install '%s' ERROR", kmod_module_get_name(mod));
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+                kmod_module_unref(mod);
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+        kmod_module_unref_list(modlist);
Harald Hoyer b38677
+
Harald Hoyer b38677
+        return ret;
Harald Hoyer b38677
+}
Harald Hoyer b38677
+
Harald Hoyer b38677
+static int install_modules(int argc, char **argv)
Harald Hoyer b38677
+{
Harald Hoyer b38677
+        struct kmod_ctx *ctx = NULL;
Harald Hoyer b38677
+        struct kmod_list *itr, *modlist = NULL;
Harald Hoyer b38677
+        struct kmod_module *mod = NULL, *mod_o = NULL;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        const char *modname = NULL;
Harald Hoyer b38677
+        int i;
Harald Hoyer b38677
+
Harald Hoyer b38677
+        ctx = kmod_new(kerneldir, NULL);
Harald Hoyer b38677
+
Harald Hoyer b38677
+        for (i = 0; i < argc; i++) {
Harald Hoyer b38677
+                int r = 0;
Harald Hoyer b38677
+                int ret = 0;
Harald Hoyer b38677
+                log_debug("Handle module '%s'", argv[i]);
Harald Hoyer b38677
+
Harald Hoyer b38677
+                if (argv[i][0] == '/') {
Harald Hoyer b38677
+                        r = kmod_module_new_from_path(ctx, argv[i], &mod_o);
Harald Hoyer b38677
+                        if (r < 0) {
Harald Hoyer b38677
+                                log_debug("Failed to lookup modules path '%s': %m", argv[i]);
Harald Hoyer b38677
+                                if (!arg_optional)
Harald Hoyer b38677
+                                        return -ENOENT;
Harald Hoyer b38677
+                                continue;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        /* Check, if we have to load another module with that name instead */
Harald Hoyer b38677
+                        modname = kmod_module_get_name(mod_o);
Harald Hoyer b38677
+                        if (!modname) {
Harald Hoyer b38677
+                                if (!arg_optional) {
Harald Hoyer b38677
+                                        if (!arg_silent)
Harald Hoyer b38677
+                                                log_error("Failed to get name for module '%s'", argv[i]);
Harald Hoyer b38677
+                                        return -ENOENT;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                log_info("Failed to get name for module '%s'", argv[i]);
Harald Hoyer b38677
+                                continue;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        r = kmod_module_new_from_lookup(ctx, modname, &modlist);
Harald Hoyer b38677
+                        kmod_module_unref(mod_o);
Harald Hoyer b38677
+                        if (r < 0) {
Harald Hoyer b38677
+                                if (!arg_optional) {
Harald Hoyer b38677
+                                        if (!arg_silent)
Harald Hoyer b38677
+                                                log_error("3 Failed to lookup alias '%s': %d", modname, r);
Harald Hoyer b38677
+                                        return -ENOENT;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                log_info("3 Failed to lookup alias '%s': %d", modname, r);
Harald Hoyer b38677
+                                continue;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        if (!modlist) {
Harald Hoyer b38677
+                                if (!arg_optional) {
Harald Hoyer b38677
+                                        if (!arg_silent)
Harald Hoyer b38677
+                                                log_error("Failed to find module '%s' %s", modname, argv[i]);
Harald Hoyer b38677
+                                        return -ENOENT;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                log_info("Failed to find module '%s' %s", modname, argv[i]);
Harald Hoyer b38677
+                                continue;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        kmod_list_foreach(itr, modlist) {
Harald Hoyer b38677
+                                mod = kmod_module_get_module(itr);
Harald Hoyer b38677
+                                ret = install_module(mod);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        kmod_module_unref_list(modlist);
Harald Hoyer b38677
+                        modlist = 0;
Harald Hoyer b38677
+                } else if (argv[i][0] == '=') {
Harald Hoyer b38677
+                        char *path1, *path2, *path3;
Harald Hoyer b38677
+                        FTS *fts;
Harald Hoyer b38677
+                        log_debug("Handling =%s", &argv[i][1]);
Harald Hoyer b38677
+                        /* FIXME and add more paths*/
Harald Hoyer b38677
+                        {
Harald Hoyer b38677
+                                int r;
Harald Hoyer b38677
+                                r = asprintf(&path2, "%s/kernel/%s", kerneldir, &argv[i][1]);
Harald Hoyer b38677
+                                if (r < 0) {
Harald Hoyer b38677
+                                        log_error("Out of memory!");
Harald Hoyer b38677
+                                        exit(EXIT_FAILURE);
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+
Harald Hoyer b38677
+                                r = asprintf(&path1, "%s/extra/%s", kerneldir, &argv[i][1]);
Harald Hoyer b38677
+                                if (r < 0) {
Harald Hoyer b38677
+                                        log_error("Out of memory!");
Harald Hoyer b38677
+                                        exit(EXIT_FAILURE);
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+
Harald Hoyer b38677
+                                r = asprintf(&path3, "%s/updates/%s", kerneldir, &argv[i][1]);
Harald Hoyer b38677
+                                if (r < 0) {
Harald Hoyer b38677
+                                        log_error("Out of memory!");
Harald Hoyer b38677
+                                        exit(EXIT_FAILURE);
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+
Harald Hoyer b38677
+                                char *paths[] = { path1, path2, path3, NULL };
Harald Hoyer b38677
+                                fts = fts_open(paths, FTS_COMFOLLOW|FTS_NOCHDIR|FTS_NOSTAT|FTS_LOGICAL, NULL);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        for (FTSENT *ftsent = fts_read(fts); ftsent != NULL; ftsent = fts_read(fts)) {
Harald Hoyer b38677
+                                if((ftsent->fts_info == FTS_D) && !check_module_path(ftsent->fts_accpath)) {
Harald Hoyer b38677
+                                        fts_set(fts, ftsent, FTS_SKIP);
Harald Hoyer b38677
+                                        log_debug("Skipping %s", ftsent->fts_accpath);
Harald Hoyer b38677
+                                        continue;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                if((ftsent->fts_info != FTS_F) && (ftsent->fts_info != FTS_SL)) {
Harald Hoyer b38677
+                                        log_debug("Ignoring %s", ftsent->fts_accpath);
Harald Hoyer b38677
+                                        continue;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                log_debug("Handling %s", ftsent->fts_accpath);
Harald Hoyer b38677
+                                r = kmod_module_new_from_path(ctx, ftsent->fts_accpath, &mod_o);
Harald Hoyer b38677
+                                if (r < 0) {
Harald Hoyer b38677
+                                        log_debug("Failed to lookup modules path '%s': %m", ftsent->fts_accpath);
Harald Hoyer b38677
+                                        continue;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+#if 1
Harald Hoyer b38677
+                                /* Check, if we have to load another module with that name instead */
Harald Hoyer b38677
+                                modname = kmod_module_get_name(mod_o);
Harald Hoyer b38677
+                                if (!modname) {
Harald Hoyer b38677
+                                        log_error("Failed to get name for module '%s'", ftsent->fts_accpath);
Harald Hoyer b38677
+                                        continue;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                r = kmod_module_new_from_lookup(ctx, modname, &modlist);
Harald Hoyer b38677
+                                kmod_module_unref(mod_o);
Harald Hoyer b38677
+                                if (r < 0) {
Harald Hoyer b38677
+                                        log_error("2 Failed to lookup alias '%s': %m", modname);
Harald Hoyer b38677
+                                        kmod_module_unref_list(modlist);
Harald Hoyer b38677
+                                        continue;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                if (!modlist) {
Harald Hoyer b38677
+                                        log_error("Failed to find module '%s' %s", modname, ftsent->fts_accpath);
Harald Hoyer b38677
+                                        kmod_module_unref_list(modlist);
Harald Hoyer b38677
+                                        continue;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                kmod_list_foreach(itr, modlist) {
Harald Hoyer b38677
+                                        mod = kmod_module_get_module(itr);
Harald Hoyer b38677
+                                        ret = install_module(mod);
Harald Hoyer b38677
+                                        kmod_module_unref(mod);
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                kmod_module_unref_list(modlist);
Harald Hoyer b38677
+                                modlist = 0;
Harald Hoyer b38677
+#else
Harald Hoyer b38677
+                                ret = install_module(mod_o);
Harald Hoyer b38677
+                                kmod_module_unref(mod_o);
Harald Hoyer b38677
+#endif
Harald Hoyer b38677
+
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        if (errno) {
Harald Hoyer b38677
+                                log_error("FTS ERROR: %m");
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        fts_close(fts);
Harald Hoyer b38677
+                        free(path1); path1 = NULL;
Harald Hoyer b38677
+                        free(path2); path2 = NULL;
Harald Hoyer b38677
+                        free(path3); path3 = NULL;
Harald Hoyer b38677
+                } else {
Harald Hoyer b38677
+                        char *modname = argv[i];
Harald Hoyer b38677
+                        if (endswith(modname, ".ko")) {
Harald Hoyer b38677
+                                int len = strlen(modname);
Harald Hoyer b38677
+                                modname[len-3]=0;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        if (endswith(modname, ".ko.xz") || endswith(modname, ".ko.gz")) {
Harald Hoyer b38677
+                                int len = strlen(modname);
Harald Hoyer b38677
+                                modname[len-6]=0;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        r = kmod_module_new_from_lookup(ctx, modname, &modlist);
Harald Hoyer b38677
+                        if (r < 0) {
Harald Hoyer b38677
+                                if (!arg_optional) {
Harald Hoyer b38677
+                                        if (!arg_silent)
Harald Hoyer b38677
+                                                log_error("Failed to lookup alias '%s': %m", modname);
Harald Hoyer b38677
+                                        return -ENOENT;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                log_info("Failed to lookup alias '%s': %m", modname);
Harald Hoyer b38677
+                                continue;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        if (!modlist) {
Harald Hoyer b38677
+                                if (!arg_optional) {
Harald Hoyer b38677
+                                        if (!arg_silent)
Harald Hoyer b38677
+                                                log_error("Failed to find module '%s'", modname);
Harald Hoyer b38677
+                                        return -ENOENT;
Harald Hoyer b38677
+                                }
Harald Hoyer b38677
+                                log_info("Failed to find module '%s'", modname);
Harald Hoyer b38677
+                                continue;
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        kmod_list_foreach(itr, modlist) {
Harald Hoyer b38677
+                                mod = kmod_module_get_module(itr);
Harald Hoyer b38677
+                                ret = install_module(mod);
Harald Hoyer b38677
+                                kmod_module_unref(mod);
Harald Hoyer b38677
+                        }
Harald Hoyer b38677
+                        kmod_module_unref_list(modlist);
Harald Hoyer b38677
+                        modlist = 0;
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+
Harald Hoyer b38677
+                if ((ret != 0) && (!arg_optional)) {
Harald Hoyer b38677
+                        if (!arg_silent)
Harald Hoyer b38677
+                                log_error("ERROR: installing '%s'", argv[i]);
Harald Hoyer b38677
+                        return EXIT_FAILURE;
Harald Hoyer b38677
+                }
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+        return EXIT_SUCCESS;
Harald Hoyer b38677
+}
Harald Hoyer b38677
+
Harald Hoyer b38677
 int main(int argc, char **argv)
Harald Hoyer b38677
 {
Harald Hoyer b38677
         int r;
Harald Hoyer b38677
         char *i;
Harald Hoyer b38677
+        char *path = NULL;
Harald Hoyer b38677
 
Harald Hoyer b38677
         r = parse_argv(argc, argv);
Harald Hoyer b38677
         if (r <= 0)
Harald Hoyer b38677
@@ -993,6 +1447,17 @@ int main(int argc, char **argv)
Harald Hoyer b38677
 
Harald Hoyer b38677
         log_open();
Harald Hoyer b38677
 
Harald Hoyer b38677
+        path = getenv("PATH");
Harald Hoyer b38677
+
Harald Hoyer b38677
+        if (path == NULL) {
Harald Hoyer b38677
+                log_error("PATH is not set");
Harald Hoyer b38677
+                exit(EXIT_FAILURE);
Harald Hoyer b38677
+        }
Harald Hoyer b38677
+
Harald Hoyer b38677
+        log_debug("PATH=%s", path);
Harald Hoyer b38677
+
Harald Hoyer b38677
+        pathdirs = strv_split(path, ":");
Harald Hoyer b38677
+
Harald Hoyer b38677
         umask(0022);
Harald Hoyer b38677
 
Harald Hoyer b38677
         if (destrootdir == NULL || strlen(destrootdir) == 0) {
Harald Hoyer b38677
@@ -1059,7 +1524,9 @@ int main(int argc, char **argv)
Harald Hoyer b38677
                 }
Harald Hoyer b38677
         }
Harald Hoyer b38677
 
Harald Hoyer b38677
-        if (arg_resolvelazy) {
Harald Hoyer b38677
+        if (arg_module) {
Harald Hoyer b38677
+                r = install_modules(argc - optind, &argv[optind]);
Harald Hoyer b38677
+        } else if (arg_resolvelazy) {
Harald Hoyer b38677
                 r = resolve_lazy(argc - optind, &argv[optind]);
Harald Hoyer b38677
         } else if (arg_all || (argc - optind > 2) || ((argc - optind) == 1)) {
Harald Hoyer b38677
                 r = install_all(argc - optind, &argv[optind]);
Harald Hoyer b38677
@@ -1085,6 +1552,7 @@ int main(int argc, char **argv)
Harald Hoyer b38677
         hashmap_free(items_failed);
Harald Hoyer b38677
 
Harald Hoyer b38677
         free(destrootdir);
Harald Hoyer b38677
-
Harald Hoyer b38677
+        strv_free(firmwaredirs);
Harald Hoyer b38677
+        strv_free(pathdirs);
Harald Hoyer b38677
         return r;
Harald Hoyer b38677
 }
Harald Hoyer b38677
diff --git a/modules.d/50drm/module-setup.sh b/modules.d/50drm/module-setup.sh
Harald Hoyer b38677
index 55a214e..e0b2959 100755
Harald Hoyer b38677
--- a/modules.d/50drm/module-setup.sh
Harald Hoyer b38677
+++ b/modules.d/50drm/module-setup.sh
Harald Hoyer b38677
@@ -15,40 +15,6 @@ installkernel() {
Harald Hoyer b38677
     local _modname
Harald Hoyer b38677
     # Include KMS capable drm drivers
Harald Hoyer b38677
 
Harald Hoyer b38677
-    drm_module_filter() {
Harald Hoyer b38677
-        local _drm_drivers='drm_crtc_init'
Harald Hoyer b38677
-        local _ret
Harald Hoyer b38677
-        # subfunctions inherit following FDs
Harald Hoyer b38677
-        local _merge=8 _side2=9
Harald Hoyer b38677
-        function nmf1() {
Harald Hoyer b38677
-            local _fname _fcont
Harald Hoyer b38677
-            while read _fname || [ -n "$_fname" ]; do
Harald Hoyer b38677
-                case "$_fname" in
Harald Hoyer b38677
-                    *.ko)    _fcont="$(<        $_fname)" ;;
Harald Hoyer b38677
-                    *.ko.gz) _fcont="$(gzip -dc $_fname)" ;;
Harald Hoyer b38677
-                    *.ko.xz) _fcont="$(xz -dc   $_fname)" ;;
Harald Hoyer b38677
-                esac
Harald Hoyer b38677
-                [[   $_fcont =~ $_drm_drivers
Harald Hoyer b38677
-                && ! $_fcont =~ iw_handler_get_spy ]] \
Harald Hoyer b38677
-                && echo "$_fname"
Harald Hoyer b38677
-            done
Harald Hoyer b38677
-        }
Harald Hoyer b38677
-        function rotor() {
Harald Hoyer b38677
-            local _f1 _f2
Harald Hoyer b38677
-            while read _f1 || [ -n "$_f1" ]; do
Harald Hoyer b38677
-                echo "$_f1"
Harald Hoyer b38677
-                if read _f2; then
Harald Hoyer b38677
-                    echo "$_f2" 1>&${_side2}
Harald Hoyer b38677
-                fi
Harald Hoyer b38677
-            done | nmf1 1>&${_merge}
Harald Hoyer b38677
-        }
Harald Hoyer b38677
-        # Use two parallel streams to filter alternating modules.
Harald Hoyer b38677
-        set +x
Harald Hoyer b38677
-        eval "( ( rotor ) ${_side2}>&1 | nmf1 ) ${_merge}>&1"
Harald Hoyer b38677
-        [[ $debug ]] && set -x
Harald Hoyer b38677
-        return 0
Harald Hoyer b38677
-    }
Harald Hoyer b38677
-
Harald Hoyer b38677
     if [[ "$(uname -p)" == arm* ]]; then
Harald Hoyer b38677
         # arm specific modules needed by drm
Harald Hoyer b38677
         instmods \
Harald Hoyer b38677
@@ -62,20 +28,19 @@ installkernel() {
Harald Hoyer b38677
 
Harald Hoyer b38677
     instmods amdkfd hyperv_fb
Harald Hoyer b38677
 
Harald Hoyer b38677
-    for _modname in $(find_kernel_modules_by_path drivers/gpu/drm \
Harald Hoyer b38677
-        | drm_module_filter) ; do
Harald Hoyer b38677
-        # if the hardware is present, include module even if it is not currently loaded,
Harald Hoyer b38677
-        # as we could e.g. be in the installer; nokmsboot boot parameter will disable
Harald Hoyer b38677
-        # loading of the driver if needed
Harald Hoyer b38677
-        if [[ $hostonly ]] && modinfo -F alias $_modname | sed -e 's,\?,\.,g' -e 's,\*,\.\*,g' \
Harald Hoyer b38677
-            | grep -qxf - /sys/bus/{pci/devices,soc/devices/soc?}/*/modalias 2>/dev/null; then
Harald Hoyer b38677
-            hostonly='' instmods $_modname
Harald Hoyer b38677
-            # if radeon.ko is installed, we want amdkfd also
Harald Hoyer b38677
-            if strstr "$_modname" radeon.ko; then
Harald Hoyer b38677
-                hostonly='' instmods amdkfd
Harald Hoyer b38677
+    # if the hardware is present, include module even if it is not currently loaded,
Harald Hoyer b38677
+    # as we could e.g. be in the installer; nokmsboot boot parameter will disable
Harald Hoyer b38677
+    # loading of the driver if needed
Harald Hoyer b38677
+    if [[ $hostonly ]]; then
Harald Hoyer b38677
+        for i in /sys/bus/{pci/devices,soc/devices/soc?}/*/modalias; do
Harald Hoyer b38677
+            [[ -e $i ]] || continue
Harald Hoyer b38677
+            if hostonly="" dracut_instmods -s "drm_crtc_init" $(<$i) 2>/dev/null; then
Harald Hoyer b38677
+                if strstr $(modinfo -F filename $(<$i) 2>/dev/null) radeon.ko; then
Harald Hoyer b38677
+                    hostonly='' instmods amdkfd
Harald Hoyer b38677
+                fi
Harald Hoyer b38677
             fi
Harald Hoyer b38677
-            continue
Harald Hoyer b38677
-        fi
Harald Hoyer b38677
-        instmods $_modname
Harald Hoyer b38677
-    done
Harald Hoyer b38677
+        done
Harald Hoyer b38677
+    else
Harald Hoyer b38677
+        dracut_instmods -s "drm_crtc_init" "=drivers/gpu/drm"
Harald Hoyer b38677
+    fi
Harald Hoyer b38677
 }
Harald Hoyer b38677
diff --git a/modules.d/90crypt/module-setup.sh b/modules.d/90crypt/module-setup.sh
Harald Hoyer b38677
index 5d964f4..6c377ef 100755
Harald Hoyer b38677
--- a/modules.d/90crypt/module-setup.sh
Harald Hoyer b38677
+++ b/modules.d/90crypt/module-setup.sh
Harald Hoyer b38677
@@ -24,8 +24,10 @@ depends() {
Harald Hoyer b38677
 
Harald Hoyer b38677
 # called by dracut
Harald Hoyer b38677
 installkernel() {
Harald Hoyer b38677
-    instmods dm_crypt =crypto
Harald Hoyer b38677
     hostonly="" instmods drbg
Harald Hoyer b38677
+    arch=$(arch)
Harald Hoyer b38677
+    [[ $arch == x86_64 ]] && arch=x86
Harald Hoyer b38677
+    instmods dm_crypt =crypto =drivers/crypto =arch/$arch/crypto
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
 # called by dracut
Harald Hoyer b38677
diff --git a/modules.d/90dm/module-setup.sh b/modules.d/90dm/module-setup.sh
Harald Hoyer b38677
index 419e8b1..2b8e39f 100755
Harald Hoyer b38677
--- a/modules.d/90dm/module-setup.sh
Harald Hoyer b38677
+++ b/modules.d/90dm/module-setup.sh
Harald Hoyer b38677
@@ -13,8 +13,7 @@ depends() {
Harald Hoyer b38677
 
Harald Hoyer b38677
 # called by dracut
Harald Hoyer b38677
 installkernel() {
Harald Hoyer b38677
-    instmods =drivers/md
Harald Hoyer b38677
-    instmods dm_mod dm-cache dm-cache-mq dm-cache-cleaner
Harald Hoyer b38677
+    instmods =drivers/md dm_mod dm-cache dm-cache-mq dm-cache-cleaner
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
 # called by dracut
Harald Hoyer b38677
diff --git a/modules.d/90kernel-modules/module-setup.sh b/modules.d/90kernel-modules/module-setup.sh
Harald Hoyer b38677
index 300adc7..e97d598 100755
Harald Hoyer b38677
--- a/modules.d/90kernel-modules/module-setup.sh
Harald Hoyer b38677
+++ b/modules.d/90kernel-modules/module-setup.sh
Harald Hoyer b38677
@@ -2,54 +2,25 @@
Harald Hoyer b38677
 
Harald Hoyer b38677
 # called by dracut
Harald Hoyer b38677
 installkernel() {
Harald Hoyer b38677
-    if [[ -z $drivers ]]; then
Harald Hoyer b38677
-        block_module_filter() {
Harald Hoyer b38677
-            local _blockfuncs='ahci_platform_get_resources|ata_scsi_ioctl|scsi_add_host|blk_cleanup_queue|register_mtd_blktrans|scsi_esp_register|register_virtio_device|usb_stor_disconnect|mmc_add_host|sdhci_add_host'
Harald Hoyer b38677
-            # subfunctions inherit following FDs
Harald Hoyer b38677
-            local _merge=8 _side2=9
Harald Hoyer b38677
-            function bmf1() {
Harald Hoyer b38677
-                local _f
Harald Hoyer b38677
-                while read _f || [ -n "$_f" ]; do case "$_f" in
Harald Hoyer b38677
-                    *.ko)    [[ $(<         $_f) =~ $_blockfuncs ]] && echo "$_f" ;;
Harald Hoyer b38677
-                    *.ko.gz) [[ $(gzip -dc <$_f) =~ $_blockfuncs ]] && echo "$_f" ;;
Harald Hoyer b38677
-                    *.ko.xz) [[ $(xz -dc   <$_f) =~ $_blockfuncs ]] && echo "$_f" ;;
Harald Hoyer b38677
-                    esac
Harald Hoyer b38677
-                done
Harald Hoyer b38677
-                return 0
Harald Hoyer b38677
-            }
Harald Hoyer b38677
-            function rotor() {
Harald Hoyer b38677
-                local _f1 _f2
Harald Hoyer b38677
-                while read _f1 || [ -n "$_f1" ]; do
Harald Hoyer b38677
-                    echo "$_f1"
Harald Hoyer b38677
-                    if read _f2; then
Harald Hoyer b38677
-                        echo "$_f2" 1>&${_side2}
Harald Hoyer b38677
-                    fi
Harald Hoyer b38677
-                done | bmf1 1>&${_merge}
Harald Hoyer b38677
-                return 0
Harald Hoyer b38677
-            }
Harald Hoyer b38677
-            # Use two parallel streams to filter alternating modules.
Harald Hoyer b38677
-            set +x
Harald Hoyer b38677
-            eval "( ( rotor ) ${_side2}>&1 | bmf1 ) ${_merge}>&1"
Harald Hoyer b38677
-            [[ $debug ]] && set -x
Harald Hoyer b38677
-            return 0
Harald Hoyer b38677
-        }
Harald Hoyer b38677
+    local _blockfuncs='ahci_platform_get_resources|ata_scsi_ioctl|scsi_add_host|blk_cleanup_queue|register_mtd_blktrans|scsi_esp_register|register_virtio_device|usb_stor_disconnect|mmc_add_host|sdhci_add_host|scsi_add_host_with_dma'
Harald Hoyer b38677
 
Harald Hoyer b38677
+    if [[ -z $drivers ]]; then
Harald Hoyer b38677
         hostonly='' instmods \
Harald Hoyer b38677
             sr_mod sd_mod scsi_dh ata_piix hid_generic unix \
Harald Hoyer b38677
-            ehci-hcd ehci-pci ehci-platform \
Harald Hoyer b38677
+            ehci-hcd ehci-pci \
Harald Hoyer b38677
             ohci-hcd ohci-pci \
Harald Hoyer b38677
             uhci-hcd \
Harald Hoyer b38677
             xhci-hcd xhci-pci xhci-plat-hcd \
Harald Hoyer b38677
+            ehci-platform
Harald Hoyer b38677
+
Harald Hoyer b38677
+        instmods \
Harald Hoyer b38677
             "=drivers/hid" \
Harald Hoyer b38677
             "=drivers/input/serio" \
Harald Hoyer b38677
             "=drivers/input/keyboard" \
Harald Hoyer b38677
-            "=drivers/usb/storage"
Harald Hoyer b38677
-
Harald Hoyer b38677
-        instmods \
Harald Hoyer b38677
             yenta_socket scsi_dh_rdac scsi_dh_emc scsi_dh_alua \
Harald Hoyer b38677
             atkbd i8042 usbhid firewire-ohci pcmcia hv-vmbus \
Harald Hoyer b38677
             virtio virtio_blk virtio_ring virtio_pci virtio_scsi \
Harald Hoyer b38677
-            "=drivers/pcmcia" =ide
Harald Hoyer b38677
+            "=drivers/pcmcia" =ide "=drivers/usb/storage"
Harald Hoyer b38677
 
Harald Hoyer b38677
         if [[ "$(uname -p)" == arm* ]]; then
Harald Hoyer b38677
             # arm specific modules
Harald Hoyer b38677
@@ -62,20 +33,16 @@ installkernel() {
Harald Hoyer b38677
                 ${NULL}
Harald Hoyer b38677
         fi
Harald Hoyer b38677
 
Harald Hoyer b38677
-
Harald Hoyer b38677
-        find_kernel_modules  |  block_module_filter  |  instmods
Harald Hoyer b38677
+        dracut_instmods -s "${_blockfuncs}" "=drivers"
Harald Hoyer b38677
 
Harald Hoyer b38677
         # if not on hostonly mode, install all known filesystems,
Harald Hoyer b38677
         # if the required list is not set via the filesystems variable
Harald Hoyer b38677
         if ! [[ $hostonly ]]; then
Harald Hoyer b38677
             if [[ -z $filesystems ]]; then
Harald Hoyer b38677
-                silent_omit_drivers="kernel/fs/nfs|kernel/fs/nfsd|kernel/fs/lockd" \
Harald Hoyer b38677
-                    instmods '=fs'
Harald Hoyer b38677
+                dracut_instmods -P ".*/(kernel/fs/nfs|kernel/fs/nfsd|kernel/fs/lockd)/.*" '=fs'
Harald Hoyer b38677
             fi
Harald Hoyer b38677
         else
Harald Hoyer b38677
-            for i in "${host_fs_types[@]}"; do
Harald Hoyer b38677
-                hostonly='' instmods $i
Harald Hoyer b38677
-            done
Harald Hoyer b38677
+            hostonly='' instmods "${host_fs_types[@]}"
Harald Hoyer b38677
         fi
Harald Hoyer b38677
     fi
Harald Hoyer b38677
     :
Harald Hoyer b38677
diff --git a/modules.d/90kernel-network-modules/module-setup.sh b/modules.d/90kernel-network-modules/module-setup.sh
Harald Hoyer b38677
index 18d7d96..c004ff8 100755
Harald Hoyer b38677
--- a/modules.d/90kernel-network-modules/module-setup.sh
Harald Hoyer b38677
+++ b/modules.d/90kernel-network-modules/module-setup.sh
Harald Hoyer b38677
@@ -14,47 +14,14 @@ depends() {
Harald Hoyer b38677
 installkernel() {
Harald Hoyer b38677
     # Include wired net drivers, excluding wireless
Harald Hoyer b38677
     local _arch=$(uname -m)
Harald Hoyer b38677
+    local _net_drivers='eth_type_trans|register_virtio_device|usbnet_open'
Harald Hoyer b38677
+    local _unwanted_drivers='/(wireless|isdn|uwb|net/ethernet|net/phy|net/team)/'
Harald Hoyer b38677
 
Harald Hoyer b38677
-    net_module_filter() {
Harald Hoyer b38677
-        local _net_drivers='eth_type_trans|register_virtio_device|usbnet_open'
Harald Hoyer b38677
-        local _unwanted_drivers='/(wireless|isdn|uwb|net/ethernet|net/phy|net/team)/'
Harald Hoyer b38677
-        local _ret
Harald Hoyer b38677
-        # subfunctions inherit following FDs
Harald Hoyer b38677
-        local _merge=8 _side2=9
Harald Hoyer b38677
-        function nmf1() {
Harald Hoyer b38677
-            local _fname _fcont
Harald Hoyer b38677
-            while read _fname; do
Harald Hoyer b38677
-                [[ $_fname =~ $_unwanted_drivers ]] && continue
Harald Hoyer b38677
-                case "$_fname" in
Harald Hoyer b38677
-                    *.ko)    _fcont="$(<        $_fname)" ;;
Harald Hoyer b38677
-                    *.ko.gz) _fcont="$(gzip -dc $_fname)" ;;
Harald Hoyer b38677
-                    *.ko.xz) _fcont="$(xz -dc   $_fname)" ;;
Harald Hoyer b38677
-                esac
Harald Hoyer b38677
-                [[   $_fcont =~ $_net_drivers
Harald Hoyer b38677
-                && ! $_fcont =~ iw_handler_get_spy ]] \
Harald Hoyer b38677
-                && echo "$_fname"
Harald Hoyer b38677
-            done
Harald Hoyer b38677
-            return 0
Harald Hoyer b38677
-        }
Harald Hoyer b38677
-        function rotor() {
Harald Hoyer b38677
-            local _f1 _f2
Harald Hoyer b38677
-            while read _f1; do
Harald Hoyer b38677
-                echo "$_f1"
Harald Hoyer b38677
-                if read _f2; then
Harald Hoyer b38677
-                    echo "$_f2" 1>&${_side2}
Harald Hoyer b38677
-                fi
Harald Hoyer b38677
-            done | nmf1 1>&${_merge}
Harald Hoyer b38677
-            return 0
Harald Hoyer b38677
-        }
Harald Hoyer b38677
-        # Use two parallel streams to filter alternating modules.
Harald Hoyer b38677
-        set +x
Harald Hoyer b38677
-        eval "( ( rotor ) ${_side2}>&1 | nmf1 ) ${_merge}>&1"
Harald Hoyer b38677
-        [[ $debug ]] && set -x
Harald Hoyer b38677
-        return 0
Harald Hoyer b38677
-    }
Harald Hoyer b38677
+    if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then
Harald Hoyer b38677
+        _s390drivers="=drivers/s390/net"
Harald Hoyer b38677
+    fi
Harald Hoyer b38677
 
Harald Hoyer b38677
-    { find_kernel_modules_by_path drivers/net; if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then find_kernel_modules_by_path drivers/s390/net; fi; } \
Harald Hoyer b38677
-        | net_module_filter | instmods
Harald Hoyer b38677
+    dracut_instmods -P ".*${_unwanted_drivers}.*" -s "$_net_drivers" "=drivers/net" ${_s390drivers:+"$_s390drivers"}
Harald Hoyer b38677
 
Harald Hoyer b38677
     #instmods() will take care of hostonly
Harald Hoyer b38677
     instmods \
Harald Hoyer b38677
diff --git a/modules.d/90multipath/module-setup.sh b/modules.d/90multipath/module-setup.sh
Harald Hoyer b38677
index a808678..27817bd 100755
Harald Hoyer b38677
--- a/modules.d/90multipath/module-setup.sh
Harald Hoyer b38677
+++ b/modules.d/90multipath/module-setup.sh
Harald Hoyer b38677
@@ -51,41 +51,14 @@ cmdline() {
Harald Hoyer b38677
 installkernel() {
Harald Hoyer b38677
     local _ret
Harald Hoyer b38677
     local _arch=$(uname -m)
Harald Hoyer b38677
-    mp_mod_filter() {
Harald Hoyer b38677
-        local _funcs='scsi_register_device_handler|dm_dirty_log_type_register|dm_register_path_selector|dm_register_target'
Harald Hoyer b38677
-        # subfunctions inherit following FDs
Harald Hoyer b38677
-        local _merge=8 _side2=9
Harald Hoyer b38677
-        function bmf1() {
Harald Hoyer b38677
-            local _f
Harald Hoyer b38677
-            while read _f || [ -n "$_f" ]; do
Harald Hoyer b38677
-                case "$_f" in
Harald Hoyer b38677
-                    *.ko)    [[ $(<         $_f) =~ $_funcs ]] && echo "$_f" ;;
Harald Hoyer b38677
-                    *.ko.gz) [[ $(gzip -dc <$_f) =~ $_funcs ]] && echo "$_f" ;;
Harald Hoyer b38677
-                    *.ko.xz) [[ $(xz -dc   <$_f) =~ $_funcs ]] && echo "$_f" ;;
Harald Hoyer b38677
-                esac
Harald Hoyer b38677
-            done
Harald Hoyer b38677
-            return 0
Harald Hoyer b38677
-        }
Harald Hoyer b38677
+    local _funcs='scsi_register_device_handler|dm_dirty_log_type_register|dm_register_path_selector|dm_register_target'
Harald Hoyer b38677
+    local _s390
Harald Hoyer b38677
 
Harald Hoyer b38677
-        function rotor() {
Harald Hoyer b38677
-            local _f1 _f2
Harald Hoyer b38677
-            while read _f1 || [ -n "$_f1" ]; do
Harald Hoyer b38677
-                echo "$_f1"
Harald Hoyer b38677
-                if read _f2; then
Harald Hoyer b38677
-                    echo "$_f2" 1>&${_side2}
Harald Hoyer b38677
-                fi
Harald Hoyer b38677
-            done | bmf1 1>&${_merge}
Harald Hoyer b38677
-            return 0
Harald Hoyer b38677
-        }
Harald Hoyer b38677
-        # Use two parallel streams to filter alternating modules.
Harald Hoyer b38677
-        set +x
Harald Hoyer b38677
-        eval "( ( rotor ) ${_side2}>&1 | bmf1 ) ${_merge}>&1"
Harald Hoyer b38677
-        [[ $debug ]] && set -x
Harald Hoyer b38677
-        return 0
Harald Hoyer b38677
-    }
Harald Hoyer b38677
+    if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then
Harald Hoyer b38677
+        _s390drivers="=drivers/s390/scsi"
Harald Hoyer b38677
+    fi
Harald Hoyer b38677
 
Harald Hoyer b38677
-    ( find_kernel_modules_by_path drivers/scsi; if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then find_kernel_modules_by_path drivers/s390/scsi; fi;
Harald Hoyer b38677
-      find_kernel_modules_by_path drivers/md )  |  mp_mod_filter  |  hostonly='' instmods
Harald Hoyer b38677
+    hostonly='' dracut_instmods -s "$_funcs" "=drivers/scsi" "=drivers/md" ${_s390drivers:+"$_s390drivers"}
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
 # called by dracut
Harald Hoyer b38677
diff --git a/modules.d/95iscsi/module-setup.sh b/modules.d/95iscsi/module-setup.sh
Harald Hoyer b38677
index beb80e3..203e313 100755
Harald Hoyer b38677
--- a/modules.d/95iscsi/module-setup.sh
Harald Hoyer b38677
+++ b/modules.d/95iscsi/module-setup.sh
Harald Hoyer b38677
@@ -157,44 +157,17 @@ depends() {
Harald Hoyer b38677
 # called by dracut
Harald Hoyer b38677
 installkernel() {
Harald Hoyer b38677
     local _arch=$(uname -m)
Harald Hoyer b38677
+    local _funcs='iscsi_register_transport'
Harald Hoyer b38677
 
Harald Hoyer b38677
     instmods bnx2i qla4xxx cxgb3i cxgb4i be2iscsi
Harald Hoyer b38677
     hostonly="" instmods iscsi_tcp iscsi_ibft crc32c iscsi_boot_sysfs
Harald Hoyer b38677
-    iscsi_module_filter() {
Harald Hoyer b38677
-        local _funcs='iscsi_register_transport'
Harald Hoyer b38677
-        # subfunctions inherit following FDs
Harald Hoyer b38677
-        local _merge=8 _side2=9
Harald Hoyer b38677
-        function bmf1() {
Harald Hoyer b38677
-            local _f
Harald Hoyer b38677
-            while read _f || [ -n "$_f" ]; do
Harald Hoyer b38677
-                case "$_f" in
Harald Hoyer b38677
-                    *.ko)    [[ $(<         $_f) =~ $_funcs ]] && echo "$_f" ;;
Harald Hoyer b38677
-                    *.ko.gz) [[ $(gzip -dc <$_f) =~ $_funcs ]] && echo "$_f" ;;
Harald Hoyer b38677
-                    *.ko.xz) [[ $(xz -dc   <$_f) =~ $_funcs ]] && echo "$_f" ;;
Harald Hoyer b38677
-                esac
Harald Hoyer b38677
-            done
Harald Hoyer b38677
-            return 0
Harald Hoyer b38677
-        }
Harald Hoyer b38677
-
Harald Hoyer b38677
-        function rotor() {
Harald Hoyer b38677
-            local _f1 _f2
Harald Hoyer b38677
-            while read _f1 || [ -n "$_f1" ]; do
Harald Hoyer b38677
-                echo "$_f1"
Harald Hoyer b38677
-                if read _f2; then
Harald Hoyer b38677
-                    echo "$_f2" 1>&${_side2}
Harald Hoyer b38677
-                fi
Harald Hoyer b38677
-            done | bmf1 1>&${_merge}
Harald Hoyer b38677
-            return 0
Harald Hoyer b38677
-        }
Harald Hoyer b38677
-        # Use two parallel streams to filter alternating modules.
Harald Hoyer b38677
-        set +x
Harald Hoyer b38677
-        eval "( ( rotor ) ${_side2}>&1 | bmf1 ) ${_merge}>&1"
Harald Hoyer b38677
-        [[ $debug ]] && set -x
Harald Hoyer b38677
-        return 0
Harald Hoyer b38677
-    }
Harald Hoyer b38677
 
Harald Hoyer b38677
-    { find_kernel_modules_by_path drivers/scsi; if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then find_kernel_modules_by_path drivers/s390/scsi; fi;} \
Harald Hoyer b38677
-    | iscsi_module_filter  |  instmods
Harald Hoyer b38677
+    if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then
Harald Hoyer b38677
+        _s390drivers="=drivers/s390/scsi"
Harald Hoyer b38677
+    fi
Harald Hoyer b38677
+
Harald Hoyer b38677
+    dracut_instmods -s "$_funcs" "=drivers/scsi" ${_s390drivers:+"$_s390drivers"}
Harald Hoyer b38677
+
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
 # called by dracut
Harald Hoyer b38677
diff --git a/modules.d/95nfs/module-setup.sh b/modules.d/95nfs/module-setup.sh
Harald Hoyer b38677
index 6f039bd..9767e57 100755
Harald Hoyer b38677
--- a/modules.d/95nfs/module-setup.sh
Harald Hoyer b38677
+++ b/modules.d/95nfs/module-setup.sh
Harald Hoyer b38677
@@ -25,7 +25,7 @@ depends() {
Harald Hoyer b38677
 
Harald Hoyer b38677
 # called by dracut
Harald Hoyer b38677
 installkernel() {
Harald Hoyer b38677
-    instmods nfs sunrpc ipv6 nfsv2 nfsv3 nfsv4 nfs_acl nfs_layout_nfsv41_files
Harald Hoyer b38677
+    instmods =net/sunrpc =fs/nfs ipv6 nfs_acl nfs_layout_nfsv41_files
Harald Hoyer b38677
 }
Harald Hoyer b38677
 
Harald Hoyer b38677
 cmdline() {