mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
test: rewrite kernel module handling
This code was partially broken, since the firmware directory was undefined. Also, some of the parts were a dead code, since they relied on code from the original dracut test suite.
This commit is contained in:
parent
0f1947059b
commit
94009c27f4
@ -2076,53 +2076,37 @@ dracut_install() {
|
||||
# Install a single kernel module along with any firmware it may require.
|
||||
# $1 = full path to kernel module to install
|
||||
install_kmod_with_fw() {
|
||||
local module="${1:?}"
|
||||
# no need to go further if the module is already installed
|
||||
[[ -e "${initdir:?}/lib/modules/${KERNEL_VER:?}/${module##*/lib/modules/$KERNEL_VER/}" ]] && return 0
|
||||
[[ -e "$initdir/.kernelmodseen/${module##*/}" ]] && return 0
|
||||
|
||||
[[ -e "${initdir}/lib/modules/$KERNEL_VER/${1##*/lib/modules/$KERNEL_VER/}" ]] \
|
||||
&& return 0
|
||||
[ -d "$initdir/.kernelmodseen" ] && : >"$initdir/.kernelmodseen/${module##*/}"
|
||||
|
||||
[[ -e "$initdir/.kernelmodseen/${1##*/}" ]] && return 0
|
||||
inst_simple "$module" "/lib/modules/$KERNEL_VER/${module##*/lib/modules/$KERNEL_VER/}" || return $?
|
||||
|
||||
if [[ $omit_drivers ]]; then
|
||||
local _kmod=${1##*/}
|
||||
_kmod=${_kmod%.ko}
|
||||
_kmod=${_kmod/-/_}
|
||||
if [[ "$_kmod" =~ $omit_drivers ]]; then
|
||||
dinfo "Omitting driver $_kmod"
|
||||
return 1
|
||||
fi
|
||||
if [[ "${1##*/lib/modules/$KERNEL_VER/}" =~ $omit_drivers ]]; then
|
||||
dinfo "Omitting driver $_kmod"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
local modname="${module##*/}"
|
||||
local fwdir found fw
|
||||
modname="${modname%.ko*}"
|
||||
|
||||
[ -d "$initdir/.kernelmodseen" ] && \
|
||||
>"$initdir/.kernelmodseen/${1##*/}"
|
||||
|
||||
inst_simple "$1" "/lib/modules/$KERNEL_VER/${1##*/lib/modules/$KERNEL_VER/}" \
|
||||
|| return $?
|
||||
|
||||
local _modname=${1##*/} _fwdir _found _fw
|
||||
_modname=${_modname%.ko*}
|
||||
for _fw in $(modinfo -k $KERNEL_VER -F firmware $1 2>/dev/null); do
|
||||
_found=''
|
||||
for _fwdir in $fw_dir; do
|
||||
if [[ -d $_fwdir && -f $_fwdir/$_fw ]]; then
|
||||
inst_simple "$_fwdir/$_fw" "/lib/firmware/$_fw"
|
||||
_found=yes
|
||||
while read -r fw; do
|
||||
found=
|
||||
for fwdir in /lib/firmware/updates /lib/firmware; do
|
||||
if [[ -d "$fwdir" && -f "$fwdir/$fw" ]]; then
|
||||
inst_simple "$fwdir/$fw" "/lib/firmware/$fw"
|
||||
found=yes
|
||||
fi
|
||||
done
|
||||
if [[ $_found != yes ]]; then
|
||||
if ! grep -qe "\<${_modname//-/_}\>" /proc/modules; then
|
||||
dinfo "Possible missing firmware \"${_fw}\" for kernel module" \
|
||||
"\"${_modname}.ko\""
|
||||
if [[ $found != yes ]]; then
|
||||
if ! grep -qe "\<${modname//-/_}\>" /proc/modules; then
|
||||
dinfo "Possible missing firmware \"${fw}\" for kernel module" \
|
||||
"\"${modname}.ko\""
|
||||
else
|
||||
dwarn "Possible missing firmware \"${_fw}\" for kernel module" \
|
||||
"\"${_modname}.ko\""
|
||||
dwarn "Possible missing firmware \"${fw}\" for kernel module" \
|
||||
"\"${modname}.ko\""
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done < <(modinfo -k "$KERNEL_VER" -F firmware "$module" 2>/dev/null)
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -2132,168 +2116,104 @@ install_kmod_with_fw() {
|
||||
# It will be passed the full path to the found kernel module
|
||||
# $2 = module to get dependencies for
|
||||
# rest of args = arguments to modprobe
|
||||
# _fderr specifies FD passed from surrounding scope
|
||||
for_each_kmod_dep() {
|
||||
local _func=$1 _kmod=$2 _cmd _modpath _options _found=0
|
||||
local func="${1:?}"
|
||||
local kmod="${2:?}"
|
||||
local found=0
|
||||
local cmd modpath
|
||||
shift 2
|
||||
modprobe "$@" --ignore-install --show-depends $_kmod 2>&${_fderr} | (
|
||||
while read _cmd _modpath _options; do
|
||||
[[ $_cmd = insmod ]] || continue
|
||||
$_func ${_modpath} || exit $?
|
||||
_found=1
|
||||
done
|
||||
[[ $_found -eq 0 ]] && exit 1
|
||||
exit 0
|
||||
)
|
||||
}
|
||||
|
||||
# filter kernel modules to install certain modules that meet specific
|
||||
# requirements.
|
||||
# $1 = search only in subdirectory of /kernel/$1
|
||||
# $2 = function to call with module name to filter.
|
||||
# This function will be passed the full path to the module to test.
|
||||
# The behavior of this function can vary depending on whether $hostonly is set.
|
||||
# If it is, we will only look at modules that are already in memory.
|
||||
# If it is not, we will look at all kernel modules
|
||||
# This function returns the full filenames of modules that match $1
|
||||
filter_kernel_modules_by_path () (
|
||||
local _modname _filtercmd
|
||||
if ! [[ $hostonly ]]; then
|
||||
_filtercmd='find "$KERNEL_MODS/kernel/$1" "$KERNEL_MODS/extra"'
|
||||
_filtercmd+=' "$KERNEL_MODS/weak-updates" -name "*.ko" -o -name "*.ko.gz"'
|
||||
_filtercmd+=' -o -name "*.ko.xz"'
|
||||
_filtercmd+=' 2>/dev/null'
|
||||
else
|
||||
_filtercmd='cut -d " " -f 1 </proc/modules|xargs modinfo -F filename '
|
||||
_filtercmd+='-k $KERNEL_VER 2>/dev/null'
|
||||
fi
|
||||
for _modname in $(eval $_filtercmd); do
|
||||
case $_modname in
|
||||
*.ko) "$2" "$_modname" && echo "$_modname";;
|
||||
*.ko.gz) gzip -dc "$_modname" >$initdir/$$.ko
|
||||
$2 $initdir/$$.ko && echo "$_modname"
|
||||
rm -f $initdir/$$.ko
|
||||
;;
|
||||
*.ko.xz) xz -dc "$_modname" >$initdir/$$.ko
|
||||
$2 $initdir/$$.ko && echo "$_modname"
|
||||
rm -f $initdir/$$.ko
|
||||
;;
|
||||
esac
|
||||
done
|
||||
)
|
||||
find_kernel_modules_by_path () (
|
||||
if ! [[ $hostonly ]]; then
|
||||
find "$KERNEL_MODS/kernel/$1" "$KERNEL_MODS/extra" "$KERNEL_MODS/weak-updates" \
|
||||
-name "*.ko" -o -name "*.ko.gz" -o -name "*.ko.xz" 2>/dev/null
|
||||
else
|
||||
cut -d " " -f 1 </proc/modules \
|
||||
| xargs modinfo -F filename -k $KERNEL_VER 2>/dev/null
|
||||
fi
|
||||
)
|
||||
while read -r cmd modpath _; do
|
||||
[[ "$cmd" = insmod ]] || continue
|
||||
"$func" "$modpath" || return $?
|
||||
found=1
|
||||
done < <(modprobe "$@" --ignore-install --show-depends "$kmod")
|
||||
|
||||
filter_kernel_modules () {
|
||||
filter_kernel_modules_by_path drivers "$1"
|
||||
}
|
||||
|
||||
find_kernel_modules () {
|
||||
find_kernel_modules_by_path drivers
|
||||
[[ $found -eq 0 ]] && return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# instmods [-c] <kernel module> [<kernel module> ... ]
|
||||
# instmods [-c] <kernel subsystem>
|
||||
# install kernel modules along with all their dependencies.
|
||||
# <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
|
||||
# FIXME(?): dracutdevs/dracut@f4e38c0da8d6bf3764c1ad753d9d52aef63050e5
|
||||
instmods() {
|
||||
[[ $no_kernel = yes ]] && return
|
||||
# called [sub]functions inherit _fderr
|
||||
local _fderr=9
|
||||
local _check=no
|
||||
if [[ $1 = '-c' ]]; then
|
||||
_check=yes
|
||||
local check=no
|
||||
if [[ $# -ge 0 && "$1" = '-c' ]]; then
|
||||
check=yes
|
||||
shift
|
||||
fi
|
||||
|
||||
function inst1mod() {
|
||||
local _ret=0 _mod="$1"
|
||||
case $_mod in
|
||||
inst1mod() {
|
||||
local mod="${1:?}"
|
||||
local ret=0
|
||||
local mod_dir="/lib/modules/${KERNEL_VER:?}/"
|
||||
|
||||
case "$mod" in
|
||||
=*)
|
||||
if [ -f $KERNEL_MODS/modules.${_mod#=} ]; then
|
||||
( [[ "$_mpargs" ]] && echo $_mpargs
|
||||
cat "${KERNEL_MODS}/modules.${_mod#=}" ) \
|
||||
| instmods
|
||||
if [ -f "${mod_dir}/modules.${mod#=}" ]; then
|
||||
(
|
||||
[[ "$mpargs" ]] && echo "$mpargs"
|
||||
cat "${mod_dir}/modules.${mod#=}"
|
||||
) | instmods
|
||||
else
|
||||
( [[ "$_mpargs" ]] && echo $_mpargs
|
||||
find "$KERNEL_MODS" -path "*/${_mod#=}/*" -type f -printf '%f\n' ) \
|
||||
| instmods
|
||||
(
|
||||
[[ "$mpargs" ]] && echo "$mpargs"
|
||||
find "$mod_dir" -path "*/${mod#=}/*" -type f -printf '%f\n'
|
||||
) | instmods
|
||||
fi
|
||||
;;
|
||||
--*) _mpargs+=" $_mod" ;;
|
||||
i2o_scsi) return ;; # Do not load this diagnostic-only module
|
||||
--*)
|
||||
mpargs+=" $mod"
|
||||
;;
|
||||
i2o_scsi)
|
||||
# Do not load this diagnostic-only module
|
||||
return
|
||||
;;
|
||||
*)
|
||||
_mod=${_mod##*/}
|
||||
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 [[ $omit_drivers ]] && [[ "$1" =~ $omit_drivers ]]; then
|
||||
dinfo "Omitting driver ${_mod##$KERNEL_MODS}"
|
||||
return
|
||||
fi
|
||||
# If we are building a host-specific initramfs and this
|
||||
# module is not already loaded, move on to the next one.
|
||||
[[ $hostonly ]] && ! grep -qe "\<${_mod//-/_}\>" /proc/modules \
|
||||
&& ! echo $add_drivers | grep -qe "\<${_mod}\>" \
|
||||
&& return
|
||||
[[ -f "${initdir:?}/.kernelmodseen/${mod%.ko}.ko" ]] && return
|
||||
|
||||
# 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=${KERNEL_MODS%%/lib/modules/*}
|
||||
[[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/"
|
||||
local mod_dirname=${mod_dir%%/lib/modules/*}
|
||||
[[ -n ${mod_dirname} ]] && mod_dirname="-d ${mod_dirname}/"
|
||||
|
||||
# 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_VER ${_moddirname} $_mpargs
|
||||
((_ret+=$?))
|
||||
for_each_kmod_dep install_kmod_with_fw "$mod" \
|
||||
--set-version "$KERNEL_VER" \
|
||||
${mod_dirname:+"$mod_dirname"} \
|
||||
${mpargs:+"$mpargs"}
|
||||
((ret+=$?))
|
||||
;;
|
||||
esac
|
||||
return $_ret
|
||||
return $ret
|
||||
}
|
||||
|
||||
function instmods_1() {
|
||||
local _mod _mpargs
|
||||
if (($# == 0)); then # filenames from stdin
|
||||
while read _mod; do
|
||||
inst1mod "${_mod%.ko*}" || {
|
||||
if [ "$_check" = "yes" ]; then
|
||||
dfatal "Failed to install $_mod"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
done
|
||||
fi
|
||||
while (($# > 0)); do # filenames as arguments
|
||||
inst1mod ${1%.ko*} || {
|
||||
if [ "$_check" = "yes" ]; then
|
||||
dfatal "Failed to install $1"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
shift
|
||||
local mod mpargs
|
||||
|
||||
if [[ $# -eq 0 ]]; then # filenames from stdin
|
||||
while read -r mod; do
|
||||
if ! inst1mod "${mod%.ko*}" && [ "$check" = "yes" ]; then
|
||||
dfatal "Failed to install $mod"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
fi
|
||||
|
||||
local _ret _filter_not_found='FATAL: Module .* not found.'
|
||||
set -o pipefail
|
||||
# Capture all stderr from modprobe to _fderr. We could use {var}>...
|
||||
# redirections, but that would make dracut require bash4 at least.
|
||||
eval "( instmods_1 \"\$@\" ) ${_fderr}>&1" \
|
||||
| while read line; do [[ "$line" =~ $_filter_not_found ]] && echo $line || echo $line >&2 ;done | derror
|
||||
_ret=$?
|
||||
set +o pipefail
|
||||
return $_ret
|
||||
for mod in "$@"; do # filenames as arguments
|
||||
if ! inst1mod "${mod%.ko*}" && [ "$check" = "yes" ]; then
|
||||
dfatal "Failed to install $mod"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
setup_suse() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user