]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
dracut.sh, dracut-functions.sh: do lazy kernel module dep resolving
authorHarald Hoyer <harald@redhat.com>
Wed, 27 Jun 2012 07:35:39 +0000 (09:35 +0200)
committerHarald Hoyer <harald@redhat.com>
Fri, 29 Jun 2012 10:41:27 +0000 (12:41 +0200)
First, we just install the kernel module and keep track, what we
installed. At the very end, call modprobe and modinfo for firmwares to
resolve all kernel module dependencies. This speeds up image creation,
because we can call modprobe and modinfo with many modules.

dracut-functions.sh
dracut.sh

index cecd59a4a98293013cb176c2c9306096c43dd6f7..fd133b8318ab69d431c5c6cd47e667df2de20c4e 100755 (executable)
@@ -1050,7 +1050,10 @@ install_kmod_with_fw() {
     [[ -e "${initdir}/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" ]] \
         && return 0
 
-    [[ -e "$initdir/.kernelmodseen/${1##*/}" ]] && return 0
+    if [[ -e "$initdir/.kernelmodseen/${1##*/}" ]]; then
+        read ret < "$initdir/.kernelmodseen/${1##*/}"
+        return $ret
+    fi
 
     if [[ $omit_drivers ]]; then
         local _kmod=${1##*/}
@@ -1066,11 +1069,11 @@ install_kmod_with_fw() {
         fi
     fi
 
+    inst_simple "$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}"
+    ret=$?
     [ -d "$initdir/.kernelmodseen" ] && \
-        > "$initdir/.kernelmodseen/${1##*/}"
-
-    inst_simple "$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" \
-        || return $?
+        echo $ret > "$initdir/.kernelmodseen/${1##*/}"
+    (($ret != 0)) && return $ret
 
     local _modname=${1##*/} _fwdir _found _fw
     _modname=${_modname%.ko*}
@@ -1113,6 +1116,35 @@ for_each_kmod_dep() {
     )
 }
 
+do_lazy_kmod_dep() {
+    local _moddirname=${srcmods%%/lib/modules/*}
+
+    [[ -f "$initdir/.kernelmodseen/lazylist" ]] || return 0
+
+    [[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/"
+
+    xargs modprobe -a $_moddirname --ignore-install --show-depends \
+        < "$initdir/.kernelmodseen/lazylist" 2>/dev/null \
+        | sort -u \
+        | while read _cmd _modpath _options; do
+        [[ $_cmd = insmod ]] || continue
+        echo "$_modpath"
+    done > "$initdir/.kernelmodseen/lazylist.dep"
+
+    ( while read _modpath; do
+        inst_simple "$_modpath" "/lib/modules/$kernel/${_modpath##*/lib/modules/$kernel/}" || exit $?
+    done < "$initdir/.kernelmodseen/lazylist.dep" ) &
+
+    for _fw in $(xargs modinfo -k $kernel -F firmware < "$initdir/.kernelmodseen/lazylist.dep"); do
+        for _fwdir in $fw_dir; do
+            if [[ -d $_fwdir && -f $_fwdir/$_fw ]]; then
+                inst_simple "$_fwdir/$_fw" "/lib/firmware/$_fw"
+                break
+            fi
+        done
+    done
+    wait
+}
 
 find_kernel_modules_by_path () (
     local _OLDIFS
@@ -1120,9 +1152,7 @@ find_kernel_modules_by_path () (
         _OLDIFS=$IFS
         IFS=:
         while read a rest; do
-            if [[ "${a##kernel}" != "$a" ]]; then
-                [[ "${a##kernel/$1}" != "$a" ]] || continue
-            fi
+            [[ $a = kernel*/$1/* ]] || continue
             echo $srcmods/$a
         done < $srcmods/modules.dep
         IFS=$_OLDIFS
@@ -1155,17 +1185,10 @@ instmods() {
         local _ret=0 _mod="$1"
         case $_mod in
             =*)
-                if [ -f $srcmods/modules.${_mod#=} ]; then
-                    ( [[ "$_mpargs" ]] && echo $_mpargs
-                      cat "${srcmods}/modules.${_mod#=}" ) \
-                    | instmods
-                    ((_ret+=$?))
-                else
-                    ( [[ "$_mpargs" ]] && echo $_mpargs
-                      find "$srcmods" -type f -path "*/${_mod#=}/*" -printf '%f\n' ) \
-                    | instmods
-                    ((_ret+=$?))
-                fi
+                ( [[ "$_mpargs" ]] && echo $_mpargs
+                    find_kernel_modules_by_path "${_mod#=}" ) \
+                        | instmods
+                ((_ret+=$?))
                 ;;
             --*) _mpargs+=" $_mod" ;;
             i2o_scsi) return 0;; # Do not load this diagnostic-only module
@@ -1173,7 +1196,10 @@ instmods() {
                 _mod=${_mod##*/}
                 # if we are already installed, skip this module and go on
                 # to the next one.
-                [[ -f "$initdir/.kernelmodseen/${_mod%.ko}.ko" ]] && return
+                if [[ -f "$initdir/.kernelmodseen/${_mod%.ko}.ko" ]]; then
+                    read _ret <"$initdir/.kernelmodseen/${_mod%.ko}.ko"
+                    return $_ret
+                fi
 
                 if [[ $omit_drivers ]] && [[ "$1" =~ $omit_drivers ]]; then
                     dinfo "Omitting driver ${_mod##$srcmods}"
@@ -1186,17 +1212,21 @@ instmods() {
                     && ! [[ "$add_drivers" =~ " ${_mod} " ]] \
                     && return 0
 
-                # We use '-d' option in modprobe only if modules prefix path
-                # differs from default '/'.  This allows us to use Dracut with
-                # old version of modprobe which doesn't have '-d' option.
-                local _moddirname=${srcmods%%/lib/modules/*}
-                [[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/"
-
-                # ok, load the module, all its dependencies, and any firmware
-                # it may require
-                for_each_kmod_dep install_kmod_with_fw $_mod \
-                    --set-version $kernel ${_moddirname} $_mpargs
-                ((_ret+=$?))
+                if [[ "$_check" = "yes" ]]; then
+                    # We use '-d' option in modprobe only if modules prefix path
+                    # differs from default '/'.  This allows us to use Dracut with
+                    # old version of modprobe which doesn't have '-d' option.
+                    local _moddirname=${srcmods%%/lib/modules/*}
+                    [[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/"
+
+                    # ok, load the module, all its dependencies, and any firmware
+                    # it may require
+                    for_each_kmod_dep install_kmod_with_fw $_mod \
+                        --set-version $kernel ${_moddirname} $_mpargs
+                    ((_ret+=$?))
+                else
+                    echo $_mod >> "$initdir/.kernelmodseen/lazylist"
+                fi
                 ;;
         esac
         return $_ret
index 0fb0a18b03f4625c18690233604cd1ceecf9abed..c56f17bae6ae3757fb0e692026f9f2ae6c5d71c7 100755 (executable)
--- a/dracut.sh
+++ b/dracut.sh
@@ -773,6 +773,10 @@ dinfo "*** Including modules done ***"
 
 ## final stuff that has to happen
 
+dinfo "*** Installing kernel module dependencies and firmware ***"
+do_lazy_kmod_dep
+dinfo "*** Installing kernel module dependencies and firmware done ***"
+
 # generate module dependencies for the initrd
 if [[ -d $initdir/lib/modules/$kernel ]] && \
     ! depmod -a -b "$initdir" $kernel; then
@@ -835,7 +839,6 @@ fi
 
 rm -fr "$initdir/.kernelmodseen"
 
-
 if (($maxloglvl >= 5)); then
     ddebug "Listing sizes of included files:"
     du -c "$initdir" | sort -n | ddebug