]> git.ipfire.org Git - thirdparty/dracut.git/blame - dracut-functions.sh
ifcfg: only bind to HWADDR, if addr_assign_type == 0
[thirdparty/dracut.git] / dracut-functions.sh
CommitLineData
04b56f3a 1#!/bin/bash
cc02093d
HH
2# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3# ex: ts=8 sw=4 sts=4 et filetype=sh
04b56f3a 4#
33ee031c 5# functions used by dracut and other tools.
04b56f3a 6#
33ee031c 7# Copyright 2005-2009 Red Hat, Inc. All rights reserved.
04b56f3a
JK
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
0f9c78c1 20# along with this program. If not, see <http://www.gnu.org/licenses/>.
04b56f3a 21#
258de828 22export LC_MESSAGES=C
f4031e8a
HH
23
24if [[ $DRACUT_KERNEL_LAZY ]] && ! [[ $DRACUT_KERNEL_LAZY_HASHDIR ]]; then
25 if ! [[ -d "$initdir/.kernelmodseen" ]]; then
26 mkdir -p "$initdir/.kernelmodseen"
27 fi
28 DRACUT_KERNEL_LAZY_HASHDIR="$initdir/.kernelmodseen"
29fi
ec1aa3bc 30
eaa924b6
HH
31if [[ $initdir ]] && ! [[ -d $initdir ]]; then
32 mkdir -p "$initdir"
33fi
34
8d95b8b3 35# Generic substring function. If $2 is in $1, return 0.
520047c3 36strstr() { [[ $1 = *$2* ]]; }
8d95b8b3 37
30e6e809
HH
38# helper function for check() in module-setup.sh
39# to check for required installed binaries
40# issues a standardized warning message
41require_binaries() {
42 local _module_name="${moddir##*/}"
43 local _ret=0
44
45 if [[ "$1" = "-m" ]]; then
46 _module_name="$2"
47 shift 2
48 fi
49
50 for cmd in "$@"; do
51 if ! find_binary "$cmd" &>/dev/null; then
83a3cba7 52 dinfo "$_module_name: Could not find command '$cmd'!"
30e6e809
HH
53 ((_ret++))
54 fi
55 done
56 return $_ret
57}
58
59require_any_binary() {
60 local _module_name="${moddir##*/}"
61 local _ret=1
62
63 if [[ "$1" = "-m" ]]; then
64 _module_name="$2"
65 shift 2
66 fi
67
68 for cmd in "$@"; do
69 if find_binary "$cmd" &>/dev/null; then
70 _ret=0
71 break
72 fi
73 done
74
75 if (( $_ret != 0 )); then
83a3cba7 76 dinfo "$_module_name: Could not find any command of '$@'!"
30e6e809
HH
77 return 1
78 fi
79
80 return 0
81}
82
f4031e8a
HH
83# find a binary. If we were not passed the full path directly,
84# search in the usual places to find the binary.
85find_binary() {
86 if [[ -z ${1##/*} ]]; then
b093aa2d
HH
87 if [[ -x $1 ]] || { [[ "$1" == *.so* ]] && ldd "$1" &>/dev/null; }; then
88 printf "%s\n" "$1"
f4031e8a
HH
89 return 0
90 fi
91 fi
92
b093aa2d 93 type -P "${1##*/}"
f4031e8a
HH
94}
95
0874654c
HH
96if ! [[ $dracutbasedir ]]; then
97 dracutbasedir=${BASH_SOURCE[0]%/*}
98 [[ $dracutbasedir = "dracut-functions" ]] && dracutbasedir="."
99 [[ $dracutbasedir ]] || dracutbasedir="."
100 dracutbasedir="$(readlink -f $dracutbasedir)"
101fi
102
4fe1bdd4
HH
103ldconfig_paths()
104{
105 local a i
106 declare -A a
107 for i in $(
108 ldconfig -pN 2>/dev/null | while read a b c d; do
109 [[ "$c" != "=>" ]] && continue
466a5998 110 printf "%s\n" ${d%/*};
4fe1bdd4
HH
111 done
112 ); do
1d50dfe6 113 [[ "$i" = "/lib" || "$i" = "/usr/lib" || "$i" = "/lib64" || "$i" = "/usr/lib64" ]] && continue
4fe1bdd4
HH
114 a["$i"]=1;
115 done;
116 printf "%s\n" ${!a[@]}
117}
118
8d95b8b3
HH
119# Detect lib paths
120if ! [[ $libdirs ]] ; then
b093aa2d 121 if [[ "$(ldd /bin/sh)" == */lib64/* ]] &>/dev/null \
8d95b8b3
HH
122 && [[ -d /lib64 ]]; then
123 libdirs+=" /lib64"
124 [[ -d /usr/lib64 ]] && libdirs+=" /usr/lib64"
125 else
126 libdirs+=" /lib"
127 [[ -d /usr/lib ]] && libdirs+=" /usr/lib"
128 fi
4fe1bdd4 129
1d50dfe6 130 libdirs+=" $(ldconfig_paths)"
4fe1bdd4 131
8d95b8b3
HH
132 export libdirs
133fi
134
135if ! [[ $kernel ]]; then
136 kernel=$(uname -r)
137 export kernel
138fi
139
f06c2b58
HH
140# Version comparision function. Assumes Linux style version scheme.
141# $1 = version a
142# $2 = comparision op (gt, ge, eq, le, lt, ne)
143# $3 = version b
144vercmp() {
145 local _n1=(${1//./ }) _op=$2 _n2=(${3//./ }) _i _res
146
147 for ((_i=0; ; _i++))
148 do
149 if [[ ! ${_n1[_i]}${_n2[_i]} ]]; then _res=0
150 elif ((${_n1[_i]:-0} > ${_n2[_i]:-0})); then _res=1
151 elif ((${_n1[_i]:-0} < ${_n2[_i]:-0})); then _res=2
152 else continue
153 fi
154 break
155 done
156
157 case $_op in
158 gt) ((_res == 1));;
159 ge) ((_res != 2));;
160 eq) ((_res == 0));;
161 le) ((_res != 1));;
162 lt) ((_res == 2));;
163 ne) ((_res != 0));;
164 esac
165}
166
8d95b8b3 167srcmods="/lib/modules/$kernel/"
f06c2b58 168
8d95b8b3 169[[ $drivers_dir ]] && {
f06c2b58 170 if ! command -v kmod &>/dev/null && vercmp "$(modprobe --version | cut -d' ' -f3)" lt 3.7; then
8d95b8b3
HH
171 dfatal 'To use --kmoddir option module-init-tools >= 3.7 is required.'
172 exit 1
173 fi
174 srcmods="$drivers_dir"
175}
176export srcmods
177
d6d53f60 178if ! type dinfo >/dev/null 2>&1; then
552ecca6 179 . "$dracutbasedir/dracut-logger.sh"
e103615b
180 dlog_init
181fi
182
593b315c
HH
183if ! [[ $initdir ]]; then
184 dfatal "initdir not set"
185 exit 1
186fi
187
7e2bca48
HH
188# export standard hookdirs
189[[ $hookdirs ]] || {
4fed3ddf 190 hookdirs="cmdline pre-udev pre-trigger netroot "
6e3cc00f 191 hookdirs+="initqueue initqueue/settled initqueue/online initqueue/finished initqueue/timeout "
eef7649e 192 hookdirs+="pre-mount pre-pivot cleanup mount "
2b6dd6a1 193 hookdirs+="emergency shutdown-emergency pre-shutdown shutdown "
7e2bca48
HH
194 export hookdirs
195}
196
8d85429a
HH
197dracut_need_initqueue() {
198 >"$initdir/lib/dracut/need-initqueue"
199}
200
201dracut_module_included() {
50411d30 202 [[ " $mods_to_load $modules_loaded " == *\ $*\ * ]]
8d85429a
HH
203}
204
87122afc
205# Create all subdirectories for given path without creating the last element.
206# $1 = path
b093aa2d
HH
207mksubdirs() {
208 [[ -e ${1%/*} ]] || mkdir -m 0755 -p -- "${1%/*}"
209}
87122afc 210
7e2bca48
HH
211# is_func <command>
212# Check whether $1 is a function.
95d2dabc 213is_func() {
b093aa2d 214 [[ "$(type -t "$1")" = "function" ]]
95d2dabc
HH
215}
216
87122afc
217# Function prints global variables in format name=value line by line.
218# $@ = list of global variables' name
219print_vars() {
29b10e65 220 local _var _value
87122afc 221
b093aa2d 222 for _var in "$@"
87122afc 223 do
b093aa2d
HH
224 eval printf -v _value "%s" "\$$_var"
225 [[ ${_value} ]] && printf '%s="%s"\n' "$_var" "$_value"
87122afc
226 done
227}
228
7e2bca48
HH
229# normalize_path <path>
230# Prints the normalized path, where it removes any duplicated
231# and trailing slashes.
232# Example:
233# $ normalize_path ///test/test//
234# /test/test
626d9eba 235normalize_path() {
c44e3cb4
MS
236 shopt -q -s extglob
237 set -- "${1//+(\/)//}"
238 shopt -q -u extglob
466a5998 239 printf "%s\n" "${1%/}"
626d9eba 240}
d4bb4316 241
7e2bca48
HH
242# convert_abs_rel <from> <to>
243# Prints the relative path, when creating a symlink to <to> from <from>.
244# Example:
245# $ convert_abs_rel /usr/bin/test /bin/test-2
246# ../../bin/test-2
247# $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test
d4bb4316 248convert_abs_rel() {
6d2a7942 249 local __current __absolute __abssize __cursize __newpath
c44e3cb4 250 local -i __i __level
d4bb4316 251
c44e3cb4
MS
252 set -- "$(normalize_path "$1")" "$(normalize_path "$2")"
253
c1609dd4 254 # corner case #1 - self looping link
466a5998 255 [[ "$1" == "$2" ]] && { printf "%s\n" "${1##*/}"; return; }
c1609dd4
MS
256
257 # corner case #2 - own dir link
466a5998 258 [[ "${1%/*}" == "$2" ]] && { printf ".\n"; return; }
c1609dd4 259
6d2a7942
HH
260 IFS="/" __current=($1)
261 IFS="/" __absolute=($2)
d4bb4316
HH
262
263 __abssize=${#__absolute[@]}
264 __cursize=${#__current[@]}
265
b093aa2d 266 while [[ "${__absolute[__level]}" == "${__current[__level]}" ]]
d4bb4316
HH
267 do
268 (( __level++ ))
269 if (( __level > __abssize || __level > __cursize ))
270 then
271 break
272 fi
273 done
274
275 for ((__i = __level; __i < __cursize-1; __i++))
276 do
277 if ((__i > __level))
278 then
279 __newpath=$__newpath"/"
280 fi
281 __newpath=$__newpath".."
282 done
283
284 for ((__i = __level; __i < __abssize; __i++))
285 do
286 if [[ -n $__newpath ]]
287 then
288 __newpath=$__newpath"/"
289 fi
290 __newpath=$__newpath${__absolute[__i]}
291 done
292
466a5998 293 printf "%s\n" "$__newpath"
d4bb4316
HH
294}
295
b093aa2d 296if [[ "$(ln --help)" == *--relative* ]]; then
a20d24de
HH
297 ln_r() {
298 ln -sfnr "${initdir}/$1" "${initdir}/$2"
299 }
300else
301 ln_r() {
302 local _source=$1
303 local _dest=$2
304 [[ -d "${_dest%/*}" ]] && _dest=$(readlink -f "${_dest%/*}")/${_dest##*/}
b093aa2d 305 ln -sfn -- "$(convert_abs_rel "${_dest}" "${_source}")" "${initdir}/${_dest}"
a20d24de
HH
306 }
307fi
308
7e2bca48 309# get_fs_env <device>
97af51db 310# Get and the ID_FS_TYPE variable from udev for a device.
7e2bca48 311# Example:
97af51db 312# $ get_fs_env /dev/sda2
7e2bca48 313# ext4
9ede1929 314get_fs_env() {
0e979d48
HH
315 local evalstr
316 local found
317
7c179686 318 [[ $1 ]] || return
29b10e65 319 unset ID_FS_TYPE
69f7ed96
HH
320 ID_FS_TYPE=$(blkid -u filesystem -o export -- "$1" \
321 | while read line; do
322 if [[ "$line" == TYPE\=* ]]; then
323 printf "%s" "${line#TYPE=}";
324 exit 0;
325 fi
326 done)
327 if [[ $ID_FS_TYPE ]]; then
328 printf "%s" "$ID_FS_TYPE"
329 return 0
7c179686 330 fi
a5cde2dd
HH
331 return 1
332}
9ede1929 333
7e2bca48
HH
334# get_maj_min <device>
335# Prints the major and minor of a device node.
336# Example:
337# $ get_maj_min /dev/sda2
338# 8:2
480d772f 339get_maj_min() {
dba20559
HH
340 local _maj _min _majmin
341 _majmin="$(stat -L -c '%t:%T' "$1" 2>/dev/null)"
342 printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))"
480d772f
HH
343}
344
281327f7
HH
345
346# get_devpath_block <device>
347# get the DEVPATH in /sys of a block device
348get_devpath_block() {
8552a327 349 local _majmin _i
281327f7
HH
350 _majmin=$(get_maj_min "$1")
351
352 for _i in /sys/block/*/dev /sys/block/*/*/dev; do
353 [[ -e "$_i" ]] || continue
354 if [[ "$_majmin" == "$(<"$_i")" ]]; then
355 printf "%s" "${_i%/dev}"
356 return 0
357 fi
358 done
359 return 1
360}
361
69f7ed96
HH
362# get a persistent path from a device
363get_persistent_dev() {
364 local i _tmp _dev
365
366 _dev=$(get_maj_min "$1")
367 [ -z "$_dev" ] && return
368
324ea606
HH
369 for i in \
370 /dev/mapper/* \
3411ad66 371 /dev/disk/${persistent_policy:-by-uuid}/* \
324ea606
HH
372 /dev/disk/by-uuid/* \
373 /dev/disk/by-label/* \
374 /dev/disk/by-partuuid/* \
375 /dev/disk/by-partlabel/* \
376 /dev/disk/by-id/* \
377 /dev/disk/by-path/* \
378 ; do
2b9d8f65 379 [[ -e "$i" ]] || continue
1743473b 380 [[ $i == /dev/mapper/control ]] && continue
69f7ed96
HH
381 [[ $i == /dev/mapper/mpath* ]] && continue
382 _tmp=$(get_maj_min "$i")
383 if [ "$_tmp" = "$_dev" ]; then
384 printf -- "%s" "$i"
385 return
386 fi
387 done
388}
389
c82a1133
HH
390expand_persistent_dev() {
391 local _dev=$1
392
393 case "$_dev" in
394 LABEL=*)
395 _dev="/dev/disk/by-label/${_dev#LABEL=}"
396 ;;
397 UUID=*)
398 _dev="${_dev#UUID=}"
93b02f50 399 _dev="${_dev,,}"
c82a1133
HH
400 _dev="/dev/disk/by-uuid/${_dev}"
401 ;;
402 PARTUUID=*)
403 _dev="${_dev#PARTUUID=}"
93b02f50 404 _dev="${_dev,,}"
c82a1133
HH
405 _dev="/dev/disk/by-partuuid/${_dev}"
406 ;;
407 PARTLABEL=*)
408 _dev="/dev/disk/by-partlabel/${_dev#PARTLABEL=}"
409 ;;
410 esac
411 printf "%s" "$_dev"
412}
413
324ea606 414shorten_persistent_dev() {
c82a1133
HH
415 local _dev="$1"
416 case "$_dev" in
324ea606 417 /dev/disk/by-uuid/*)
c82a1133 418 printf "%s" "UUID=${_dev##*/}";;
324ea606 419 /dev/disk/by-label/*)
c82a1133 420 printf "%s" "LABEL=${_dev##*/}";;
324ea606 421 /dev/disk/by-partuuid/*)
c82a1133 422 printf "%s" "PARTUUID=${_dev##*/}";;
324ea606 423 /dev/disk/by-partlabel/*)
c82a1133 424 printf "%s" "PARTLABEL=${_dev##*/}";;
324ea606 425 *)
c82a1133 426 printf "%s" "$_dev";;
324ea606
HH
427 esac
428}
429
7e2bca48
HH
430# find_block_device <mountpoint>
431# Prints the major and minor number of the block device
432# for a given mountpoint.
433# Unless $use_fstab is set to "yes" the functions
434# uses /proc/self/mountinfo as the primary source of the
435# information and only falls back to /etc/fstab, if the mountpoint
436# is not found there.
437# Example:
438# $ find_block_device /usr
439# 8:4
f76ef3aa 440find_block_device() {
9d36d4fb 441 local _majmin _dev _majmin _find_mpt
c8d685c9 442 _find_mpt="$1"
0b706743 443 if [[ $use_fstab != yes ]]; then
9d36d4fb 444 [[ -d $_find_mpt/. ]]
dba20559
HH
445 findmnt -e -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" | { \
446 while read _majmin _dev; do
447 if [[ -b $_dev ]]; then
448 if ! [[ $_majmin ]] || [[ $_majmin == 0:* ]]; then
449 _majmin=$(get_maj_min $_dev)
450 fi
451 if [[ $_majmin ]]; then
466a5998 452 printf "%s\n" "$_majmin"
dba20559 453 else
466a5998 454 printf "%s\n" "$_dev"
dba20559
HH
455 fi
456 return 0
457 fi
458 if [[ $_dev = *:* ]]; then
466a5998 459 printf "%s\n" "$_dev"
dba20559
HH
460 return 0
461 fi
462 done; return 1; } && return 0
463 fi
464 # fall back to /etc/fstab
465
466 findmnt -e --fstab -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" | { \
9d36d4fb 467 while read _majmin _dev; do
dba20559
HH
468 if ! [[ $_dev ]]; then
469 _dev="$_majmin"
470 unset _majmin
471 fi
9d36d4fb 472 if [[ -b $_dev ]]; then
dba20559 473 [[ $_majmin ]] || _majmin=$(get_maj_min $_dev)
9d36d4fb 474 if [[ $_majmin ]]; then
466a5998 475 printf "%s\n" "$_majmin"
9d36d4fb 476 else
466a5998 477 printf "%s\n" "$_dev"
9d36d4fb
HH
478 fi
479 return 0
480 fi
481 if [[ $_dev = *:* ]]; then
466a5998 482 printf "%s\n" "$_dev"
9d36d4fb 483 return 0
cc02093d 484 fi
dba20559 485 done; return 1; } && return 0
0b706743
486
487 return 1
17829e94
VL
488}
489
9d36d4fb
HH
490# find_mp_fstype <mountpoint>
491# Echo the filesystem type for a given mountpoint.
7e2bca48
HH
492# /proc/self/mountinfo is taken as the primary source of information
493# and /etc/fstab is used as a fallback.
494# No newline is appended!
495# Example:
9d36d4fb 496# $ find_mp_fstype /;echo
7e2bca48 497# ext4
9d36d4fb
HH
498find_mp_fstype() {
499 local _fs
7ae5d9d1 500
9d36d4fb 501 if [[ $use_fstab != yes ]]; then
dba20559
HH
502 findmnt -e -v -n -o 'FSTYPE' --target "$1" | { \
503 while read _fs; do
504 [[ $_fs ]] || continue
505 [[ $_fs = "autofs" ]] && continue
466a5998 506 printf "%s" "$_fs"
dba20559
HH
507 return 0
508 done; return 1; } && return 0
509 fi
510
511 findmnt --fstab -e -v -n -o 'FSTYPE' --target "$1" | { \
9d36d4fb
HH
512 while read _fs; do
513 [[ $_fs ]] || continue
514 [[ $_fs = "autofs" ]] && continue
466a5998 515 printf "%s" "$_fs"
9d36d4fb 516 return 0
dba20559 517 done; return 1; } && return 0
7ae5d9d1
HH
518
519 return 1
520}
521
9d36d4fb
HH
522# find_dev_fstype <device>
523# Echo the filesystem type for a given device.
81672479
HH
524# /proc/self/mountinfo is taken as the primary source of information
525# and /etc/fstab is used as a fallback.
526# No newline is appended!
527# Example:
9d36d4fb 528# $ find_dev_fstype /dev/sda2;echo
81672479 529# ext4
9d36d4fb 530find_dev_fstype() {
5e601454 531 local _find_dev _fs
9d36d4fb 532 _find_dev="$1"
a4f7b504
HH
533 if ! [[ "$_find_dev" = /dev* ]]; then
534 [[ -b "/dev/block/$_find_dev" ]] && _find_dev="/dev/block/$_find_dev"
535 fi
5e601454
HH
536
537 if [[ $use_fstab != yes ]]; then
dba20559
HH
538 findmnt -e -v -n -o 'FSTYPE' --source "$_find_dev" | { \
539 while read _fs; do
540 [[ $_fs ]] || continue
541 [[ $_fs = "autofs" ]] && continue
466a5998 542 printf "%s" "$_fs"
dba20559
HH
543 return 0
544 done; return 1; } && return 0
545 fi
546
547 findmnt --fstab -e -v -n -o 'FSTYPE' --source "$_find_dev" | { \
5e601454
HH
548 while read _fs; do
549 [[ $_fs ]] || continue
550 [[ $_fs = "autofs" ]] && continue
466a5998 551 printf "%s" "$_fs"
5e601454 552 return 0
dba20559 553 done; return 1; } && return 0
5e601454
HH
554
555 return 1
97af51db 556}
5e601454 557
bbc9bfe1
HH
558# find_mp_fsopts <mountpoint>
559# Echo the filesystem options for a given mountpoint.
560# /proc/self/mountinfo is taken as the primary source of information
561# and /etc/fstab is used as a fallback.
562# No newline is appended!
563# Example:
564# $ find_mp_fsopts /;echo
565# rw,relatime,discard,data=ordered
566find_mp_fsopts() {
567 if [[ $use_fstab != yes ]]; then
568 findmnt -e -v -n -o 'OPTIONS' --target "$1" 2>/dev/null && return 0
569 fi
570
571 findmnt --fstab -e -v -n -o 'OPTIONS' --target "$1"
572}
573
97af51db
HH
574# find_dev_fsopts <device>
575# Echo the filesystem options for a given device.
576# /proc/self/mountinfo is taken as the primary source of information
577# and /etc/fstab is used as a fallback.
578# Example:
579# $ find_dev_fsopts /dev/sda2
580# rw,relatime,discard,data=ordered
581find_dev_fsopts() {
582 local _find_dev _opts
583 _find_dev="$1"
584 if ! [[ "$_find_dev" = /dev* ]]; then
585 [[ -b "/dev/block/$_find_dev" ]] && _find_dev="/dev/block/$_find_dev"
586 fi
587
588 if [[ $use_fstab != yes ]]; then
589 findmnt -e -v -n -o 'OPTIONS' --source "$_find_dev" 2>/dev/null && return 0
590 fi
591
592 findmnt --fstab -e -v -n -o 'OPTIONS' --source "$_find_dev"
81672479
HH
593}
594
97af51db 595
7ae5d9d1 596# finds the major:minor of the block device backing the root filesystem.
f76ef3aa
VL
597find_root_block_device() { find_block_device /; }
598
7e2bca48 599# for_each_host_dev_fs <func>
d351541e 600# Execute "<func> <dev> <filesystem>" for every "<dev> <fs>" pair found
7e2bca48 601# in ${host_fs_types[@]}
480d772f
HH
602for_each_host_dev_fs()
603{
604 local _func="$1"
d0096de7 605 local _dev
2efa546f 606 local _ret=1
fd191a7b
HH
607
608 [[ "${!host_fs_types[@]}" ]] || return 0
609
d351541e
HH
610 for _dev in "${!host_fs_types[@]}"; do
611 $_func "$_dev" "${host_fs_types[$_dev]}" && _ret=0
480d772f 612 done
2efa546f 613 return $_ret
480d772f
HH
614}
615
fd191a7b
HH
616host_fs_all()
617{
466a5998 618 printf "%s\n" "${host_fs_types[@]}"
fd191a7b
HH
619}
620
17829e94
VL
621# Walk all the slave relationships for a given block device.
622# Stop when our helper function returns success
623# $1 = function to call on every found block device
624# $2 = block device in major:minor format
0b706743 625check_block_and_slaves() {
29b10e65 626 local _x
17829e94 627 [[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
96c6f6f3 628 if ! lvm_internal_dev $2; then "$1" $2 && return; fi
533d7dc4 629 check_vol_slaves "$@" && return 0
3478b314 630 if [[ -f /sys/dev/block/$2/../dev ]]; then
dba20559 631 check_block_and_slaves $1 $(<"/sys/dev/block/$2/../dev") && return 0
a3afcf2a 632 fi
17829e94 633 [[ -d /sys/dev/block/$2/slaves ]] || return 1
29b10e65 634 for _x in /sys/dev/block/$2/slaves/*/dev; do
d82e0d7d 635 [[ -f $_x ]] || continue
dba20559 636 check_block_and_slaves $1 $(<"$_x") && return 0
17829e94
VL
637 done
638 return 1
639}
640
83e0dc7a
DY
641check_block_and_slaves_all() {
642 local _x _ret=1
643 [[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
96c6f6f3 644 if ! lvm_internal_dev $2 && "$1" $2; then
dba20559 645 _ret=0
83e0dc7a
DY
646 fi
647 check_vol_slaves "$@" && return 0
648 if [[ -f /sys/dev/block/$2/../dev ]]; then
dba20559 649 check_block_and_slaves_all $1 $(<"/sys/dev/block/$2/../dev") && _ret=0
83e0dc7a
DY
650 fi
651 [[ -d /sys/dev/block/$2/slaves ]] || return 1
652 for _x in /sys/dev/block/$2/slaves/*/dev; do
653 [[ -f $_x ]] || continue
dba20559 654 check_block_and_slaves_all $1 $(<"$_x") && _ret=0
83e0dc7a
DY
655 done
656 return $_ret
657}
658# for_each_host_dev_and_slaves <func>
659# Execute "<func> <dev>" for every "<dev>" found
660# in ${host_devs[@]} and their slaves
661for_each_host_dev_and_slaves_all()
662{
663 local _func="$1"
664 local _dev
665 local _ret=1
fd191a7b
HH
666
667 [[ "${host_devs[@]}" ]] || return 0
668
83e0dc7a
DY
669 for _dev in ${host_devs[@]}; do
670 [[ -b "$_dev" ]] || continue
83e0dc7a 671 if check_block_and_slaves_all $_func $(get_maj_min $_dev); then
dba20559 672 _ret=0
83e0dc7a
DY
673 fi
674 done
675 return $_ret
676}
677
678for_each_host_dev_and_slaves()
679{
680 local _func="$1"
681 local _dev
fd191a7b
HH
682
683 [[ "${host_devs[@]}" ]] || return 0
684
83e0dc7a
DY
685 for _dev in ${host_devs[@]}; do
686 [[ -b "$_dev" ]] || continue
a999414e 687 check_block_and_slaves $_func $(get_maj_min $_dev) && return 0
83e0dc7a
DY
688 done
689 return 1
690}
691
533d7dc4
HH
692# ugly workaround for the lvm design
693# There is no volume group device,
694# so, there are no slave devices for volume groups.
695# Logical volumes only have the slave devices they really live on,
696# but you cannot create the logical volume without the volume group.
95bde758 697# And the volume group might be bigger than the devices the LV needs.
533d7dc4 698check_vol_slaves() {
29b10e65 699 local _lv _vg _pv
0b706743 700 for i in /dev/mapper/*; do
1743473b 701 [[ $i == /dev/mapper/control ]] && continue
c4e48eae 702 _lv=$(get_maj_min $i)
29b10e65
HH
703 if [[ $_lv = $2 ]]; then
704 _vg=$(lvm lvs --noheadings -o vg_name $i 2>/dev/null)
cc02093d 705 # strip space
466a5998 706 _vg=$(printf "%s\n" "$_vg")
29b10e65
HH
707 if [[ $_vg ]]; then
708 for _pv in $(lvm vgs --noheadings -o pv_name "$_vg" 2>/dev/null)
0b706743 709 do
c4e48eae 710 check_block_and_slaves $1 $(get_maj_min $_pv) && return 0
cc02093d
HH
711 done
712 fi
713 fi
533d7dc4
HH
714 done
715 return 1
716}
717
8aa99268
HH
718# fs_get_option <filesystem options> <search for option>
719# search for a specific option in a bunch of filesystem options
720# and return the value
721fs_get_option() {
722 local _fsopts=$1
723 local _option=$2
724 local OLDIFS="$IFS"
725 IFS=,
726 set -- $_fsopts
727 IFS="$OLDIFS"
728 while [ $# -gt 0 ]; do
729 case $1 in
730 $_option=*)
731 echo ${1#${_option}=}
732 break
733 esac
734 shift
735 done
736}
737
89d44e72 738
55a0b3ab
HH
739if ! [[ $DRACUT_INSTALL ]]; then
740 DRACUT_INSTALL=$(find_binary dracut-install)
741fi
19612483 742
55a0b3ab
HH
743if ! [[ $DRACUT_INSTALL ]] && [[ -x $dracutbasedir/dracut-install ]]; then
744 DRACUT_INSTALL=$dracutbasedir/dracut-install
745fi
3f590c78 746
55a0b3ab
HH
747if ! [[ -x $DRACUT_INSTALL ]]; then
748 dfatal "dracut-install not found!"
749 exit 10
750fi
22048b44 751
55a0b3ab
HH
752[[ $DRACUT_RESOLVE_LAZY ]] || export DRACUT_RESOLVE_DEPS=1
753inst_dir() {
754 [[ -e ${initdir}/"$1" ]] && return 0 # already there
ffc68f35
HH
755 $DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@"
756 (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@" || :
55a0b3ab 757}
22048b44 758
55a0b3ab
HH
759inst() {
760 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
761 #dinfo "$DRACUT_INSTALL -l $@"
ffc68f35
HH
762 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@"
763 (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@" || :
55a0b3ab 764}
89d44e72 765
55a0b3ab
HH
766inst_simple() {
767 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
768 [[ -e $1 ]] || return 1 # no source
ffc68f35
HH
769 $DRACUT_INSTALL ${initdir:+-D "$initdir"} "$@"
770 (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} "$@" || :
55a0b3ab 771}
89d44e72 772
55a0b3ab
HH
773inst_symlink() {
774 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
775 [[ -L $1 ]] || return 1
ffc68f35
HH
776 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@"
777 (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@" || :
55a0b3ab 778}
89d44e72 779
af119460 780inst_multiple() {
55a0b3ab
HH
781 local ret
782 #dinfo "initdir=$initdir $DRACUT_INSTALL -l $@"
ffc68f35 783 $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@"
55a0b3ab 784 ret=$?
ffc68f35 785 (($ret != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@" || :
55a0b3ab
HH
786 return $ret
787}
89d44e72 788
af119460
HH
789dracut_install() {
790 inst_multiple "$@"
791}
792
55a0b3ab
HH
793inst_library() {
794 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
795 [[ -e $1 ]] || return 1 # no source
ffc68f35
HH
796 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@"
797 (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@" || :
55a0b3ab 798}
89d44e72 799
55a0b3ab 800inst_binary() {
ffc68f35
HH
801 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@"
802 (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@" || :
55a0b3ab 803}
89d44e72 804
55a0b3ab 805inst_script() {
ffc68f35
HH
806 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@"
807 (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@" || :
55a0b3ab 808}
36b24d7c 809
a10a1416
810# find symlinks linked to given library file
811# $1 = library file
812# Function searches for symlinks by stripping version numbers appended to
813# library filename, checks if it points to the same target and finally
814# prints the list of symlinks to stdout.
815#
816# Example:
817# rev_lib_symlinks libfoo.so.8.1
818# output: libfoo.so.8 libfoo.so
819# (Only if libfoo.so.8 and libfoo.so exists on host system.)
820rev_lib_symlinks() {
821 [[ ! $1 ]] && return 0
822
823 local fn="$1" orig="$(readlink -f "$1")" links=''
824
b093aa2d 825 [[ ${fn} == *.so.* ]] || return 1
a10a1416
826
827 until [[ ${fn##*.} == so ]]; do
828 fn="${fn%.*}"
829 [[ -L ${fn} && $(readlink -f "${fn}") == ${orig} ]] && links+=" ${fn}"
830 done
831
0b706743 832 echo "${links}"
a10a1416
833}
834
62073c30
CG
835# attempt to install any programs specified in a udev rule
836inst_rule_programs() {
837 local _prog _bin
838
839 if grep -qE 'PROGRAM==?"[^ "]+' "$1"; then
840 for _prog in $(grep -E 'PROGRAM==?"[^ "]+' "$1" | sed -r 's/.*PROGRAM==?"([^ "]+).*/\1/'); do
76d5c79e 841 _bin=""
604d1eb2
HH
842 if [ -x ${udevdir}/$_prog ]; then
843 _bin=${udevdir}/$_prog
34bd2be2 844 elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then
604d1eb2 845 _bin=$(find_binary "$_prog") || {
cc218087 846 dinfo "Skipping program $_prog using in udev rule ${1##*/} as it cannot be found"
604d1eb2
HH
847 continue;
848 }
849 fi
850
af119460 851 [[ $_bin ]] && inst_binary "$_bin"
604d1eb2
HH
852 done
853 fi
da9c5181
HH
854 if grep -qE 'RUN[+=]=?"[^ "]+' "$1"; then
855 for _prog in $(grep -E 'RUN[+=]=?"[^ "]+' "$1" | sed -r 's/.*RUN[+=]=?"([^ "]+).*/\1/'); do
76d5c79e 856 _bin=""
604d1eb2
HH
857 if [ -x ${udevdir}/$_prog ]; then
858 _bin=${udevdir}/$_prog
34bd2be2 859 elif [[ "${_prog/\$env\{/}" == "$_prog" ]] && [[ "${_prog}" != "/sbin/initqueue" ]]; then
604d1eb2 860 _bin=$(find_binary "$_prog") || {
cc218087 861 dinfo "Skipping program $_prog using in udev rule ${1##*/} as it cannot be found"
604d1eb2
HH
862 continue;
863 }
864 fi
865
af119460 866 [[ $_bin ]] && inst_binary "$_bin"
604d1eb2
HH
867 done
868 fi
65d1a8a4
HH
869 if grep -qE 'IMPORT\{program\}==?"[^ "]+' "$1"; then
870 for _prog in $(grep -E 'IMPORT\{program\}==?"[^ "]+' "$1" | sed -r 's/.*IMPORT\{program\}==?"([^ "]+).*/\1/'); do
76d5c79e 871 _bin=""
604d1eb2
HH
872 if [ -x ${udevdir}/$_prog ]; then
873 _bin=${udevdir}/$_prog
34bd2be2 874 elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then
62073c30 875 _bin=$(find_binary "$_prog") || {
cc218087 876 dinfo "Skipping program $_prog using in udev rule ${1##*/} as it cannot be found"
62073c30
CG
877 continue;
878 }
879 fi
880
76d5c79e 881 [[ $_bin ]] && dracut_install "$_bin"
62073c30
CG
882 done
883 fi
884}
885
e0a39336
HH
886# attempt to install any programs specified in a udev rule
887inst_rule_group_owner() {
888 local i
889
890 if grep -qE 'OWNER=?"[^ "]+' "$1"; then
891 for i in $(grep -E 'OWNER=?"[^ "]+' "$1" | sed -r 's/.*OWNER=?"([^ "]+).*/\1/'); do
892 if ! egrep -q "^$i:" "$initdir/etc/passwd" 2>/dev/null; then
893 egrep "^$i:" /etc/passwd 2>/dev/null >> "$initdir/etc/passwd"
894 fi
895 done
896 fi
897 if grep -qE 'GROUP=?"[^ "]+' "$1"; then
898 for i in $(grep -E 'GROUP=?"[^ "]+' "$1" | sed -r 's/.*GROUP=?"([^ "]+).*/\1/'); do
899 if ! egrep -q "^$i:" "$initdir/etc/group" 2>/dev/null; then
900 egrep "^$i:" /etc/group 2>/dev/null >> "$initdir/etc/group"
901 fi
902 done
903 fi
904}
905
8d85429a
HH
906inst_rule_initqueue() {
907 if grep -q -F initqueue "$1"; then
908 dracut_need_initqueue
909 fi
910}
911
f04dc5f3
VL
912# udev rules always get installed in the same place, so
913# create a function to install them to make life simpler.
0b706743 914inst_rules() {
29b10e65 915 local _target=/etc/udev/rules.d _rule _found
fd2312e0 916
604d1eb2 917 inst_dir "${udevdir}/rules.d"
29b10e65
HH
918 inst_dir "$_target"
919 for _rule in "$@"; do
256cba18 920 if [ "${_rule#/}" = "$_rule" ]; then
ffc68f35 921 for r in ${udevdir}/rules.d ${hostonly:+/etc/udev/rules.d}; do
ace51ef5 922 if [[ -e $r/$_rule ]]; then
76f5fa54 923 _found="$r/$_rule"
62073c30 924 inst_rule_programs "$_found"
e0a39336 925 inst_rule_group_owner "$_found"
8d85429a 926 inst_rule_initqueue "$_found"
604d1eb2 927 inst_simple "$_found"
76f5fa54
HH
928 fi
929 done
930 fi
63330a89
HH
931 for r in '' $dracutbasedir/rules.d/; do
932 # skip rules without an absolute path
933 [[ "${r}$_rule" != /* ]] && continue
934
29b10e65
HH
935 if [[ -f ${r}$_rule ]]; then
936 _found="${r}$_rule"
62073c30 937 inst_rule_programs "$_found"
e0a39336 938 inst_rule_group_owner "$_found"
8d85429a 939 inst_rule_initqueue "$_found"
604d1eb2 940 inst_simple "$_found" "$_target/${_found##*/}"
c97e1a76
HH
941 fi
942 done
29b10e65 943 [[ $_found ]] || dinfo "Skipping udev rule: $_rule"
f04dc5f3
VL
944 done
945}
946
bfa1db78
HR
947inst_rules_wildcard() {
948 local _target=/etc/udev/rules.d _rule _found
949
950 inst_dir "${udevdir}/rules.d"
951 inst_dir "$_target"
952 for _rule in ${udevdir}/rules.d/$1 ${dracutbasedir}/rules.d/$1 ; do
953 if [[ -e $_rule ]]; then
954 inst_rule_programs "$_rule"
955 inst_rule_group_owner "$_rule"
956 inst_rule_initqueue "$_rule"
957 inst_simple "$_rule"
958 _found=$_rule
959 fi
960 done
961 if [ -n ${hostonly} ] ; then
962 for _rule in ${_target}/$1 ; do
963 if [[ -f $_rule ]]; then
964 inst_rule_programs "$_rule"
965 inst_rule_group_owner "$_rule"
966 inst_rule_initqueue "$_rule"
967 inst_simple "$_rule"
968 _found=$_rule
969 fi
970 done
971 fi
972 [[ $_found ]] || dinfo "Skipping udev rule: $_rule"
973}
974
c46cda82
HH
975prepare_udev_rules() {
976 [ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version)
977
978 for f in "$@"; do
979 f="${initdir}/etc/udev/rules.d/$f"
980 [ -e "$f" ] || continue
981 while read line; do
982 if [ "${line%%IMPORT PATH_ID}" != "$line" ]; then
983 if [ $UDEVVERSION -ge 174 ]; then
984 printf '%sIMPORT{builtin}="path_id"\n' "${line%%IMPORT PATH_ID}"
985 else
986 printf '%sIMPORT{program}="path_id %%p"\n' "${line%%IMPORT PATH_ID}"
987 fi
988 elif [ "${line%%IMPORT BLKID}" != "$line" ]; then
989 if [ $UDEVVERSION -ge 176 ]; then
990 printf '%sIMPORT{builtin}="blkid"\n' "${line%%IMPORT BLKID}"
991 else
992 printf '%sIMPORT{program}="/sbin/blkid -o udev -p $tempnode"\n' "${line%%IMPORT BLKID}"
993 fi
994 else
995 echo "$line"
996 fi
997 done < "${f}" > "${f}.new"
998 mv "${f}.new" "$f"
999 done
1000}
1001
53f95456
VL
1002# install function specialized for hooks
1003# $1 = type of hook, $2 = hook priority (lower runs first), $3 = hook
1004# All hooks should be POSIX/SuS compliant, they will be sourced by init.
1005inst_hook() {
cdad82fd 1006 if ! [[ -f $3 ]]; then
e27770e1
1007 dfatal "Cannot install a hook ($3) that does not exist."
1008 dfatal "Aborting initrd creation."
cc02093d 1009 exit 1
b093aa2d 1010 elif ! [[ "$hookdirs" == *$1* ]]; then
3b403b32 1011 dfatal "No such hook type $1. Aborting initrd creation."
cc02093d 1012 exit 1
cdad82fd 1013 fi
5a84ac3f 1014 inst_simple "$3" "/lib/dracut/hooks/${1}/${2}-${3##*/}"
53f95456
VL
1015}
1016
3378a54f
1017# install any of listed files
1018#
1019# If first argument is '-d' and second some destination path, first accessible
1020# source is installed into this path, otherwise it will installed in the same
1021# path as source. If none of listed files was installed, function return 1.
1022# On first successful installation it returns with 0 status.
1023#
1024# Example:
1025#
1026# inst_any -d /bin/foo /bin/bar /bin/baz
1027#
1028# Lets assume that /bin/baz exists, so it will be installed as /bin/foo in
1029# initramfs.
1030inst_any() {
1031 local to f
1032
1033 [[ $1 = '-d' ]] && to="$2" && shift 2
1034
1035 for f in "$@"; do
1036 if [[ -e $f ]]; then
1037 [[ $to ]] && inst "$f" "$to" && return 0
1038 inst "$f" && return 0
1039 fi
1040 done
1041
1042 return 1
1043}
1044
c9143a63
JAH
1045
1046# inst_libdir_file [-n <pattern>] <file> [<file>...]
1047# Install a <file> located on a lib directory to the initramfs image
cacaa90c 1048# -n <pattern> install matching files
c9143a63 1049inst_libdir_file() {
0c6565c8 1050 local _files
c9143a63 1051 if [[ "$1" == "-n" ]]; then
cacaa90c 1052 local _pattern=$2
c9143a63
JAH
1053 shift 2
1054 for _dir in $libdirs; do
7828692f 1055 for _i in "$@"; do
c9143a63 1056 for _f in "$_dir"/$_i; do
7828692f 1057 [[ "$_f" =~ $_pattern ]] || continue
0c6565c8 1058 [[ -e "$_f" ]] && _files+="$_f "
c9143a63
JAH
1059 done
1060 done
1061 done
1062 else
1063 for _dir in $libdirs; do
7828692f 1064 for _i in "$@"; do
c9143a63 1065 for _f in "$_dir"/$_i; do
0c6565c8 1066 [[ -e "$_f" ]] && _files+="$_f "
c9143a63
JAH
1067 done
1068 done
1069 done
1070 fi
af119460 1071 [[ $_files ]] && inst_multiple $_files
c9143a63
JAH
1072}
1073
1074
87122afc
1075# install function decompressing the target and handling symlinks
1076# $@ = list of compressed (gz or bz2) files or symlinks pointing to such files
1077#
1078# Function install targets in the same paths inside overlay but decompressed
1079# and without extensions (.gz, .bz2).
1080inst_decompress() {
b19c5d51 1081 local _src _cmd
87122afc 1082
29b10e65 1083 for _src in $@
87122afc 1084 do
29b10e65 1085 case ${_src} in
c62b9461 1086 *.gz) _cmd='gzip -f -d' ;;
29b10e65 1087 *.bz2) _cmd='bzip2 -d' ;;
87122afc
1088 *) return 1 ;;
1089 esac
b19c5d51 1090 inst_simple ${_src}
87122afc
1091 # Decompress with chosen tool. We assume that tool changes name e.g.
1092 # from 'name.gz' to 'name'.
29b10e65 1093 ${_cmd} "${initdir}${_src}"
87122afc
1094 done
1095}
1096
1097# It's similar to above, but if file is not compressed, performs standard
1098# install.
1099# $@ = list of files
1100inst_opt_decompress() {
29b10e65 1101 local _src
87122afc 1102
29b10e65 1103 for _src in $@
87122afc 1104 do
29b10e65 1105 inst_decompress "${_src}" || inst "${_src}"
87122afc
1106 done
1107}
1108
7e2bca48
HH
1109# module_check <dracut module>
1110# execute the check() function of module-setup.sh of <dracut module>
1111# or the "check" script, if module-setup.sh is not found
1112# "check $hostonly" is called
95d2dabc 1113module_check() {
29b10e65
HH
1114 local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
1115 local _ret
31f1c02d
AW
1116 local _forced=0
1117 local _hostonly=$hostonly
1118 [ $# -eq 2 ] && _forced=$2
29b10e65
HH
1119 [[ -d $_moddir ]] || return 1
1120 if [[ ! -f $_moddir/module-setup.sh ]]; then
95d2dabc 1121 # if we do not have a check script, we are unconditionally included
29b10e65 1122 [[ -x $_moddir/check ]] || return 0
31f1c02d 1123 [ $_forced -ne 0 ] && unset hostonly
29b10e65 1124 $_moddir/check $hostonly
31f1c02d 1125 _ret=$?
95d2dabc 1126 else
1743473b 1127 unset check depends cmdline install installkernel
b093aa2d 1128 check() { true; }
29b10e65 1129 . $_moddir/module-setup.sh
95d2dabc 1130 is_func check || return 0
31f1c02d 1131 [ $_forced -ne 0 ] && unset hostonly
30e6e809 1132 moddir=$_moddir check $hostonly
29b10e65 1133 _ret=$?
1743473b 1134 unset check depends cmdline install installkernel
0c2e3d12 1135 fi
31f1c02d
AW
1136 hostonly=$_hostonly
1137 return $_ret
0c2e3d12
VL
1138}
1139
7e2bca48
HH
1140# module_check_mount <dracut module>
1141# execute the check() function of module-setup.sh of <dracut module>
1142# or the "check" script, if module-setup.sh is not found
1143# "mount_needs=1 check 0" is called
1144module_check_mount() {
1145 local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
1146 local _ret
1147 mount_needs=1
1148 [[ -d $_moddir ]] || return 1
1149 if [[ ! -f $_moddir/module-setup.sh ]]; then
1150 # if we do not have a check script, we are unconditionally included
1151 [[ -x $_moddir/check ]] || return 0
1152 mount_needs=1 $_moddir/check 0
1153 _ret=$?
1154 else
1743473b 1155 unset check depends cmdline install installkernel
b093aa2d 1156 check() { false; }
7e2bca48 1157 . $_moddir/module-setup.sh
30e6e809 1158 moddir=$_moddir check 0
7e2bca48 1159 _ret=$?
1743473b 1160 unset check depends cmdline install installkernel
7e2bca48
HH
1161 fi
1162 unset mount_needs
1163 return $_ret
1164}
1165
1166# module_depends <dracut module>
1167# execute the depends() function of module-setup.sh of <dracut module>
1168# or the "depends" script, if module-setup.sh is not found
95d2dabc 1169module_depends() {
29b10e65
HH
1170 local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
1171 local _ret
1172 [[ -d $_moddir ]] || return 1
1173 if [[ ! -f $_moddir/module-setup.sh ]]; then
95d2dabc 1174 # if we do not have a check script, we have no deps
29b10e65
HH
1175 [[ -x $_moddir/check ]] || return 0
1176 $_moddir/check -d
95d2dabc
HH
1177 return $?
1178 else
1743473b 1179 unset check depends cmdline install installkernel
b093aa2d 1180 depends() { true; }
29b10e65 1181 . $_moddir/module-setup.sh
30e6e809 1182 moddir=$_moddir depends
29b10e65 1183 _ret=$?
1743473b
HH
1184 unset check depends cmdline install installkernel
1185 return $_ret
1186 fi
1187}
1188
1189# module_cmdline <dracut module>
1190# execute the cmdline() function of module-setup.sh of <dracut module>
1191# or the "cmdline" script, if module-setup.sh is not found
1192module_cmdline() {
1193 local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
1194 local _ret
1195 [[ -d $_moddir ]] || return 1
1196 if [[ ! -f $_moddir/module-setup.sh ]]; then
1197 [[ -x $_moddir/cmdline ]] && . "$_moddir/cmdline"
1198 return $?
1199 else
1200 unset check depends cmdline install installkernel
1201 cmdline() { true; }
1202 . $_moddir/module-setup.sh
30e6e809 1203 moddir=$_moddir cmdline
1743473b
HH
1204 _ret=$?
1205 unset check depends cmdline install installkernel
29b10e65 1206 return $_ret
33ee031c 1207 fi
0c2e3d12
VL
1208}
1209
7e2bca48
HH
1210# module_install <dracut module>
1211# execute the install() function of module-setup.sh of <dracut module>
1212# or the "install" script, if module-setup.sh is not found
95d2dabc 1213module_install() {
29b10e65
HH
1214 local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
1215 local _ret
1216 [[ -d $_moddir ]] || return 1
1217 if [[ ! -f $_moddir/module-setup.sh ]]; then
1218 [[ -x $_moddir/install ]] && . "$_moddir/install"
95d2dabc
HH
1219 return $?
1220 else
1743473b 1221 unset check depends cmdline install installkernel
b093aa2d 1222 install() { true; }
29b10e65 1223 . $_moddir/module-setup.sh
30e6e809 1224 moddir=$_moddir install
29b10e65 1225 _ret=$?
1743473b 1226 unset check depends cmdline install installkernel
29b10e65 1227 return $_ret
95d2dabc
HH
1228 fi
1229}
1230
7e2bca48
HH
1231# module_installkernel <dracut module>
1232# execute the installkernel() function of module-setup.sh of <dracut module>
1233# or the "installkernel" script, if module-setup.sh is not found
95d2dabc 1234module_installkernel() {
29b10e65
HH
1235 local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
1236 local _ret
1237 [[ -d $_moddir ]] || return 1
1238 if [[ ! -f $_moddir/module-setup.sh ]]; then
1239 [[ -x $_moddir/installkernel ]] && . "$_moddir/installkernel"
95d2dabc
HH
1240 return $?
1241 else
1743473b 1242 unset check depends cmdline install installkernel
b093aa2d 1243 installkernel() { true; }
dba20559 1244 . $_moddir/module-setup.sh
30e6e809 1245 moddir=$_moddir installkernel
29b10e65 1246 _ret=$?
1743473b 1247 unset check depends cmdline install installkernel
29b10e65 1248 return $_ret
95d2dabc
HH
1249 fi
1250}
1251
7e2bca48
HH
1252# check_mount <dracut module>
1253# check_mount checks, if a dracut module is needed for the given
1254# device and filesystem types in "${host_fs_types[@]}"
1b7fd0fa
AW
1255check_mount() {
1256 local _mod=$1
1257 local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
1258 local _ret
1259 local _moddep
ecfa02bd
HH
1260
1261 [ "${#host_fs_types[*]}" -le 0 ] && return 1
1262
1b7fd0fa 1263 # If we are already scheduled to be loaded, no need to check again.
b093aa2d
HH
1264 [[ " $mods_to_load " == *\ $_mod\ * ]] && return 0
1265 [[ " $mods_checked_as_dep " == *\ $_mod\ * ]] && return 1
1b7fd0fa
AW
1266
1267 # This should never happen, but...
1268 [[ -d $_moddir ]] || return 1
1269
1270 [[ $2 ]] || mods_checked_as_dep+=" $_mod "
1271
b093aa2d 1272 if [[ " $omit_dracutmodules " == *\ $_mod\ * ]]; then
0f283709
HH
1273 return 1
1274 fi
1b7fd0fa 1275
b093aa2d 1276 if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\ $_mod\ * ]]; then
ecfa02bd
HH
1277 module_check_mount $_mod; ret=$?
1278
1279 # explicit module, so also accept ret=255
1280 [[ $ret = 0 || $ret = 255 ]] || return 1
1b7fd0fa 1281 else
ecfa02bd
HH
1282 # module not in our list
1283 if [[ $dracutmodules = all ]]; then
1284 # check, if we can and should install this module
1285 module_check_mount $_mod || return 1
1286 else
1287 # skip this module
1288 return 1
1289 fi
1b7fd0fa
AW
1290 fi
1291
ecfa02bd 1292
1b7fd0fa
AW
1293 for _moddep in $(module_depends $_mod); do
1294 # handle deps as if they were manually added
b093aa2d 1295 [[ " $add_dracutmodules " == *\ $_moddep\ * ]] || \
1b7fd0fa 1296 add_dracutmodules+=" $_moddep "
b093aa2d 1297 [[ " $force_add_dracutmodules " == *\ $_moddep\ * ]] || \
1b7fd0fa
AW
1298 force_add_dracutmodules+=" $_moddep "
1299 # if a module we depend on fail, fail also
0f283709 1300 if ! check_module $_moddep; then
600c8769 1301 derror "dracut module '$_mod' depends on '$_moddep', which can't be installed"
0f283709
HH
1302 return 1
1303 fi
1b7fd0fa
AW
1304 done
1305
b093aa2d 1306 [[ " $mods_to_load " == *\ $_mod\ * ]] || \
1b7fd0fa
AW
1307 mods_to_load+=" $_mod "
1308
1309 return 0
1310}
1311
7e2bca48
HH
1312# check_module <dracut module> [<use_as_dep>]
1313# check if a dracut module is to be used in the initramfs process
1314# if <use_as_dep> is set, then the process also keeps track
1315# that the modules were checked for the dependency tracking process
95d2dabc 1316check_module() {
29b10e65
HH
1317 local _mod=$1
1318 local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
1319 local _ret
1320 local _moddep
95d2dabc 1321 # If we are already scheduled to be loaded, no need to check again.
b093aa2d
HH
1322 [[ " $mods_to_load " == *\ $_mod\ * ]] && return 0
1323 [[ " $mods_checked_as_dep " == *\ $_mod\ * ]] && return 1
95d2dabc
HH
1324
1325 # This should never happen, but...
29b10e65 1326 [[ -d $_moddir ]] || return 1
95d2dabc 1327
29b10e65 1328 [[ $2 ]] || mods_checked_as_dep+=" $_mod "
95d2dabc 1329
b093aa2d 1330 if [[ " $omit_dracutmodules " == *\ $_mod\ * ]]; then
600c8769 1331 dinfo "dracut module '$_mod' will not be installed, because it's in the list to be omitted!"
0f283709
HH
1332 return 1
1333 fi
95d2dabc 1334
b093aa2d
HH
1335 if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\ $_mod\ * ]]; then
1336 if [[ " $force_add_dracutmodules " == *\ $_mod\ * ]]; then
31f1c02d
AW
1337 module_check $_mod 1; ret=$?
1338 else
1339 module_check $_mod 0; ret=$?
1340 fi
95d2dabc
HH
1341 # explicit module, so also accept ret=255
1342 [[ $ret = 0 || $ret = 255 ]] || return 1
1343 else
1344 # module not in our list
1345 if [[ $dracutmodules = all ]]; then
1346 # check, if we can and should install this module
29b10e65 1347 module_check $_mod || return 1
cc02093d 1348 else
95d2dabc
HH
1349 # skip this module
1350 return 1
970e646b 1351 fi
95d2dabc 1352 fi
bb764545 1353
29b10e65 1354 for _moddep in $(module_depends $_mod); do
95d2dabc 1355 # handle deps as if they were manually added
b093aa2d 1356 [[ " $add_dracutmodules " == *\ $_moddep\ * ]] || \
29b10e65 1357 add_dracutmodules+=" $_moddep "
b093aa2d 1358 [[ " $force_add_dracutmodules " == *\ $_moddep\ * ]] || \
31f1c02d 1359 force_add_dracutmodules+=" $_moddep "
95d2dabc 1360 # if a module we depend on fail, fail also
0f283709 1361 if ! check_module $_moddep; then
600c8769 1362 derror "dracut module '$_mod' depends on '$_moddep', which can't be installed"
0f283709
HH
1363 return 1
1364 fi
0c2e3d12 1365 done
70503db4 1366
b093aa2d 1367 [[ " $mods_to_load " == *\ $_mod\ * ]] || \
29b10e65 1368 mods_to_load+=" $_mod "
95d2dabc
HH
1369
1370 return 0
1371}
1372
7e2bca48
HH
1373# for_each_module_dir <func>
1374# execute "<func> <dracut module> 1"
1b7fd0fa 1375for_each_module_dir() {
29b10e65
HH
1376 local _modcheck
1377 local _mod
1378 local _moddir
1b7fd0fa
AW
1379 local _func
1380 _func=$1
29b10e65 1381 for _moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
00ed3ccf
HH
1382 [[ -d $_moddir ]] || continue;
1383 [[ -e $_moddir/install || -e $_moddir/installkernel || \
1384 -e $_moddir/module-setup.sh ]] || continue
29b10e65 1385 _mod=${_moddir##*/}; _mod=${_mod#[0-9][0-9]}
1b7fd0fa 1386 $_func $_mod 1
70503db4 1387 done
724b87a6
HH
1388
1389 # Report any missing dracut modules, the user has specified
31f1c02d 1390 _modcheck="$add_dracutmodules $force_add_dracutmodules"
29b10e65
HH
1391 [[ $dracutmodules != all ]] && _modcheck="$m $dracutmodules"
1392 for _mod in $_modcheck; do
b093aa2d
HH
1393 [[ " $mods_to_load " == *\ $_mod\ * ]] && continue
1394 [[ " $omit_dracutmodules " == *\ $_mod\ * ]] && continue
600c8769 1395 derror "dracut module '$_mod' cannot be found or installed."
724b87a6 1396 done
0c2e3d12
VL
1397}
1398
ddfd1d10
VL
1399# Install a single kernel module along with any firmware it may require.
1400# $1 = full path to kernel module to install
1401install_kmod_with_fw() {
0b440844 1402 # no need to go further if the module is already installed
379c34d2 1403
0b706743
1404 [[ -e "${initdir}/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" ]] \
1405 && return 0
fcbcb252 1406
f4031e8a
HH
1407 if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -e "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}" ]]; then
1408 read ret < "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
d8aeb3a7
HH
1409 return $ret
1410 fi
379c34d2 1411
fcbcb252
HH
1412 if [[ $omit_drivers ]]; then
1413 local _kmod=${1##*/}
1414 _kmod=${_kmod%.ko}
1415 _kmod=${_kmod/-/_}
34248c92
HH
1416 if [[ "$_kmod" =~ $omit_drivers ]]; then
1417 dinfo "Omitting driver $_kmod"
7abd4264 1418 return 0
34248c92
HH
1419 fi
1420 if [[ "${1##*/lib/modules/$kernel/}" =~ $omit_drivers ]]; then
fcbcb252 1421 dinfo "Omitting driver $_kmod"
7abd4264 1422 return 0
fcbcb252
HH
1423 fi
1424 fi
1425
868f935e
HH
1426 if [[ $silent_omit_drivers ]]; then
1427 local _kmod=${1##*/}
1428 _kmod=${_kmod%.ko}
1429 _kmod=${_kmod/-/_}
1430 [[ "$_kmod" =~ $silent_omit_drivers ]] && return 0
1431 [[ "${1##*/lib/modules/$kernel/}" =~ $silent_omit_drivers ]] && return 0
1432 fi
1433
d8aeb3a7
HH
1434 inst_simple "$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}"
1435 ret=$?
f4031e8a
HH
1436 [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
1437 [[ -d "$DRACUT_KERNEL_LAZY_HASHDIR" ]] && \
1438 echo $ret > "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
d8aeb3a7 1439 (($ret != 0)) && return $ret
e6024e00
JR
1440
1441 local _modname=${1##*/} _fwdir _found _fw
1442 _modname=${_modname%.ko*}
29b10e65
HH
1443 for _fw in $(modinfo -k $kernel -F firmware $1 2>/dev/null); do
1444 _found=''
1445 for _fwdir in $fw_dir; do
1446 if [[ -d $_fwdir && -f $_fwdir/$_fw ]]; then
1447 inst_simple "$_fwdir/$_fw" "/lib/firmware/$_fw"
1448 _found=yes
cc02093d
HH
1449 fi
1450 done
29b10e65 1451 if [[ $_found != yes ]]; then
fe1484f3 1452 if ! [[ -d $(echo /sys/module/${_modname//-/_}|{ read a b; echo $a; }) ]]; then
29b10e65
HH
1453 dinfo "Possible missing firmware \"${_fw}\" for kernel module" \
1454 "\"${_modname}.ko\""
e2cdb570 1455 else
29b10e65
HH
1456 dwarn "Possible missing firmware \"${_fw}\" for kernel module" \
1457 "\"${_modname}.ko\""
e2cdb570 1458 fi
cc02093d 1459 fi
ddfd1d10 1460 done
0b440844 1461 return 0
ddfd1d10
VL
1462}
1463
1464# Do something with all the dependencies of a kernel module.
1465# Note that kernel modules depend on themselves using the technique we use
0b706743
1466# $1 = function to call for each dependency we find
1467# It will be passed the full path to the found kernel module
ddfd1d10
VL
1468# $2 = module to get dependencies for
1469# rest of args = arguments to modprobe
c32bda6b 1470# _fderr specifies FD passed from surrounding scope
ddfd1d10 1471for_each_kmod_dep() {
7abd4264 1472 local _func=$1 _kmod=$2 _cmd _modpath _options
ddfd1d10 1473 shift 2
c32bda6b 1474 modprobe "$@" --ignore-install --show-depends $_kmod 2>&${_fderr} | (
29b10e65
HH
1475 while read _cmd _modpath _options; do
1476 [[ $_cmd = insmod ]] || continue
1477 $_func ${_modpath} || exit $?
0b706743 1478 done
0b706743 1479 )
ddfd1d10
VL
1480}
1481
70c6b773 1482dracut_kernel_post() {
d8aeb3a7 1483 local _moddirname=${srcmods%%/lib/modules/*}
3c4bfd68 1484 local _pid
d8aeb3a7 1485
f4031e8a 1486 if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" ]]; then
ffc68f35 1487 xargs -r modprobe -a ${_moddirname:+-d ${_moddirname}/} \
ec61f0a3 1488 --ignore-install --show-depends --set-version $kernel \
f4031e8a 1489 < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" 2>/dev/null \
89d44e72
HH
1490 | sort -u \
1491 | while read _cmd _modpath _options; do
1492 [[ $_cmd = insmod ]] || continue
1493 echo "$_modpath"
f4031e8a 1494 done > "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
d8aeb3a7 1495
89d44e72 1496 (
73575f11 1497 if [[ $DRACUT_INSTALL ]] && [[ -z $_moddirname ]]; then
ffc68f35 1498 xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
89d44e72
HH
1499 else
1500 while read _modpath; do
1501 local _destpath=$_modpath
1502 [[ $_moddirname ]] && _destpath=${_destpath##$_moddirname/}
1503 _destpath=${_destpath##*/lib/modules/$kernel/}
1504 inst_simple "$_modpath" "/lib/modules/$kernel/${_destpath}" || exit $?
f4031e8a 1505 done < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
89d44e72
HH
1506 fi
1507 ) &
dba20559
HH
1508 _pid=$(jobs -p | while read a ; do printf ":$a";done)
1509 _pid=${_pid##*:}
d8aeb3a7 1510
73575f11
HH
1511 if [[ $DRACUT_INSTALL ]]; then
1512 xargs -r modinfo -k $kernel -F firmware < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep" \
89d44e72
HH
1513 | while read line; do
1514 for _fwdir in $fw_dir; do
1515 echo $_fwdir/$line;
1516 done;
ffc68f35 1517 done | xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a -o
89d44e72 1518 else
73575f11 1519 for _fw in $(xargs -r modinfo -k $kernel -F firmware < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"); do
89d44e72
HH
1520 for _fwdir in $fw_dir; do
1521 if [[ -d $_fwdir && -f $_fwdir/$_fw ]]; then
1522 inst_simple "$_fwdir/$_fw" "/lib/firmware/$_fw"
1523 break
1524 fi
1525 done
1526 done
1527 fi
d8aeb3a7 1528
3c4bfd68 1529 wait $_pid
89d44e72 1530 fi
70c6b773 1531
70c6b773
HH
1532 for _f in modules.builtin.bin modules.builtin modules.order; do
1533 [[ $srcmods/$_f ]] && inst_simple "$srcmods/$_f" "/lib/modules/$kernel/$_f"
1534 done
1535
1536 # generate module dependencies for the initrd
1537 if [[ -d $initdir/lib/modules/$kernel ]] && \
1538 ! depmod -a -b "$initdir" $kernel; then
1539 dfatal "\"depmod -a $kernel\" failed."
1540 exit 1
1541 fi
1542
32bd2fbb 1543 [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && rm -fr -- "$DRACUT_KERNEL_LAZY_HASHDIR"
d8aeb3a7 1544}
fe1484f3 1545
3c4315fa
HH
1546[[ "$kernel_current" ]] || export kernel_current=$(uname -r)
1547
dba20559 1548module_is_host_only() {
080d1b71 1549 local _mod=$1
4d7c18c7 1550 local _modenc a i _k _s _v _aliases
080d1b71
HH
1551 _mod=${_mod##*/}
1552 _mod=${_mod%.ko}
3c4315fa 1553 _modenc=${_mod//-/_}
080d1b71 1554
b093aa2d 1555 [[ " $add_drivers " == *\ ${_mod}\ * ]] && return 0
080d1b71
HH
1556
1557 # check if module is loaded
3c4315fa
HH
1558 [[ ${host_modules["$_modenc"]} ]] && return 0
1559
1560 [[ "$kernel_current" ]] || export kernel_current=$(uname -r)
1561
1562 if [[ "$kernel_current" != "$kernel" ]]; then
1563 # check if module is loadable on the current kernel
1564 # this covers the case, where a new module is introduced
1565 # or a module was renamed
1566 # or a module changed from builtin to a module
4d7c18c7 1567
3c4315fa
HH
1568 if [[ -d /lib/modules/$kernel_current ]]; then
1569 # if the modinfo can be parsed, but the module
1570 # is not loaded, then we can safely return 1
1571 modinfo -F filename "$_mod" &>/dev/null && return 1
1572 fi
080d1b71 1573
4d7c18c7
HH
1574 _aliases=$(modinfo -k $kernel -F alias $_mod 2>/dev/null)
1575
1576 # if the module has no aliases, install it
1577 [[ $_aliases ]] || return 0
1578
1579 # finally check all modalias
1580 for a in $_aliases; do
3c4315fa
HH
1581 for i in "${!host_modalias[@]}"; do
1582 [[ $i == $a ]] && return 0
1583 done
1584 done
4d7c18c7 1585
3c4315fa 1586 fi
080d1b71
HH
1587
1588 return 1
b093aa2d 1589}
080d1b71 1590
b093aa2d 1591find_kernel_modules_by_path () {
74405477 1592 local _OLDIFS
5db6ca5a 1593
b093aa2d 1594 [[ -f "$srcmods/modules.dep" ]] || return 0
5db6ca5a
HH
1595
1596 _OLDIFS=$IFS
1597 IFS=:
1598 while read a rest; do
e8a7c9bc 1599 [[ $a = */$1/* ]] || [[ $a = updates/* ]] || continue
b093aa2d
HH
1600 printf "%s\n" "$srcmods/$a"
1601 done < "$srcmods/modules.dep"
5db6ca5a 1602 IFS=$_OLDIFS
74405477 1603 return 0
b093aa2d 1604}
4073c815 1605
881eda69
JR
1606find_kernel_modules () {
1607 find_kernel_modules_by_path drivers
1608}
1609
338b43cd
HH
1610# instmods [-c [-s]] <kernel module> [<kernel module> ... ]
1611# instmods [-c [-s]] <kernel subsystem>
ddfd1d10 1612# install kernel modules along with all their dependencies.
7e2bca48 1613# <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
6fa0c3d6 1614instmods() {
0c1a8ebc 1615 [[ $no_kernel = yes ]] && return
c32bda6b
MS
1616 # called [sub]functions inherit _fderr
1617 local _fderr=9
a6d3be9d 1618 local _check=no
338b43cd 1619 local _silent=no
a6d3be9d
AW
1620 if [[ $1 = '-c' ]]; then
1621 _check=yes
1622 shift
1623 fi
881eda69 1624
338b43cd
HH
1625 if [[ $1 = '-s' ]]; then
1626 _silent=yes
1627 shift
1628 fi
1629
881eda69 1630 function inst1mod() {
a6d3be9d 1631 local _ret=0 _mod="$1"
29b10e65 1632 case $_mod in
0b706743 1633 =*)
d8aeb3a7
HH
1634 ( [[ "$_mpargs" ]] && echo $_mpargs
1635 find_kernel_modules_by_path "${_mod#=}" ) \
1636 | instmods
1637 ((_ret+=$?))
cc02093d 1638 ;;
0024702f 1639 --*) _mpargs+=" $_mod" ;;
34248c92 1640 *)
379c34d2 1641 _mod=${_mod##*/}
6568d86a 1642 # if we are already installed, skip this module and go on
cc02093d 1643 # to the next one.
f4031e8a
HH
1644 if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
1645 [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko}.ko" ]]; then
1646 read _ret <"$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko}.ko"
d8aeb3a7
HH
1647 return $_ret
1648 fi
881eda69 1649
beb26a08
DY
1650 _mod=${_mod/-/_}
1651 if [[ $omit_drivers ]] && [[ "$_mod" =~ $omit_drivers ]]; then
34248c92 1652 dinfo "Omitting driver ${_mod##$srcmods}"
7abd4264 1653 return 0
34248c92 1654 fi
080d1b71 1655
cc02093d
HH
1656 # If we are building a host-specific initramfs and this
1657 # module is not already loaded, move on to the next one.
fe1484f3 1658 [[ $hostonly ]] \
080d1b71 1659 && ! module_is_host_only "$_mod" \
7abd4264 1660 && return 0
04b56f3a 1661
f4031e8a 1662 if [[ "$_check" = "yes" ]] || ! [[ $DRACUT_KERNEL_LAZY_HASHDIR ]]; then
d8aeb3a7 1663 # We use '-d' option in modprobe only if modules prefix path
600c8769 1664 # differs from default '/'. This allows us to use dracut with
d8aeb3a7
HH
1665 # old version of modprobe which doesn't have '-d' option.
1666 local _moddirname=${srcmods%%/lib/modules/*}
1667 [[ -n ${_moddirname} ]] && _moddirname="-d ${_moddirname}/"
1668
1669 # ok, load the module, all its dependencies, and any firmware
1670 # it may require
1671 for_each_kmod_dep install_kmod_with_fw $_mod \
1672 --set-version $kernel ${_moddirname} $_mpargs
1673 ((_ret+=$?))
1674 else
f4031e8a
HH
1675 [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
1676 echo $_mod >> "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist"
d8aeb3a7 1677 fi
cc02093d 1678 ;;
0b706743 1679 esac
a6d3be9d 1680 return $_ret
881eda69
JR
1681 }
1682
f9708da2 1683 function instmods_1() {
a6d3be9d 1684 local _mod _mpargs
f9708da2
JR
1685 if (($# == 0)); then # filenames from stdin
1686 while read _mod; do
a6d3be9d 1687 inst1mod "${_mod%.ko*}" || {
338b43cd 1688 if [[ "$_check" == "yes" ]]; then
19b5c109 1689 [[ "$_silent" == "no" ]] && dfatal "Failed to install module $_mod"
a6d3be9d
AW
1690 return 1
1691 fi
1692 }
f9708da2
JR
1693 done
1694 fi
1695 while (($# > 0)); do # filenames as arguments
a6d3be9d 1696 inst1mod ${1%.ko*} || {
338b43cd 1697 if [[ "$_check" == "yes" ]]; then
19b5c109 1698 [[ "$_silent" == "no" ]] && dfatal "Failed to install module $1"
a6d3be9d
AW
1699 return 1
1700 fi
1701 }
f9708da2 1702 shift
881eda69 1703 done
a6d3be9d 1704 return 0
f9708da2
JR
1705 }
1706
a6d3be9d 1707 local _ret _filter_not_found='FATAL: Module .* not found.'
c32bda6b
MS
1708 # Capture all stderr from modprobe to _fderr. We could use {var}>...
1709 # redirections, but that would make dracut require bash4 at least.
1710 eval "( instmods_1 \"\$@\" ) ${_fderr}>&1" \
dba20559 1711 | while read line; do [[ "$line" =~ $_filter_not_found ]] || echo $line;done | derror
a6d3be9d 1712 _ret=$?
a6d3be9d 1713 return $_ret
0b706743 1714}
5f2c30d9
KRW
1715# get_cpu_vendor
1716# Only two values are returned: AMD or Intel
1717get_cpu_vendor ()
1718{
1719 if grep -qE AMD /proc/cpuinfo; then
1720 printf "AMD"
1721 fi
1722 if grep -qE Intel /proc/cpuinfo; then
1723 printf "Intel"
1724 fi
1725}
1726
1727# get_host_ucode
1728# Get the hosts' ucode file based on the /proc/cpuinfo
1729get_ucode_file ()
1730{
1731 local family=`grep -E "cpu family" /proc/cpuinfo | head -1 | sed s/.*:\ //`
1732 local model=`grep -E "model" /proc/cpuinfo |grep -v name | head -1 | sed s/.*:\ //`
1733 local stepping=`grep -E "stepping" /proc/cpuinfo | head -1 | sed s/.*:\ //`
1734
1735 if [[ "$(get_cpu_vendor)" == "AMD" ]]; then
1736 # If family greater or equal than 0x15
1737 if [[ $family -ge 21 ]]; then
1738 printf "microcode_amd_fam15h.bin"
1739 else
1740 printf "microcode_amd.bin"
1741 fi
1742 fi
1743 if [[ "$(get_cpu_vendor)" == "Intel" ]]; then
1744 # The /proc/cpuinfo are in decimal.
1745 printf "%02x-%02x-%02x" ${family} ${model} ${stepping}
1746 fi
1747}
96c6f6f3
MC
1748
1749# Not every device in /dev/mapper should be examined.
1750# If it is an LVM device, touch only devices which have /dev/VG/LV symlink.
1751lvm_internal_dev() {
1752 local dev_dm_dir=/sys/dev/block/$1/dm
1753 [[ ! -f $dev_dm_dir/uuid || $(<$dev_dm_dir/uuid) != LVM-* ]] && return 1 # Not an LVM device
1754 local DM_VG_NAME DM_LV_NAME DM_LV_LAYER
1755 eval $(dmsetup splitname --nameprefixes --noheadings --rows "$(<$dev_dm_dir/name)" 2>/dev/null)
1756 [[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] || return 0 # Better skip this!
1757 [[ ${DM_LV_LAYER} ]] || [[ ! -L /dev/${DM_VG_NAME}/${DM_LV_NAME} ]]
1758}
1759