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.
master
Harald Hoyer 2012-06-27 09:35:39 +02:00
parent 2cf987f5c3
commit d8aeb3a72a
2 changed files with 64 additions and 31 deletions

View File

@ -1050,7 +1050,10 @@ install_kmod_with_fw() {
[[ -e "${initdir}/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" ]] \ [[ -e "${initdir}/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" ]] \
&& return 0 && 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 if [[ $omit_drivers ]]; then
local _kmod=${1##*/} local _kmod=${1##*/}
@ -1066,11 +1069,11 @@ install_kmod_with_fw() {
fi fi
fi fi


inst_simple "$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}"
ret=$?
[ -d "$initdir/.kernelmodseen" ] && \ [ -d "$initdir/.kernelmodseen" ] && \
> "$initdir/.kernelmodseen/${1##*/}" echo $ret > "$initdir/.kernelmodseen/${1##*/}"

(($ret != 0)) && return $ret
inst_simple "$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" \
|| return $?


local _modname=${1##*/} _fwdir _found _fw local _modname=${1##*/} _fwdir _found _fw
_modname=${_modname%.ko*} _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 () ( find_kernel_modules_by_path () (
local _OLDIFS local _OLDIFS
@ -1120,9 +1152,7 @@ find_kernel_modules_by_path () (
_OLDIFS=$IFS _OLDIFS=$IFS
IFS=: IFS=:
while read a rest; do while read a rest; do
if [[ "${a##kernel}" != "$a" ]]; then [[ $a = kernel*/$1/* ]] || continue
[[ "${a##kernel/$1}" != "$a" ]] || continue
fi
echo $srcmods/$a echo $srcmods/$a
done < $srcmods/modules.dep done < $srcmods/modules.dep
IFS=$_OLDIFS IFS=$_OLDIFS
@ -1155,17 +1185,10 @@ instmods() {
local _ret=0 _mod="$1" local _ret=0 _mod="$1"
case $_mod in case $_mod in
=*) =*)
if [ -f $srcmods/modules.${_mod#=} ]; then
( [[ "$_mpargs" ]] && echo $_mpargs ( [[ "$_mpargs" ]] && echo $_mpargs
cat "${srcmods}/modules.${_mod#=}" ) \ find_kernel_modules_by_path "${_mod#=}" ) \
| instmods | instmods
((_ret+=$?)) ((_ret+=$?))
else
( [[ "$_mpargs" ]] && echo $_mpargs
find "$srcmods" -type f -path "*/${_mod#=}/*" -printf '%f\n' ) \
| instmods
((_ret+=$?))
fi
;; ;;
--*) _mpargs+=" $_mod" ;; --*) _mpargs+=" $_mod" ;;
i2o_scsi) return 0;; # Do not load this diagnostic-only module i2o_scsi) return 0;; # Do not load this diagnostic-only module
@ -1173,7 +1196,10 @@ instmods() {
_mod=${_mod##*/} _mod=${_mod##*/}
# if we are already installed, skip this module and go on # if we are already installed, skip this module and go on
# to the next one. # 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 if [[ $omit_drivers ]] && [[ "$1" =~ $omit_drivers ]]; then
dinfo "Omitting driver ${_mod##$srcmods}" dinfo "Omitting driver ${_mod##$srcmods}"
@ -1186,6 +1212,7 @@ instmods() {
&& ! [[ "$add_drivers" =~ " ${_mod} " ]] \ && ! [[ "$add_drivers" =~ " ${_mod} " ]] \
&& return 0 && return 0


if [[ "$_check" = "yes" ]]; then
# We use '-d' option in modprobe only if modules prefix path # We use '-d' option in modprobe only if modules prefix path
# differs from default '/'. This allows us to use Dracut with # differs from default '/'. This allows us to use Dracut with
# old version of modprobe which doesn't have '-d' option. # old version of modprobe which doesn't have '-d' option.
@ -1197,6 +1224,9 @@ instmods() {
for_each_kmod_dep install_kmod_with_fw $_mod \ for_each_kmod_dep install_kmod_with_fw $_mod \
--set-version $kernel ${_moddirname} $_mpargs --set-version $kernel ${_moddirname} $_mpargs
((_ret+=$?)) ((_ret+=$?))
else
echo $_mod >> "$initdir/.kernelmodseen/lazylist"
fi
;; ;;
esac esac
return $_ret return $_ret

View File

@ -773,6 +773,10 @@ dinfo "*** Including modules done ***"


## final stuff that has to happen ## 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 # generate module dependencies for the initrd
if [[ -d $initdir/lib/modules/$kernel ]] && \ if [[ -d $initdir/lib/modules/$kernel ]] && \
! depmod -a -b "$initdir" $kernel; then ! depmod -a -b "$initdir" $kernel; then
@ -835,7 +839,6 @@ fi


rm -fr "$initdir/.kernelmodseen" rm -fr "$initdir/.kernelmodseen"



if (($maxloglvl >= 5)); then if (($maxloglvl >= 5)); then
ddebug "Listing sizes of included files:" ddebug "Listing sizes of included files:"
du -c "$initdir" | sort -n | ddebug du -c "$initdir" | sort -n | ddebug