]>
Commit | Line | Data |
---|---|---|
290df2e1 ES |
1 | #!/bin/bash |
2 | ||
3 | # called by dracut | |
4 | # | |
5 | # Parses depmod configuration and calls instmods for out-of-tree kernel | |
6 | # modules found. Specifically, kernel modules inside directories that | |
7 | # come from the following places are included (if these kernel modules | |
8 | # are present in modules.dep): | |
9 | # - "search" configuration option; | |
10 | # - "override" configuration option (matching an exact file name constructed | |
11 | # by concatenating the provided directory and the kernel module name); | |
12 | # - "external" configuration option (if "external" is a part of "search" | |
13 | # configuration). | |
14 | # (See depmod.d(5) for details.) | |
15 | # | |
16 | # This module has the following variables available for configuration: | |
17 | # - "depmod_modules_dep" - Path to the modules.dep file | |
18 | # ("$srcmods/modules.dep" by default); | |
19 | # - "depmod_module_dir" - Directory containing kernel modules ("$srcmods" | |
20 | # by default); | |
21 | # - "depmod_configs" - array of depmod configuration paths to parse | |
22 | # (as supplied to depmod -C, ("/run/depmod.d/" | |
23 | # "/etc/depmod.d/" "/lib/depmod.d/") by default). | |
24 | installkernel() | |
25 | { | |
26 | : "${depmod_modules_dep:=$srcmods/modules.dep}" | |
27 | : "${depmod_module_dir:=$srcmods}" | |
28 | ||
29 | [[ -f "${depmod_modules_dep}" ]] || return 0 | |
30 | ||
31 | # Message printers with custom prefix | |
32 | local mod_name="kernel-modules-extra" | |
33 | prinfo() { dinfo " ${mod_name}: $*"; } | |
34 | prdebug() { ddebug " ${mod_name}: $*"; } | |
35 | ||
36 | # Escape a string for usage as a part of extended regular expression. | |
37 | # $1 - string to escape | |
38 | re_escape() { | |
39 | printf "%s" "$1" | sed 's/\([.+?^$\/\\|()\[]\|\]\)/\\\0/' | |
40 | } | |
41 | ||
42 | local OLDIFS | |
43 | local cfg | |
44 | local cfgs=() | |
45 | local search_list="" | |
46 | local overrides=() | |
47 | local external_dirs=() | |
48 | local e f | |
49 | ||
50 | ||
51 | ## Gathering and sorting configuration file list | |
52 | ||
8eef563f | 53 | [ -n "${depmod_configs[*]-}" ] \ |
290df2e1 ES |
54 | || depmod_configs=(/run/depmod.d/ /etc/depmod.d/ /lib/depmod.d/) |
55 | ||
56 | for cfg in "${depmod_configs[@]}"; do | |
57 | [ -e "$cfg" ] || { | |
58 | prdebug "configuration source \"$cfg\" does not exist" | |
59 | continue | |
60 | } | |
61 | ||
62 | # '/' is used as a separator between configuration name and | |
63 | # configuration path | |
64 | if [ -d "$cfg" ]; then | |
65 | for f in "$cfg/"*; do | |
66 | [[ -e "$f" && ! -d "$f" ]] || { | |
67 | prdebug "configuration source" \ | |
68 | "\"$cfg\" is ignored" \ | |
69 | "(directory or doesn't exist)" | |
70 | continue | |
71 | } | |
72 | cfgs+=("$(basename "$f")/$f") | |
73 | done | |
74 | else | |
75 | cfgs+=("$(basename "$cfg")/$cfg") | |
76 | fi | |
77 | done | |
78 | ||
79 | OLDIFS="$IFS" | |
80 | IFS=$'\n' | |
81 | LANG=C cfgs=($(printf '%s\n' "${cfgs[@]}" \ | |
82 | | sort -u -k1,1 -t '/' | cut -f 2- -d '/')) | |
83 | IFS="$OLDIFS" | |
84 | ||
85 | ||
86 | ## Parse configurations | |
87 | ||
88 | for cfg in "${cfgs[@]}"; do | |
89 | prdebug "parsing configuration file \"$cfg\"" | |
90 | ||
91 | local k v mod kverpat path | |
92 | while read -r k v; do | |
93 | case "$k" in | |
94 | search) | |
95 | search_list="$search_list $v" | |
96 | prdebug "$cfg: added \"$v\" to the list of" \ | |
97 | "search directories" | |
98 | ;; | |
99 | override) # module_name kver_pattern dir | |
100 | read -r mod kverpat path <<<"$v" | |
101 | ||
102 | if [[ ! "$mod" || ! "$kverpat" || ! "$path" ]] | |
103 | then | |
104 | prinfo "$cfg: ignoring incorrect" \ | |
105 | "override option: \"$k $v\"" | |
106 | continue | |
107 | fi | |
108 | ||
8eef563f HH |
109 | if [[ '*' = "$kverpat" ]] \ |
110 | || [[ "$kernel" =~ $kverpat ]] | |
290df2e1 ES |
111 | then |
112 | overrides+=("${path}/${mod}") | |
113 | ||
114 | prdebug "$cfg: added override" \ | |
115 | "\"${path}/${mod}\"" | |
116 | else | |
117 | prdebug "$cfg: override \"$v\" is" \ | |
118 | "ignored since \"$kverpat\"" \ | |
119 | "doesn't match \"$kernel\"" | |
120 | fi | |
121 | ;; | |
122 | external) # kverpat dir | |
123 | read -r kverpat path <<<"$v" | |
124 | ||
125 | if [[ ! "$kverpat" || ! "$path" ]]; then | |
126 | prinfo "$cfg: ignoring incorrect" \ | |
127 | "external option: \"$k $v\"" | |
128 | continue | |
129 | fi | |
130 | ||
131 | if [[ '*' = "$kverpat" \ | |
8eef563f | 132 | || "$kernel" =~ $kverpat ]] |
290df2e1 ES |
133 | then |
134 | external_dirs+=("$path") | |
135 | ||
136 | prdebug "$cfg: added external" \ | |
137 | "directory \"$path\"" | |
138 | else | |
139 | prdebug "$cfg: external directory" \ | |
140 | "\"$path\" is ignored since" \ | |
141 | "\"$kverpat\" doesn't match " \ | |
142 | "\"$kernel\"" | |
143 | fi | |
144 | ;; | |
145 | '#'*|'') # comments and empty strings | |
146 | ;; | |
147 | include|make_map_files) # ignored by depmod | |
148 | ;; | |
149 | *) | |
150 | prinfo "$cfg: unknown depmod configuration" \ | |
151 | "option \"$k $v\"" | |
152 | ;; | |
153 | esac | |
154 | done < "$cfg" | |
155 | done | |
156 | ||
157 | # "updates built-in" is the default search list | |
158 | : "${search_list:=updates}" | |
159 | ||
160 | ||
161 | ## Build a list of regular expressions for grepping modules.dep | |
162 | ||
163 | local pathlist=() | |
164 | for f in "${overrides[@]}"; do | |
165 | pathlist+=("^$(re_escape "$f")") | |
166 | done | |
167 | ||
168 | for f in $(printf "%s" "$search_list"); do | |
169 | # Ignoring builtin modules | |
170 | [ "built-in" != "$f" ] || continue | |
171 | ||
172 | if [ "external" = "$f" ]; then | |
173 | for e in "${external_dirs[@]}"; do | |
174 | pathlist+=("$(re_escape "${e%/}")/[^:]+") | |
175 | done | |
176 | fi | |
177 | ||
178 | pathlist+=("$(re_escape "${f%/}")/[^:]+") | |
179 | done | |
180 | ||
181 | ||
182 | ## Filter modules.dep, canonicalise the resulting filenames and supply | |
183 | ## them to instmods. | |
184 | ||
185 | [ 0 -lt "${#pathlist[@]}" ] || return 0 | |
186 | ||
187 | printf "^%s\.ko(\.gz|\.bz2|\.xz)?:\n" "${pathlist[@]}" \ | |
188 | | (LANG=C grep -E -o -f - -- "$depmod_modules_dep" || exit 0) \ | |
189 | | tr -d ':' \ | |
d1afff43 | 190 | | (cd "$depmod_module_dir" || exit; xargs -r realpath -se --) \ |
290df2e1 ES |
191 | | instmods || return 1 |
192 | ||
193 | return 0 | |
194 | } |