]>
Commit | Line | Data |
---|---|---|
777f2db0 HH |
1 | #!/bin/bash |
2 | # | |
561eb42f | 3 | # functions used only by dracut and dracut modules |
777f2db0 HH |
4 | # |
5 | # Copyright 2005-2009 Red Hat, Inc. All rights reserved. | |
6 | # | |
7 | # This program is free software; you can redistribute it and/or modify | |
8 | # it under the terms of the GNU General Public License as published by | |
9 | # the Free Software Foundation; either version 2 of the License, or | |
10 | # (at your option) any later version. | |
11 | # | |
12 | # This program is distributed in the hope that it will be useful, | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | # GNU General Public License for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU General Public License | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | # | |
20 | export LC_MESSAGES=C | |
21 | ||
93be2bc6 | 22 | if [[ "$EUID" = "0" ]] && ! [[ $DRACUT_NO_XATTR ]]; then |
076fcd16 HH |
23 | export DRACUT_CP="cp --reflink=auto --sparse=auto --preserve=mode,timestamps,xattr,links -dfr" |
24 | else | |
25 | export DRACUT_CP="cp --reflink=auto --sparse=auto --preserve=mode,timestamps,links -dfr" | |
26 | fi | |
7e51a94f | 27 | |
561eb42f HH |
28 | # is_func <command> |
29 | # Check whether $1 is a function. | |
30 | is_func() { | |
31 | [[ "$(type -t "$1")" = "function" ]] | |
32 | } | |
33 | ||
34 | if ! [[ $dracutbasedir ]]; then | |
35 | dracutbasedir=${BASH_SOURCE[0]%/*} | |
36 | [[ $dracutbasedir = dracut-functions* ]] && dracutbasedir="." | |
37 | [[ $dracutbasedir ]] || dracutbasedir="." | |
38 | dracutbasedir="$(readlink -f $dracutbasedir)" | |
39 | fi | |
40 | ||
41 | if ! is_func dinfo >/dev/null 2>&1; then | |
2d4344bc | 42 | # shellcheck source=./dracut-logger.sh |
561eb42f HH |
43 | . "$dracutbasedir/dracut-logger.sh" |
44 | dlog_init | |
45 | fi | |
46 | ||
2d4344bc | 47 | # shellcheck disable=SC2154 |
561eb42f HH |
48 | if ! [[ $initdir ]]; then |
49 | dfatal "initdir not set" | |
50 | exit 1 | |
51 | fi | |
52 | ||
53 | if ! [[ -d $initdir ]]; then | |
54 | mkdir -p "$initdir" | |
55 | fi | |
56 | ||
561eb42f HH |
57 | if ! [[ $kernel ]]; then |
58 | kernel=$(uname -r) | |
59 | export kernel | |
60 | fi | |
61 | ||
2d4344bc | 62 | # shellcheck disable=SC2154 |
a0120420 | 63 | srcmods="$dracutsysrootdir/lib/modules/$kernel/" |
561eb42f | 64 | |
2d4344bc | 65 | # shellcheck disable=SC2154 |
561eb42f HH |
66 | [[ $drivers_dir ]] && { |
67 | if ! command -v kmod &>/dev/null && vercmp "$(modprobe --version | cut -d' ' -f3)" lt 3.7; then | |
68 | dfatal 'To use --kmoddir option module-init-tools >= 3.7 is required.' | |
69 | exit 1 | |
70 | fi | |
71 | srcmods="$drivers_dir" | |
72 | } | |
73 | export srcmods | |
74 | ||
8e010957 HH |
75 | [[ $DRACUT_FIRMWARE_PATH ]] || export DRACUT_FIRMWARE_PATH="/lib/firmware/updates:/lib/firmware:/lib/firmware/$kernel" |
76 | ||
561eb42f HH |
77 | # export standard hookdirs |
78 | [[ $hookdirs ]] || { | |
79 | hookdirs="cmdline pre-udev pre-trigger netroot " | |
80 | hookdirs+="initqueue initqueue/settled initqueue/online initqueue/finished initqueue/timeout " | |
81 | hookdirs+="pre-mount pre-pivot cleanup mount " | |
82 | hookdirs+="emergency shutdown-emergency pre-shutdown shutdown " | |
83 | export hookdirs | |
84 | } | |
85 | ||
a0120420 BZ |
86 | DRACUT_LDD=${DRACUT_LDD:-ldd} |
87 | DRACUT_TESTBIN=${DRACUT_TESTBIN:-/bin/sh} | |
88 | DRACUT_LDCONFIG=${DRACUT_LDCONFIG:-ldconfig} | |
89 | ||
2d4344bc HH |
90 | # shellcheck source=./dracut-functions.sh |
91 | . "$dracutbasedir"/dracut-functions.sh | |
456f299a | 92 | |
561eb42f HH |
93 | # Detect lib paths |
94 | if ! [[ $libdirs ]] ; then | |
2d4344bc | 95 | if [[ $("$DRACUT_LDD" "$dracutsysrootdir$DRACUT_TESTBIN") == */lib64/* ]] &>/dev/null \ |
a0120420 | 96 | && [[ -d $dracutsysrootdir/lib64 ]]; then |
561eb42f | 97 | libdirs+=" /lib64" |
a0120420 | 98 | [[ -d $dracutsysrootdir/usr/lib64 ]] && libdirs+=" /usr/lib64" |
561eb42f HH |
99 | else |
100 | libdirs+=" /lib" | |
a0120420 | 101 | [[ -d $dracutsysrootdir/usr/lib ]] && libdirs+=" /usr/lib" |
561eb42f HH |
102 | fi |
103 | ||
104 | libdirs+=" $(ldconfig_paths)" | |
105 | ||
106 | export libdirs | |
777f2db0 HH |
107 | fi |
108 | ||
561eb42f HH |
109 | # helper function for check() in module-setup.sh |
110 | # to check for required installed binaries | |
111 | # issues a standardized warning message | |
112 | require_binaries() { | |
2d4344bc | 113 | # shellcheck disable=SC2154 |
561eb42f HH |
114 | local _module_name="${moddir##*/}" |
115 | local _ret=0 | |
116 | ||
117 | if [[ "$1" = "-m" ]]; then | |
118 | _module_name="$2" | |
119 | shift 2 | |
120 | fi | |
121 | ||
122 | for cmd in "$@"; do | |
123 | if ! find_binary "$cmd" &>/dev/null; then | |
124 | dinfo "dracut module '${_module_name#[0-9][0-9]}' will not be installed, because command '$cmd' could not be found!" | |
125 | ((_ret++)) | |
126 | fi | |
127 | done | |
2d4344bc | 128 | return "$_ret" |
561eb42f HH |
129 | } |
130 | ||
131 | require_any_binary() { | |
132 | local _module_name="${moddir##*/}" | |
133 | local _ret=1 | |
134 | ||
135 | if [[ "$1" = "-m" ]]; then | |
136 | _module_name="$2" | |
137 | shift 2 | |
138 | fi | |
139 | ||
140 | for cmd in "$@"; do | |
141 | if find_binary "$cmd" &>/dev/null; then | |
142 | _ret=0 | |
143 | break | |
144 | fi | |
145 | done | |
146 | ||
2d4344bc HH |
147 | if (( _ret != 0 )); then |
148 | dinfo "$_module_name: Could not find any command of '$*'!" | |
561eb42f HH |
149 | return 1 |
150 | fi | |
151 | ||
152 | return 0 | |
153 | } | |
154 | ||
155 | dracut_need_initqueue() { | |
2d4344bc | 156 | : >"$initdir/lib/dracut/need-initqueue" |
561eb42f HH |
157 | } |
158 | ||
159 | dracut_module_included() { | |
2d4344bc | 160 | # shellcheck disable=SC2154 |
561eb42f HH |
161 | [[ " $mods_to_load $modules_loaded " == *\ $*\ * ]] |
162 | } | |
163 | ||
19e57585 | 164 | dracut_no_switch_root() { |
2d4344bc | 165 | : >"$initdir/lib/dracut/no-switch-root" |
19e57585 KS |
166 | } |
167 | ||
5916d31b | 168 | dracut_module_path() { |
2d4344bc HH |
169 | local _dir |
170 | ||
171 | # shellcheck disable=SC2231 | |
172 | for _dir in "${dracutbasedir}"/modules.d/??${1}; do | |
173 | echo "$_dir" | |
174 | return 0 | |
175 | done | |
176 | return 1 | |
5916d31b KS |
177 | } |
178 | ||
561eb42f HH |
179 | if ! [[ $DRACUT_INSTALL ]]; then |
180 | DRACUT_INSTALL=$(find_binary dracut-install) | |
181 | fi | |
182 | ||
183 | if ! [[ $DRACUT_INSTALL ]] && [[ -x $dracutbasedir/dracut-install ]]; then | |
184 | DRACUT_INSTALL=$dracutbasedir/dracut-install | |
185 | elif ! [[ $DRACUT_INSTALL ]] && [[ -x $dracutbasedir/install/dracut-install ]]; then | |
186 | DRACUT_INSTALL=$dracutbasedir/install/dracut-install | |
187 | fi | |
188 | ||
a0120420 BZ |
189 | # Test if dracut-install is a standalone executable with no options. |
190 | # E.g. DRACUT_INSTALL may be set externally as: | |
191 | # DRACUT_INSTALL="valgrind dracut-install" | |
192 | # or | |
193 | # DRACUT_INSTALL="dracut-install --debug" | |
194 | # in which case the string cannot be tested for being executable. | |
195 | DRINSTALLPARTS=0 | |
196 | for i in $DRACUT_INSTALL ; do | |
2d4344bc | 197 | DRINSTALLPARTS=$((DRINSTALLPARTS+1)) |
a0120420 BZ |
198 | done |
199 | ||
f84ad9e0 | 200 | if [[ $DRINSTALLPARTS = 1 ]] && ! command -v "$DRACUT_INSTALL" > /dev/null 2>&1 ; then |
561eb42f HH |
201 | dfatal "dracut-install not found!" |
202 | exit 10 | |
203 | fi | |
204 | ||
3ad12c7b | 205 | if [[ $hostonly == "-h" ]]; then |
d84f4687 | 206 | if ! [[ $DRACUT_KERNEL_MODALIASES ]] || ! [[ -f "$DRACUT_KERNEL_MODALIASES" ]]; then |
3ad12c7b | 207 | export DRACUT_KERNEL_MODALIASES="${DRACUT_TMPDIR}/modaliases" |
2d4344bc | 208 | "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${srcmods:+--kerneldir "$srcmods"} --modalias > "$DRACUT_KERNEL_MODALIASES" |
3ad12c7b HH |
209 | fi |
210 | fi | |
211 | ||
561eb42f HH |
212 | [[ $DRACUT_RESOLVE_LAZY ]] || export DRACUT_RESOLVE_DEPS=1 |
213 | inst_dir() { | |
214 | [[ -e ${initdir}/"$1" ]] && return 0 # already there | |
2d4344bc HH |
215 | if ! "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} -d "$@"; then |
216 | derror FAILED: "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} -d "$@" | |
217 | fi | |
561eb42f HH |
218 | } |
219 | ||
220 | inst() { | |
221 | local _hostonly_install | |
222 | if [[ "$1" == "-H" ]]; then | |
223 | _hostonly_install="-H" | |
224 | shift | |
225 | fi | |
226 | [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there | |
2d4344bc HH |
227 | # shellcheck disable=SC2154 |
228 | if ! "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"; then | |
229 | derror FAILED: "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" | |
230 | fi | |
561eb42f HH |
231 | } |
232 | ||
233 | inst_simple() { | |
234 | local _hostonly_install | |
235 | if [[ "$1" == "-H" ]]; then | |
236 | _hostonly_install="-H" | |
237 | shift | |
238 | fi | |
239 | [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there | |
240 | [[ -e $1 ]] || return 1 # no source | |
63356d54 HH |
241 | if ! "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${_hostonly_install:+-H} "$@"; then |
242 | derror FAILED: "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${_hostonly_install:+-H} "$@" || : | |
243 | fi | |
561eb42f HH |
244 | } |
245 | ||
246 | inst_symlink() { | |
247 | local _hostonly_install | |
248 | if [[ "$1" == "-H" ]]; then | |
249 | _hostonly_install="-H" | |
250 | shift | |
251 | fi | |
252 | [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there | |
253 | [[ -L $1 ]] || return 1 | |
63356d54 HH |
254 | if ! "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"; then |
255 | derror FAILED: "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" || : | |
256 | fi | |
561eb42f HH |
257 | } |
258 | ||
259 | inst_multiple() { | |
260 | local _ret | |
d437970c AH |
261 | if "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} -a ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"; then |
262 | return 0 | |
263 | else | |
63356d54 HH |
264 | _ret=$? |
265 | derror FAILED: "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} -a ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" || : | |
266 | return $_ret | |
267 | fi | |
561eb42f HH |
268 | } |
269 | ||
270 | dracut_install() { | |
271 | inst_multiple "$@" | |
272 | } | |
273 | ||
794b2d2c | 274 | dracut_instmods() { |
fa295f0b HH |
275 | local _silent=0; |
276 | local i; | |
63356d54 | 277 | # shellcheck disable=SC2154 |
794b2d2c | 278 | [[ $no_kernel = yes ]] && return |
fa295f0b | 279 | for i in "$@"; do |
d13071d7 | 280 | [[ $i == "--silent" ]] && _silent=1 |
fa295f0b HH |
281 | done |
282 | ||
63356d54 HH |
283 | # shellcheck disable=SC2154 |
284 | if ! "$DRACUT_INSTALL" \ | |
a0120420 | 285 | ${dracutsysrootdir:+-r "$dracutsysrootdir"} \ |
63356d54 HH |
286 | ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${srcmods:+--kerneldir "$srcmods"} -m "$@"; then |
287 | if ((_silent == 0)); then | |
288 | derror FAILED: "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${srcmods:+--kerneldir "$srcmods"} -m "$@" || : | |
289 | fi | |
290 | fi | |
794b2d2c HH |
291 | } |
292 | ||
561eb42f HH |
293 | inst_library() { |
294 | local _hostonly_install | |
295 | if [[ "$1" == "-H" ]]; then | |
296 | _hostonly_install="-H" | |
297 | shift | |
298 | fi | |
299 | [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there | |
300 | [[ -e $1 ]] || return 1 # no source | |
63356d54 HH |
301 | if ! "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"; then |
302 | derror FAILED: "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" || : | |
303 | fi | |
561eb42f HH |
304 | } |
305 | ||
306 | inst_binary() { | |
63356d54 HH |
307 | if ! "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"; then |
308 | derror FAILED: "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@" || : | |
309 | fi | |
561eb42f HH |
310 | } |
311 | ||
312 | inst_script() { | |
63356d54 HH |
313 | if ! "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"; then |
314 | derror FAILED: "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@" || : | |
315 | fi | |
561eb42f HH |
316 | } |
317 | ||
1f8a7ae7 MF |
318 | inst_fsck_help() { |
319 | local _helper="/run/dracut/fsck/fsck_help_$1.txt" | |
63356d54 HH |
320 | if ! "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$2" "$_helper"; then |
321 | derror "$DRACUT_INSTALL" ${dracutsysrootdir:+-r "$dracutsysrootdir"} ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$2" "$_helper" || : | |
322 | fi | |
1f8a7ae7 MF |
323 | } |
324 | ||
a695250e KS |
325 | # Use with form hostonly="$(optional_hostonly)" inst_xxxx <args> |
326 | # If hosotnly mode is set to "strict", hostonly restrictions will still | |
327 | # be applied, else will ignore hostonly mode and try to install all | |
328 | # given modules. | |
329 | optional_hostonly() { | |
63356d54 | 330 | # shellcheck disable=SC2154 |
a695250e | 331 | if [[ $hostonly_mode = "strict" ]]; then |
63356d54 | 332 | printf -- "%s" "$hostonly" |
a695250e KS |
333 | else |
334 | printf "" | |
335 | fi | |
336 | } | |
337 | ||
561eb42f HH |
338 | mark_hostonly() { |
339 | for i in "$@"; do | |
340 | echo "$i" >> "$initdir/lib/dracut/hostonly-files" | |
341 | done | |
342 | } | |
343 | ||
344 | # find symlinks linked to given library file | |
345 | # $1 = library file | |
346 | # Function searches for symlinks by stripping version numbers appended to | |
347 | # library filename, checks if it points to the same target and finally | |
348 | # prints the list of symlinks to stdout. | |
349 | # | |
350 | # Example: | |
351 | # rev_lib_symlinks libfoo.so.8.1 | |
352 | # output: libfoo.so.8 libfoo.so | |
353 | # (Only if libfoo.so.8 and libfoo.so exists on host system.) | |
354 | rev_lib_symlinks() { | |
63356d54 HH |
355 | local _fn |
356 | local _orig | |
357 | local _links | |
358 | ||
561eb42f HH |
359 | [[ ! $1 ]] && return 0 |
360 | ||
63356d54 HH |
361 | _fn="$1" |
362 | _orig="$(readlink -f "$1")" | |
363 | _links=() | |
561eb42f | 364 | |
63356d54 | 365 | [[ ${_fn} == *.so.* ]] || return 1 |
561eb42f | 366 | |
63356d54 HH |
367 | until [[ ${_fn##*.} == so ]]; do |
368 | _fn="${_fn%.*}" | |
369 | [[ -L ${_fn} ]] && [[ $(readlink -f "${_fn}") == "${_orig}" ]] && _links+=( "${_fn}" ) | |
561eb42f HH |
370 | done |
371 | ||
63356d54 | 372 | echo "${_links[*]}}" |
561eb42f HH |
373 | } |
374 | ||
375 | # attempt to install any programs specified in a udev rule | |
376 | inst_rule_programs() { | |
377 | local _prog _bin | |
378 | ||
63356d54 | 379 | # shellcheck disable=SC2013 |
374ef3ed | 380 | for _prog in $(sed -nr 's/.*PROGRAM==?"([^ "]+).*/\1/p' "$1"); do |
06a1d076 | 381 | _bin="" |
63356d54 HH |
382 | # shellcheck disable=SC2154 |
383 | if [[ -x ${udevdir}/$_prog ]]; then | |
384 | _bin="${udevdir}"/$_prog | |
06a1d076 VS |
385 | elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then |
386 | _bin=$(find_binary "$_prog") || { | |
387 | dinfo "Skipping program $_prog using in udev rule ${1##*/} as it cannot be found" | |
388 | continue; | |
389 | } | |
390 | fi | |
391 | ||
392 | [[ $_bin ]] && inst_binary "$_bin" | |
393 | done | |
63356d54 HH |
394 | |
395 | # shellcheck disable=SC2013 | |
374ef3ed | 396 | for _prog in $(sed -nr 's/.*RUN[+=]=?"([^ "]+).*/\1/p' "$1"); do |
06a1d076 | 397 | _bin="" |
63356d54 | 398 | if [[ -x ${udevdir}/$_prog ]]; then |
06a1d076 VS |
399 | _bin=${udevdir}/$_prog |
400 | elif [[ "${_prog/\$env\{/}" == "$_prog" ]] && [[ "${_prog}" != "/sbin/initqueue" ]]; then | |
401 | _bin=$(find_binary "$_prog") || { | |
402 | dinfo "Skipping program $_prog using in udev rule ${1##*/} as it cannot be found" | |
403 | continue; | |
404 | } | |
405 | fi | |
406 | ||
407 | [[ $_bin ]] && inst_binary "$_bin" | |
408 | done | |
63356d54 HH |
409 | |
410 | # shellcheck disable=SC2013 | |
374ef3ed | 411 | for _prog in $(sed -nr 's/.*IMPORT\{program\}==?"([^ "]+).*/\1/p' "$1"); do |
06a1d076 | 412 | _bin="" |
63356d54 | 413 | if [[ -x ${udevdir}/$_prog ]]; then |
06a1d076 VS |
414 | _bin=${udevdir}/$_prog |
415 | elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then | |
416 | _bin=$(find_binary "$_prog") || { | |
417 | dinfo "Skipping program $_prog using in udev rule ${1##*/} as it cannot be found" | |
418 | continue; | |
419 | } | |
420 | fi | |
421 | ||
422 | [[ $_bin ]] && dracut_install "$_bin" | |
423 | done | |
561eb42f HH |
424 | } |
425 | ||
426 | # attempt to install any programs specified in a udev rule | |
427 | inst_rule_group_owner() { | |
428 | local i | |
429 | ||
63356d54 | 430 | # shellcheck disable=SC2013 |
374ef3ed | 431 | for i in $(sed -nr 's/.*OWNER=?"([^ "]+).*/\1/p' "$1"); do |
06a1d076 | 432 | if ! grep -Eq "^$i:" "$initdir/etc/passwd" 2>/dev/null; then |
63356d54 | 433 | grep -E "^$i:" "$dracutsysrootdir"/etc/passwd 2>/dev/null >> "$initdir/etc/passwd" |
06a1d076 VS |
434 | fi |
435 | done | |
63356d54 HH |
436 | |
437 | # shellcheck disable=SC2013 | |
06a1d076 VS |
438 | for i in $(sed -nr 's/.*GROUP=?"([^ "]+).*/\1/p' "$1"); do |
439 | if ! grep -Eq "^$i:" "$initdir/etc/group" 2>/dev/null; then | |
63356d54 | 440 | grep -E "^$i:" "$dracutsysrootdir"/etc/group 2>/dev/null >> "$initdir/etc/group" |
06a1d076 VS |
441 | fi |
442 | done | |
561eb42f HH |
443 | } |
444 | ||
445 | inst_rule_initqueue() { | |
446 | if grep -q -F initqueue "$1"; then | |
447 | dracut_need_initqueue | |
448 | fi | |
449 | } | |
450 | ||
451 | # udev rules always get installed in the same place, so | |
452 | # create a function to install them to make life simpler. | |
453 | inst_rules() { | |
454 | local _target=/etc/udev/rules.d _rule _found | |
455 | ||
456 | inst_dir "${udevdir}/rules.d" | |
457 | inst_dir "$_target" | |
458 | for _rule in "$@"; do | |
459 | if [ "${_rule#/}" = "$_rule" ]; then | |
63356d54 | 460 | for r in "$dracutsysrootdir${udevdir}/rules.d" ${hostonly:+"$dracutsysrootdir"/etc/udev/rules.d}; do |
561eb42f HH |
461 | [[ -e $r/$_rule ]] || continue |
462 | _found="$r/$_rule" | |
463 | inst_rule_programs "$_found" | |
464 | inst_rule_group_owner "$_found" | |
465 | inst_rule_initqueue "$_found" | |
466 | inst_simple "$_found" | |
467 | done | |
468 | fi | |
994d0035 | 469 | for r in '' "$dracutsysrootdir$dracutbasedir/rules.d/"; do |
561eb42f HH |
470 | # skip rules without an absolute path |
471 | [[ "${r}$_rule" != /* ]] && continue | |
472 | [[ -f ${r}$_rule ]] || continue | |
473 | _found="${r}$_rule" | |
474 | inst_rule_programs "$_found" | |
475 | inst_rule_group_owner "$_found" | |
476 | inst_rule_initqueue "$_found" | |
477 | inst_simple "$_found" "$_target/${_found##*/}" | |
478 | done | |
479 | [[ $_found ]] || dinfo "Skipping udev rule: $_rule" | |
480 | done | |
481 | } | |
482 | ||
483 | inst_rules_wildcard() { | |
484 | local _target=/etc/udev/rules.d _rule _found | |
485 | ||
486 | inst_dir "${udevdir}/rules.d" | |
487 | inst_dir "$_target" | |
488 | for _rule in ${udevdir}/rules.d/$1 ${dracutbasedir}/rules.d/$1 ; do | |
489 | [[ -e $_rule ]] || continue | |
490 | inst_rule_programs "$_rule" | |
491 | inst_rule_group_owner "$_rule" | |
492 | inst_rule_initqueue "$_rule" | |
493 | inst_simple "$_rule" | |
494 | _found=$_rule | |
495 | done | |
496 | if [[ -n ${hostonly} ]] ; then | |
497 | for _rule in ${_target}/$1 ; do | |
498 | [[ -f $_rule ]] || continue | |
499 | inst_rule_programs "$_rule" | |
500 | inst_rule_group_owner "$_rule" | |
501 | inst_rule_initqueue "$_rule" | |
502 | inst_simple "$_rule" | |
503 | _found=$_rule | |
504 | done | |
505 | fi | |
506 | [[ $_found ]] || dinfo "Skipping udev rule: $_rule" | |
507 | } | |
508 | ||
509 | prepare_udev_rules() { | |
994d0035 HH |
510 | if [ -z "$UDEVVERSION" ]; then |
511 | UDEVVERSION=$(udevadm --version) | |
512 | export UDEVVERSION | |
513 | fi | |
514 | ||
6e761674 MN |
515 | if [ -z "$UDEVVERSION" ]; then |
516 | derror "Failed to detect udev version!" | |
517 | return 1 | |
518 | fi | |
718aefda MN |
519 | if [ -z "${UDEVVERSION##*[!0-9]*}" ]; then |
520 | derror "udevadm --version did not report an integer, udev version cannot be determined!" | |
521 | return 1 | |
522 | fi | |
561eb42f HH |
523 | |
524 | for f in "$@"; do | |
525 | f="${initdir}/etc/udev/rules.d/$f" | |
526 | [ -e "$f" ] || continue | |
994d0035 | 527 | while read -r line || [ -n "$line" ]; do |
561eb42f | 528 | if [ "${line%%IMPORT PATH_ID}" != "$line" ]; then |
994d0035 | 529 | if (( UDEVVERSION >= 174 )); then |
561eb42f HH |
530 | printf '%sIMPORT{builtin}="path_id"\n' "${line%%IMPORT PATH_ID}" |
531 | else | |
532 | printf '%sIMPORT{program}="path_id %%p"\n' "${line%%IMPORT PATH_ID}" | |
533 | fi | |
534 | elif [ "${line%%IMPORT BLKID}" != "$line" ]; then | |
994d0035 | 535 | if (( UDEVVERSION >= 176 )); then |
561eb42f HH |
536 | printf '%sIMPORT{builtin}="blkid"\n' "${line%%IMPORT BLKID}" |
537 | else | |
994d0035 | 538 | # shellcheck disable=SC2016 |
561eb42f HH |
539 | printf '%sIMPORT{program}="/sbin/blkid -o udev -p $tempnode"\n' "${line%%IMPORT BLKID}" |
540 | fi | |
541 | else | |
542 | echo "$line" | |
543 | fi | |
544 | done < "${f}" > "${f}.new" | |
545 | mv "${f}.new" "$f" | |
546 | done | |
547 | } | |
548 | ||
549 | # install function specialized for hooks | |
550 | # $1 = type of hook, $2 = hook priority (lower runs first), $3 = hook | |
551 | # All hooks should be POSIX/SuS compliant, they will be sourced by init. | |
552 | inst_hook() { | |
553 | if ! [[ -f $3 ]]; then | |
554 | dfatal "Cannot install a hook ($3) that does not exist." | |
555 | dfatal "Aborting initrd creation." | |
556 | exit 1 | |
557 | elif ! [[ "$hookdirs" == *$1* ]]; then | |
558 | dfatal "No such hook type $1. Aborting initrd creation." | |
559 | exit 1 | |
560 | fi | |
561 | inst_simple "$3" "/lib/dracut/hooks/${1}/${2}-${3##*/}" | |
562 | } | |
563 | ||
564 | # install any of listed files | |
565 | # | |
566 | # If first argument is '-d' and second some destination path, first accessible | |
567 | # source is installed into this path, otherwise it will installed in the same | |
568 | # path as source. If none of listed files was installed, function return 1. | |
569 | # On first successful installation it returns with 0 status. | |
570 | # | |
571 | # Example: | |
572 | # | |
573 | # inst_any -d /bin/foo /bin/bar /bin/baz | |
574 | # | |
575 | # Lets assume that /bin/baz exists, so it will be installed as /bin/foo in | |
576 | # initramfs. | |
577 | inst_any() { | |
578 | local to f | |
579 | ||
580 | [[ $1 = '-d' ]] && to="$2" && shift 2 | |
581 | ||
582 | for f in "$@"; do | |
583 | [[ -e $f ]] || continue | |
584 | [[ $to ]] && inst "$f" "$to" && return 0 | |
585 | inst "$f" && return 0 | |
586 | done | |
587 | ||
588 | return 1 | |
589 | } | |
590 | ||
591 | ||
592 | # inst_libdir_file [-n <pattern>] <file> [<file>...] | |
593 | # Install a <file> located on a lib directory to the initramfs image | |
594 | # -n <pattern> install matching files | |
595 | inst_libdir_file() { | |
994d0035 | 596 | local -a _files |
561eb42f HH |
597 | if [[ "$1" == "-n" ]]; then |
598 | local _pattern=$2 | |
599 | shift 2 | |
600 | for _dir in $libdirs; do | |
601 | for _i in "$@"; do | |
b955dbf4 ZB |
602 | for _f in "$dracutsysrootdir$_dir"/$_i; do |
603 | [[ "${_f#$dracutsysrootdir}" =~ $_pattern ]] || continue | |
994d0035 | 604 | [[ -e "$_f" ]] && _files+=("${_f#$dracutsysrootdir}") |
561eb42f HH |
605 | done |
606 | done | |
607 | done | |
608 | else | |
609 | for _dir in $libdirs; do | |
610 | for _i in "$@"; do | |
b955dbf4 | 611 | for _f in "$dracutsysrootdir$_dir"/$_i; do |
994d0035 | 612 | [[ -e "$_f" ]] && _files+=("${_f#$dracutsysrootdir}") |
561eb42f HH |
613 | done |
614 | done | |
615 | done | |
616 | fi | |
994d0035 | 617 | [[ ${#_files[@]} -gt 0 ]] && inst_multiple "${_files[@]}" |
561eb42f HH |
618 | } |
619 | ||
3e53195b TI |
620 | # get a command to decompress the given file |
621 | get_decompress_cmd() { | |
622 | case "$1" in | |
623 | *.gz) echo 'gzip -f -d' ;; | |
624 | *.bz2) echo 'bzip2 -d' ;; | |
625 | *.xz) echo 'xz -f -d' ;; | |
626 | esac | |
627 | } | |
561eb42f HH |
628 | |
629 | # install function decompressing the target and handling symlinks | |
630 | # $@ = list of compressed (gz or bz2) files or symlinks pointing to such files | |
631 | # | |
632 | # Function install targets in the same paths inside overlay but decompressed | |
633 | # and without extensions (.gz, .bz2). | |
634 | inst_decompress() { | |
635 | local _src _cmd | |
636 | ||
994d0035 HH |
637 | for _src in "$@"; do |
638 | _cmd=$(get_decompress_cmd "${_src}") | |
3e53195b | 639 | [[ -z "${_cmd}" ]] && return 1 |
994d0035 | 640 | inst_simple "${_src}" |
561eb42f HH |
641 | # Decompress with chosen tool. We assume that tool changes name e.g. |
642 | # from 'name.gz' to 'name'. | |
643 | ${_cmd} "${initdir}${_src}" | |
644 | done | |
645 | } | |
646 | ||
647 | # It's similar to above, but if file is not compressed, performs standard | |
648 | # install. | |
649 | # $@ = list of files | |
650 | inst_opt_decompress() { | |
651 | local _src | |
652 | ||
994d0035 | 653 | for _src in "$@"; do |
561eb42f HH |
654 | inst_decompress "${_src}" || inst "${_src}" |
655 | done | |
656 | } | |
657 | ||
5916d31b | 658 | # module_check <dracut module> [<forced>] [<module path>] |
561eb42f HH |
659 | # execute the check() function of module-setup.sh of <dracut module> |
660 | # or the "check" script, if module-setup.sh is not found | |
661 | # "check $hostonly" is called | |
662 | module_check() { | |
5916d31b | 663 | local _moddir=$3 |
561eb42f HH |
664 | local _ret |
665 | local _forced=0 | |
666 | local _hostonly=$hostonly | |
5916d31b | 667 | [[ -z $_moddir ]] && _moddir=$(dracut_module_path "$1") |
561eb42f HH |
668 | [ $# -eq 2 ] && _forced=$2 |
669 | [[ -d $_moddir ]] || return 1 | |
670 | if [[ ! -f $_moddir/module-setup.sh ]]; then | |
671 | # if we do not have a check script, we are unconditionally included | |
672 | [[ -x $_moddir/check ]] || return 0 | |
994d0035 HH |
673 | [[ $_forced != 0 ]] && unset hostonly |
674 | # don't quote $hostonly to leave argument empty | |
675 | # shellcheck disable=SC2086 | |
676 | "$_moddir"/check $hostonly | |
561eb42f HH |
677 | _ret=$? |
678 | else | |
679 | unset check depends cmdline install installkernel | |
680 | check() { true; } | |
994d0035 | 681 | . "$_moddir"/module-setup.sh |
561eb42f | 682 | is_func check || return 0 |
994d0035 HH |
683 | [[ $_forced != 0 ]] && unset hostonly |
684 | # don't quote $hostonly to leave argument empty | |
685 | # shellcheck disable=SC2086 | |
686 | moddir="$_moddir" check $hostonly | |
561eb42f HH |
687 | _ret=$? |
688 | unset check depends cmdline install installkernel | |
689 | fi | |
690 | hostonly=$_hostonly | |
691 | return $_ret | |
692 | } | |
693 | ||
5916d31b | 694 | # module_check_mount <dracut module> [<module path>] |
561eb42f HH |
695 | # execute the check() function of module-setup.sh of <dracut module> |
696 | # or the "check" script, if module-setup.sh is not found | |
697 | # "mount_needs=1 check 0" is called | |
698 | module_check_mount() { | |
5916d31b | 699 | local _moddir=$2 |
561eb42f | 700 | local _ret |
994d0035 | 701 | export mount_needs=1 |
5916d31b | 702 | [[ -z $_moddir ]] && _moddir=$(dracut_module_path "$1") |
561eb42f HH |
703 | [[ -d $_moddir ]] || return 1 |
704 | if [[ ! -f $_moddir/module-setup.sh ]]; then | |
705 | # if we do not have a check script, we are unconditionally included | |
706 | [[ -x $_moddir/check ]] || return 0 | |
994d0035 | 707 | mount_needs=1 "$_moddir"/check 0 |
561eb42f HH |
708 | _ret=$? |
709 | else | |
710 | unset check depends cmdline install installkernel | |
711 | check() { false; } | |
994d0035 | 712 | . "$_moddir"/module-setup.sh |
561eb42f HH |
713 | moddir=$_moddir check 0 |
714 | _ret=$? | |
715 | unset check depends cmdline install installkernel | |
716 | fi | |
717 | unset mount_needs | |
994d0035 | 718 | return "$_ret" |
561eb42f HH |
719 | } |
720 | ||
5916d31b | 721 | # module_depends <dracut module> [<module path>] |
561eb42f HH |
722 | # execute the depends() function of module-setup.sh of <dracut module> |
723 | # or the "depends" script, if module-setup.sh is not found | |
724 | module_depends() { | |
5916d31b | 725 | local _moddir=$2 |
561eb42f | 726 | local _ret |
5916d31b | 727 | [[ -z $_moddir ]] && _moddir=$(dracut_module_path "$1") |
561eb42f HH |
728 | [[ -d $_moddir ]] || return 1 |
729 | if [[ ! -f $_moddir/module-setup.sh ]]; then | |
730 | # if we do not have a check script, we have no deps | |
731 | [[ -x $_moddir/check ]] || return 0 | |
cdb714c5 | 732 | "$_moddir"/check -d |
561eb42f HH |
733 | return $? |
734 | else | |
735 | unset check depends cmdline install installkernel | |
736 | depends() { true; } | |
cdb714c5 | 737 | . "$_moddir"/module-setup.sh |
561eb42f HH |
738 | moddir=$_moddir depends |
739 | _ret=$? | |
740 | unset check depends cmdline install installkernel | |
741 | return $_ret | |
742 | fi | |
743 | } | |
744 | ||
5916d31b | 745 | # module_cmdline <dracut module> [<module path>] |
561eb42f HH |
746 | # execute the cmdline() function of module-setup.sh of <dracut module> |
747 | # or the "cmdline" script, if module-setup.sh is not found | |
748 | module_cmdline() { | |
5916d31b | 749 | local _moddir=$2 |
561eb42f | 750 | local _ret |
5916d31b | 751 | [[ -z $_moddir ]] && _moddir=$(dracut_module_path "$1") |
561eb42f HH |
752 | [[ -d $_moddir ]] || return 1 |
753 | if [[ ! -f $_moddir/module-setup.sh ]]; then | |
754 | [[ -x $_moddir/cmdline ]] && . "$_moddir/cmdline" | |
755 | return $? | |
756 | else | |
757 | unset check depends cmdline install installkernel | |
758 | cmdline() { true; } | |
cdb714c5 HH |
759 | . "$_moddir"/module-setup.sh |
760 | moddir="$_moddir" cmdline | |
561eb42f HH |
761 | _ret=$? |
762 | unset check depends cmdline install installkernel | |
763 | return $_ret | |
764 | fi | |
765 | } | |
766 | ||
5916d31b | 767 | # module_install <dracut module> [<module path>] |
561eb42f HH |
768 | # execute the install() function of module-setup.sh of <dracut module> |
769 | # or the "install" script, if module-setup.sh is not found | |
770 | module_install() { | |
5916d31b | 771 | local _moddir=$2 |
561eb42f | 772 | local _ret |
5916d31b | 773 | [[ -z $_moddir ]] && _moddir=$(dracut_module_path "$1") |
561eb42f HH |
774 | [[ -d $_moddir ]] || return 1 |
775 | if [[ ! -f $_moddir/module-setup.sh ]]; then | |
776 | [[ -x $_moddir/install ]] && . "$_moddir/install" | |
777 | return $? | |
778 | else | |
779 | unset check depends cmdline install installkernel | |
780 | install() { true; } | |
cdb714c5 HH |
781 | . "$_moddir"/module-setup.sh |
782 | moddir="$_moddir" install | |
561eb42f HH |
783 | _ret=$? |
784 | unset check depends cmdline install installkernel | |
785 | return $_ret | |
786 | fi | |
787 | } | |
788 | ||
5916d31b | 789 | # module_installkernel <dracut module> [<module path>] |
561eb42f HH |
790 | # execute the installkernel() function of module-setup.sh of <dracut module> |
791 | # or the "installkernel" script, if module-setup.sh is not found | |
792 | module_installkernel() { | |
5916d31b | 793 | local _moddir=$2 |
561eb42f | 794 | local _ret |
5916d31b | 795 | [[ -z $_moddir ]] && _moddir=$(dracut_module_path "$1") |
561eb42f HH |
796 | [[ -d $_moddir ]] || return 1 |
797 | if [[ ! -f $_moddir/module-setup.sh ]]; then | |
798 | [[ -x $_moddir/installkernel ]] && . "$_moddir/installkernel" | |
799 | return $? | |
800 | else | |
801 | unset check depends cmdline install installkernel | |
802 | installkernel() { true; } | |
cdb714c5 HH |
803 | . "$_moddir"/module-setup.sh |
804 | moddir="$_moddir" installkernel | |
561eb42f HH |
805 | _ret=$? |
806 | unset check depends cmdline install installkernel | |
807 | return $_ret | |
808 | fi | |
809 | } | |
810 | ||
5916d31b | 811 | # check_mount <dracut module> [<use_as_dep>] [<module path>] |
561eb42f HH |
812 | # check_mount checks, if a dracut module is needed for the given |
813 | # device and filesystem types in "${host_fs_types[@]}" | |
814 | check_mount() { | |
815 | local _mod=$1 | |
5916d31b | 816 | local _moddir=$3 |
561eb42f HH |
817 | local _ret |
818 | local _moddep | |
819 | ||
5916d31b | 820 | [[ -z $_moddir ]] && _moddir=$(dracut_module_path "$1") |
cdb714c5 | 821 | # shellcheck disable=SC2154 |
561eb42f HH |
822 | [ "${#host_fs_types[@]}" -le 0 ] && return 1 |
823 | ||
824 | # If we are already scheduled to be loaded, no need to check again. | |
825 | [[ " $mods_to_load " == *\ $_mod\ * ]] && return 0 | |
826 | [[ " $mods_checked_as_dep " == *\ $_mod\ * ]] && return 1 | |
827 | ||
828 | # This should never happen, but... | |
829 | [[ -d $_moddir ]] || return 1 | |
830 | ||
831 | [[ $2 ]] || mods_checked_as_dep+=" $_mod " | |
832 | ||
cdb714c5 | 833 | # shellcheck disable=SC2154 |
561eb42f HH |
834 | if [[ " $omit_dracutmodules " == *\ $_mod\ * ]]; then |
835 | return 1 | |
836 | fi | |
837 | ||
838 | if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\ $_mod\ * ]]; then | |
cdb714c5 | 839 | module_check_mount "$_mod" "$_moddir"; ret=$? |
561eb42f HH |
840 | |
841 | # explicit module, so also accept ret=255 | |
842 | [[ $ret = 0 || $ret = 255 ]] || return 1 | |
843 | else | |
844 | # module not in our list | |
845 | if [[ $dracutmodules = all ]]; then | |
846 | # check, if we can and should install this module | |
cdb714c5 | 847 | module_check_mount "$_mod" "$_moddir" || return 1 |
561eb42f HH |
848 | else |
849 | # skip this module | |
850 | return 1 | |
851 | fi | |
852 | fi | |
853 | ||
cdb714c5 | 854 | for _moddep in $(module_depends "$_mod" "$_moddir"); do |
561eb42f HH |
855 | # handle deps as if they were manually added |
856 | [[ " $dracutmodules " == *\ $_mod\ * ]] \ | |
857 | && [[ " $dracutmodules " != *\ $_moddep\ * ]] \ | |
858 | && dracutmodules+=" $_moddep " | |
859 | [[ " $add_dracutmodules " == *\ $_mod\ * ]] \ | |
860 | && [[ " $add_dracutmodules " != *\ $_moddep\ * ]] \ | |
861 | && add_dracutmodules+=" $_moddep " | |
862 | [[ " $force_add_dracutmodules " == *\ $_mod\ * ]] \ | |
863 | && [[ " $force_add_dracutmodules " != *\ $_moddep\ * ]] \ | |
864 | && force_add_dracutmodules+=" $_moddep " | |
865 | # if a module we depend on fail, fail also | |
cdb714c5 | 866 | if ! check_module "$_moddep"; then |
561eb42f HH |
867 | derror "dracut module '$_mod' depends on '$_moddep', which can't be installed" |
868 | return 1 | |
869 | fi | |
870 | done | |
871 | ||
872 | [[ " $mods_to_load " == *\ $_mod\ * ]] || \ | |
873 | mods_to_load+=" $_mod " | |
874 | ||
875 | return 0 | |
876 | } | |
877 | ||
5916d31b | 878 | # check_module <dracut module> [<use_as_dep>] [<module path>] |
561eb42f HH |
879 | # check if a dracut module is to be used in the initramfs process |
880 | # if <use_as_dep> is set, then the process also keeps track | |
881 | # that the modules were checked for the dependency tracking process | |
882 | check_module() { | |
883 | local _mod=$1 | |
5916d31b | 884 | local _moddir=$3 |
561eb42f HH |
885 | local _ret |
886 | local _moddep | |
5916d31b KS |
887 | |
888 | [[ -z $_moddir ]] && _moddir=$(dracut_module_path "$1") | |
561eb42f HH |
889 | # If we are already scheduled to be loaded, no need to check again. |
890 | [[ " $mods_to_load " == *\ $_mod\ * ]] && return 0 | |
891 | [[ " $mods_checked_as_dep " == *\ $_mod\ * ]] && return 1 | |
892 | ||
893 | # This should never happen, but... | |
894 | [[ -d $_moddir ]] || return 1 | |
895 | ||
896 | [[ $2 ]] || mods_checked_as_dep+=" $_mod " | |
897 | ||
898 | if [[ " $omit_dracutmodules " == *\ $_mod\ * ]]; then | |
6b8ee4fc | 899 | ddebug "dracut module '$_mod' will not be installed, because it's in the list to be omitted!" |
561eb42f HH |
900 | return 1 |
901 | fi | |
902 | ||
903 | if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\ $_mod\ * ]]; then | |
904 | if [[ " $dracutmodules $force_add_dracutmodules " == *\ $_mod\ * ]]; then | |
cdb714c5 | 905 | module_check "$_mod" 1 "$_moddir"; ret=$? |
561eb42f | 906 | else |
cdb714c5 | 907 | module_check "$_mod" 0 "$_moddir"; ret=$? |
561eb42f HH |
908 | fi |
909 | # explicit module, so also accept ret=255 | |
910 | [[ $ret = 0 || $ret = 255 ]] || return 1 | |
911 | else | |
912 | # module not in our list | |
913 | if [[ $dracutmodules = all ]]; then | |
914 | # check, if we can and should install this module | |
cdb714c5 | 915 | module_check "$_mod" 0 "$_moddir"; ret=$? |
561eb42f HH |
916 | if [[ $ret != 0 ]]; then |
917 | [[ $2 ]] && return 1 | |
918 | [[ $ret != 255 ]] && return 1 | |
919 | fi | |
920 | else | |
921 | # skip this module | |
922 | return 1 | |
923 | fi | |
924 | fi | |
925 | ||
ad64c686 | 926 | for _moddep in $(module_depends "$_mod" "$_moddir"); do |
561eb42f HH |
927 | # handle deps as if they were manually added |
928 | [[ " $dracutmodules " == *\ $_mod\ * ]] \ | |
929 | && [[ " $dracutmodules " != *\ $_moddep\ * ]] \ | |
930 | && dracutmodules+=" $_moddep " | |
931 | [[ " $add_dracutmodules " == *\ $_mod\ * ]] \ | |
932 | && [[ " $add_dracutmodules " != *\ $_moddep\ * ]] \ | |
933 | && add_dracutmodules+=" $_moddep " | |
934 | [[ " $force_add_dracutmodules " == *\ $_mod\ * ]] \ | |
935 | && [[ " $force_add_dracutmodules " != *\ $_moddep\ * ]] \ | |
936 | && force_add_dracutmodules+=" $_moddep " | |
937 | # if a module we depend on fail, fail also | |
ad64c686 | 938 | if ! check_module "$_moddep"; then |
561eb42f HH |
939 | derror "dracut module '$_mod' depends on '$_moddep', which can't be installed" |
940 | return 1 | |
941 | fi | |
942 | done | |
943 | ||
944 | [[ " $mods_to_load " == *\ $_mod\ * ]] || \ | |
945 | mods_to_load+=" $_mod " | |
946 | ||
947 | return 0 | |
948 | } | |
949 | ||
950 | # for_each_module_dir <func> | |
5916d31b | 951 | # execute "<func> <dracut module> 1 <module path>" |
561eb42f HH |
952 | for_each_module_dir() { |
953 | local _modcheck | |
954 | local _mod | |
955 | local _moddir | |
956 | local _func | |
957 | _func=$1 | |
958 | for _moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do | |
959 | [[ -d $_moddir ]] || continue; | |
960 | [[ -e $_moddir/install || -e $_moddir/installkernel || \ | |
961 | -e $_moddir/module-setup.sh ]] || continue | |
962 | _mod=${_moddir##*/}; _mod=${_mod#[0-9][0-9]} | |
ad64c686 | 963 | $_func "$_mod" 1 "$_moddir" |
561eb42f HH |
964 | done |
965 | ||
966 | # Report any missing dracut modules, the user has specified | |
967 | _modcheck="$add_dracutmodules $force_add_dracutmodules" | |
968 | [[ $dracutmodules != all ]] && _modcheck="$_modcheck $dracutmodules" | |
969 | for _mod in $_modcheck; do | |
970 | [[ " $mods_to_load " == *\ $_mod\ * ]] && continue | |
971 | ||
972 | [[ " $force_add_dracutmodules " != *\ $_mod\ * ]] \ | |
973 | && [[ " $dracutmodules " != *\ $_mod\ * ]] \ | |
974 | && [[ " $omit_dracutmodules " == *\ $_mod\ * ]] \ | |
975 | && continue | |
976 | ||
977 | derror "dracut module '$_mod' cannot be found or installed." | |
978 | [[ " $force_add_dracutmodules " == *\ $_mod\ * ]] && exit 1 | |
979 | [[ " $dracutmodules " == *\ $_mod\ * ]] && exit 1 | |
980 | [[ " $add_dracutmodules " == *\ $_mod\ * ]] && exit 1 | |
981 | done | |
982 | } | |
983 | ||
561eb42f | 984 | dracut_kernel_post() { |
561eb42f | 985 | for _f in modules.builtin.bin modules.builtin modules.order; do |
3aa37caf | 986 | [[ -e $srcmods/$_f ]] && inst_simple "$srcmods/$_f" "/lib/modules/$kernel/$_f" |
561eb42f HH |
987 | done |
988 | ||
989 | # generate module dependencies for the initrd | |
990 | if [[ -d $initdir/lib/modules/$kernel ]] && \ | |
ad64c686 | 991 | ! depmod -a -b "$initdir" "$kernel"; then |
561eb42f HH |
992 | dfatal "\"depmod -a $kernel\" failed." |
993 | exit 1 | |
994 | fi | |
995 | ||
561eb42f HH |
996 | } |
997 | ||
561eb42f | 998 | instmods() { |
794b2d2c HH |
999 | # instmods [-c [-s]] <kernel module> [<kernel module> ... ] |
1000 | # instmods [-c [-s]] <kernel subsystem> | |
1001 | # install kernel modules along with all their dependencies. | |
1002 | # <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage" | |
1003 | # -c check | |
1004 | # -s silent | |
1005 | local _optional="-o" | |
1006 | local _silent | |
1007 | local _ret | |
9bb030c5 | 1008 | |
561eb42f | 1009 | [[ $no_kernel = yes ]] && return |
9bb030c5 | 1010 | |
561eb42f | 1011 | if [[ $1 = '-c' ]]; then |
9bb030c5 | 1012 | unset _optional |
561eb42f HH |
1013 | shift |
1014 | fi | |
561eb42f | 1015 | if [[ $1 = '-s' ]]; then |
794b2d2c | 1016 | _silent=1 |
561eb42f HH |
1017 | shift |
1018 | fi | |
9bb030c5 | 1019 | |
794b2d2c HH |
1020 | if (($# == 0)); then |
1021 | read -r -d '' -a args | |
1022 | set -- "${args[@]}" | |
1023 | fi | |
9bb030c5 | 1024 | |
8f773264 HH |
1025 | if (($# == 0)); then |
1026 | return 0 | |
1027 | fi | |
1028 | ||
ad64c686 | 1029 | "$DRACUT_INSTALL" \ |
9bb030c5 | 1030 | ${initdir:+-D "$initdir"} \ |
a0120420 | 1031 | ${dracutsysrootdir:+-r "$dracutsysrootdir"} \ |
9bb030c5 HH |
1032 | ${loginstall:+-L "$loginstall"} \ |
1033 | ${hostonly:+-H} \ | |
1034 | ${omit_drivers:+-N "$omit_drivers"} \ | |
1035 | ${srcmods:+--kerneldir "$srcmods"} \ | |
1036 | ${_optional:+-o} \ | |
1037 | ${_silent:+--silent} \ | |
1038 | -m "$@" | |
561eb42f | 1039 | _ret=$? |
9bb030c5 | 1040 | |
ad64c686 | 1041 | if ((_ret != 0)) && [[ -z "$_silent" ]]; then |
9bb030c5 | 1042 | derror "FAILED: " \ |
ad64c686 | 1043 | "$DRACUT_INSTALL" \ |
9bb030c5 | 1044 | ${initdir:+-D "$initdir"} \ |
a0120420 | 1045 | ${dracutsysrootdir:+-r "$dracutsysrootdir"} \ |
9bb030c5 HH |
1046 | ${loginstall:+-L "$loginstall"} \ |
1047 | ${hostonly:+-H} \ | |
1048 | ${omit_drivers:+-N "$omit_drivers"} \ | |
1049 | ${srcmods:+--kerneldir "$srcmods"} \ | |
1050 | ${_optional:+-o} \ | |
1051 | ${_silent:+--silent} \ | |
1052 | -m "$@" | |
1053 | fi | |
1054 | ||
794b2d2c | 1055 | [[ "$optional" ]] && return 0 |
561eb42f HH |
1056 | return $_ret |
1057 | } | |
19015001 HH |
1058 | |
1059 | if [[ "$(ln --help)" == *--relative* ]]; then | |
1060 | ln_r() { | |
1061 | ln -sfnr "${initdir}/$1" "${initdir}/$2" | |
1062 | } | |
1063 | else | |
1064 | ln_r() { | |
1065 | local _source=$1 | |
1066 | local _dest=$2 | |
1067 | [[ -d "${_dest%/*}" ]] && _dest=$(readlink -f "${_dest%/*}")/${_dest##*/} | |
1068 | ln -sfn -- "$(convert_abs_rel "${_dest}" "${_source}")" "${initdir}/${_dest}" | |
1069 | } | |
1070 | fi | |
b6b1bf92 DM |
1071 | |
1072 | is_qemu_virtualized() { | |
1073 | # 0 if a virt environment was detected | |
1074 | # 1 if a virt environment could not be detected | |
1075 | # 255 if any error was encountered | |
1076 | if type -P systemd-detect-virt >/dev/null 2>&1; then | |
ad64c686 HH |
1077 | if ! vm=$(systemd-detect-virt --vm >/dev/null 2>&1); then |
1078 | return 255 | |
1079 | fi | |
b6b1bf92 DM |
1080 | [[ $vm = "qemu" ]] && return 0 |
1081 | [[ $vm = "kvm" ]] && return 0 | |
1082 | [[ $vm = "bochs" ]] && return 0 | |
1083 | fi | |
1084 | ||
1085 | for i in /sys/class/dmi/id/*_vendor; do | |
1086 | [[ -f $i ]] || continue | |
ad64c686 | 1087 | read -r vendor < "$i" |
b6b1bf92 DM |
1088 | [[ "$vendor" == "QEMU" ]] && return 0 |
1089 | [[ "$vendor" == "Red Hat" ]] && return 0 | |
1090 | [[ "$vendor" == "Bochs" ]] && return 0 | |
1091 | done | |
1092 | return 1 | |
6e761674 | 1093 | } |