You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
6.2 KiB
186 lines
6.2 KiB
#!/bin/bash |
|
|
|
# called by dracut |
|
# |
|
# Parses depmod configuration and calls instmods for out-of-tree kernel |
|
# modules found. Specifically, kernel modules inside directories that |
|
# come from the following places are included (if these kernel modules |
|
# are present in modules.dep): |
|
# - "search" configuration option; |
|
# - "override" configuration option (matching an exact file name constructed |
|
# by concatenating the provided directory and the kernel module name); |
|
# - "external" configuration option (if "external" is a part of "search" |
|
# configuration). |
|
# (See depmod.d(5) for details.) |
|
# |
|
# This module has the following variables available for configuration: |
|
# - "depmod_modules_dep" - Path to the modules.dep file |
|
# ("$srcmods/modules.dep" by default); |
|
# - "depmod_module_dir" - Directory containing kernel modules ("$srcmods" |
|
# by default); |
|
# - "depmod_configs" - array of depmod configuration paths to parse |
|
# (as supplied to depmod -C, ("/run/depmod.d/" |
|
# "/etc/depmod.d/" "/lib/depmod.d/") by default). |
|
installkernel() { |
|
: "${depmod_modules_dep:=$srcmods/modules.dep}" |
|
: "${depmod_module_dir:=$srcmods}" |
|
|
|
[[ -f ${depmod_modules_dep} ]] || return 0 |
|
|
|
# Message printers with custom prefix |
|
local mod_name="kernel-modules-extra" |
|
prinfo() { dinfo " ${mod_name}: $*"; } |
|
prdebug() { ddebug " ${mod_name}: $*"; } |
|
|
|
# Escape a string for usage as a part of extended regular expression. |
|
# $1 - string to escape |
|
re_escape() { |
|
printf "%s" "$1" | sed 's/\([.+?^$\/\\|()\[]\|\]\)/\\\0/' |
|
} |
|
|
|
local cfg |
|
local cfgs=() |
|
local search_list="" |
|
local overrides=() |
|
local external_dirs=() |
|
local e f |
|
|
|
## Gathering and sorting configuration file list |
|
|
|
[ -n "${depmod_configs[*]-}" ] \ |
|
|| depmod_configs=(/run/depmod.d /etc/depmod.d /lib/depmod.d) |
|
|
|
for cfg in "${depmod_configs[@]}"; do |
|
[ -e "$cfg" ] || { |
|
prdebug "configuration source \"$cfg\" does not exist" |
|
continue |
|
} |
|
|
|
# '/' is used as a separator between configuration name and |
|
# configuration path |
|
if [ -d "$cfg" ]; then |
|
for f in "$cfg/"*.conf; do |
|
[[ -e $f && ! -d $f ]] || { |
|
prdebug "configuration source" \ |
|
"\"$cfg\" is ignored" \ |
|
"(directory or doesn't exist)" |
|
continue |
|
} |
|
cfgs+=("${f##*/}/$f") |
|
done |
|
else |
|
cfgs+=("${cfg##*/}/$cfg") |
|
fi |
|
done |
|
|
|
if ((${#cfgs[@]} > 0)); then |
|
mapfile -t cfgs < <(printf '%s\n' "${cfgs[@]}" | LANG=C sort -u -k1,1 -t '/' | cut -f 2- -d '/') |
|
fi |
|
|
|
## Parse configurations |
|
|
|
for cfg in "${cfgs[@]}"; do |
|
prdebug "parsing configuration file \"$cfg\"" |
|
|
|
local k v mod kverpat path |
|
while read -r k v; do |
|
case "$k" in |
|
search) |
|
search_list="$search_list $v" |
|
prdebug "$cfg: added \"$v\" to the list of" \ |
|
"search directories" |
|
;; |
|
override) # module_name kver_pattern dir |
|
read -r mod kverpat path <<< "$v" |
|
|
|
if [[ ! $mod || ! $kverpat || ! $path ]]; then |
|
prinfo "$cfg: ignoring incorrect" \ |
|
"override option: \"$k $v\"" |
|
continue |
|
fi |
|
|
|
if [[ '*' == "$kverpat" ]] \ |
|
|| [[ $kernel =~ $kverpat ]]; then |
|
overrides+=("${path}/${mod}") |
|
|
|
prdebug "$cfg: added override" \ |
|
"\"${path}/${mod}\"" |
|
else |
|
prdebug "$cfg: override \"$v\" is" \ |
|
"ignored since \"$kverpat\"" \ |
|
"doesn't match \"$kernel\"" |
|
fi |
|
;; |
|
external) # kverpat dir |
|
read -r kverpat path <<< "$v" |
|
|
|
if [[ ! $kverpat || ! $path ]]; then |
|
prinfo "$cfg: ignoring incorrect" \ |
|
"external option: \"$k $v\"" |
|
continue |
|
fi |
|
|
|
if [[ '*' == "$kverpat" || \ |
|
$kernel =~ $kverpat ]]; then |
|
external_dirs+=("$path") |
|
|
|
prdebug "$cfg: added external" \ |
|
"directory \"$path\"" |
|
else |
|
prdebug "$cfg: external directory" \ |
|
"\"$path\" is ignored since" \ |
|
"\"$kverpat\" doesn't match " \ |
|
"\"$kernel\"" |
|
fi |
|
;; |
|
'#'* | '') # comments and empty strings |
|
;; |
|
include | make_map_files) # ignored by depmod |
|
;; |
|
*) |
|
prinfo "$cfg: unknown depmod configuration" \ |
|
"option \"$k $v\"" |
|
;; |
|
esac |
|
done < "$cfg" |
|
done |
|
|
|
# "updates built-in" is the default search list |
|
: "${search_list:=updates}" |
|
|
|
## Build a list of regular expressions for grepping modules.dep |
|
|
|
local pathlist=() |
|
for f in "${overrides[@]}"; do |
|
pathlist+=("^$(re_escape "$f")") |
|
done |
|
|
|
for f in $(printf "%s" "$search_list"); do |
|
# Ignoring builtin modules |
|
[[ $f == "built-in" ]] && continue |
|
|
|
if [[ $f == "external" ]]; then |
|
for e in "${external_dirs[@]}"; do |
|
pathlist+=("$(re_escape "${e%/}")/[^:]+") |
|
done |
|
fi |
|
|
|
pathlist+=("$(re_escape "${f%/}")/[^:]+") |
|
done |
|
|
|
## Filter modules.dep, canonicalise the resulting filenames and supply |
|
## them to instmods. |
|
|
|
((${#pathlist[@]} > 0)) || return 0 |
|
|
|
printf "^%s\.ko(\.gz|\.bz2|\.xz)?:\n" "${pathlist[@]}" \ |
|
| (LANG=C grep -E -o -f - -- "$depmod_modules_dep" || exit 0) \ |
|
| tr -d ':' \ |
|
| ( |
|
cd "$depmod_module_dir" || exit |
|
xargs -r realpath -se -- |
|
) \ |
|
| instmods || return 1 |
|
|
|
return 0 |
|
}
|
|
|