From d8aeb3a72afe03e426f4ea9f07c857c9a499144f Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 27 Jun 2012 09:35:39 +0200 Subject: [PATCH] dracut.sh, dracut-functions.sh: do lazy kernel module dep resolving 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 | 90 ++++++++++++++++++++++++++++++--------------- dracut.sh | 5 ++- 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/dracut-functions.sh b/dracut-functions.sh index cecd59a4..fd133b83 100755 --- a/dracut-functions.sh +++ b/dracut-functions.sh @@ -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}/" + 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+=$?)) + # 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 diff --git a/dracut.sh b/dracut.sh index 0fb0a18b..c56f17ba 100755 --- 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