3 # functions used by dracut and other tools.
5 # Copyright 2005-2009 Red Hat, Inc. All rights reserved.
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.
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.
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/>.
22 if [[ $DRACUT_KERNEL_LAZY ]] && ! [[ $DRACUT_KERNEL_LAZY_HASHDIR ]]; then
23 if [[ -d "$initdir/.kernelmodseen" ]]; then
24 DRACUT_KERNEL_LAZY_HASHDIR
="$initdir/.kernelmodseen"
28 # Generic substring function. If $2 is in $1, return 0.
29 strstr
() { [[ $1 = *"$2"* ]]; }
30 # Generic glob matching function. If glob pattern $2 matches anywhere in $1, OK
31 strglobin
() { [[ $1 = *$2* ]]; }
32 # Generic glob matching function. If glob pattern $2 matches all of $1, OK
33 strglob
() { [[ $1 = $2 ]]; }
34 # returns OK if $1 contains literal string $2 at the beginning, and isn't empty
35 str_starts
() { [ "${1#"$2"*}" != "$1" ]; }
36 # returns OK if $1 contains literal string $2 at the end, and isn't empty
37 str_ends
() { [ "${1%*"$2"}" != "$1" ]; }
39 # helper function for check() in module-setup.sh
40 # to check for required installed binaries
41 # issues a standardized warning message
43 local _module_name
="${moddir##*/}"
46 if [[ "$1" = "-m" ]]; then
52 if ! find_binary
"$cmd" &>/dev
/null
; then
53 dinfo
"dracut module '${_module_name#[0-9][0-9]}' will not be installed, because command '$cmd' could not be found!"
60 require_any_binary
() {
61 local _module_name
="${moddir##*/}"
64 if [[ "$1" = "-m" ]]; then
70 if find_binary
"$cmd" &>/dev
/null
; then
76 if (( $_ret != 0 )); then
77 dinfo
"$_module_name: Could not find any command of '$@'!"
84 # find a binary. If we were not passed the full path directly,
85 # search in the usual places to find the binary.
87 if [[ -z ${1##/*} ]]; then
88 if [[ -x $1 ]] ||
{ [[ "$1" == *.so
* ]] && ldd
"$1" &>/dev
/null
; }; then
97 if ! [[ $dracutbasedir ]]; then
98 dracutbasedir
=${BASH_SOURCE[0]%/*}
99 [[ $dracutbasedir = "dracut-functions" ]] && dracutbasedir
="."
100 [[ $dracutbasedir ]] || dracutbasedir
="."
101 dracutbasedir
="$(readlink -f $dracutbasedir)"
106 ldconfig
-pN 2>/dev
/null |
grep -E -v '/(lib|lib64|usr/lib|usr/lib64)/[^/]*$' |
sed -n 's,.* => \(.*\)/.*,\1,p' |
sort |
uniq
110 if ! [[ $libdirs ]] ; then
111 if [[ "$(ldd /bin/sh)" == */lib64
/* ]] &>/dev
/null \
112 && [[ -d /lib64
]]; then
114 [[ -d /usr
/lib64
]] && libdirs
+=" /usr/lib64"
117 [[ -d /usr
/lib
]] && libdirs
+=" /usr/lib"
120 libdirs
+=" $(ldconfig_paths)"
125 if ! [[ $kernel ]]; then
130 # Version comparision function. Assumes Linux style version scheme.
132 # $2 = comparision op (gt, ge, eq, le, lt, ne)
135 local _n1
=(${1//./ }) _op
=$2 _n2
=(${3//./ }) _i _res
139 if [[ ! ${_n1[_i]}${_n2[_i]} ]]; then _res
=0
140 elif ((${_n1[_i]:-0} > ${_n2[_i]:-0})); then _res
=1
141 elif ((${_n1[_i]:-0} < ${_n2[_i]:-0})); then _res
=2
157 srcmods
="/lib/modules/$kernel/"
159 [[ $drivers_dir ]] && {
160 if ! command -v kmod
&>/dev
/null
&& vercmp
"$(modprobe --version | cut -d' ' -f3)" lt
3.7; then
161 dfatal
'To use --kmoddir option module-init-tools >= 3.7 is required.'
164 srcmods
="$drivers_dir"
169 # Check whether $1 is a function.
171 [[ "$(type -t "$1")" = "function" ]]
174 if ! is_func dinfo
>/dev
/null
2>&1; then
175 .
"$dracutbasedir/dracut-logger.sh"
179 if ! [[ $initdir ]]; then
180 dfatal
"initdir not set"
184 # export standard hookdirs
186 hookdirs
="cmdline pre-udev pre-trigger netroot "
187 hookdirs
+="initqueue initqueue/settled initqueue/online initqueue/finished initqueue/timeout "
188 hookdirs
+="pre-mount pre-pivot cleanup mount "
189 hookdirs
+="emergency shutdown-emergency pre-shutdown shutdown "
193 dracut_need_initqueue
() {
194 >"$initdir/lib/dracut/need-initqueue"
197 dracut_module_included
() {
198 [[ " $mods_to_load $modules_loaded " == *\ $
*\
* ]]
201 # Create all subdirectories for given path without creating the last element.
204 [[ -e ${1%/*} ]] || mkdir
-m 0755 -p -- "${1%/*}"
207 # Function prints global variables in format name=value line by line.
208 # $@ = list of global variables' name
214 eval printf -v _value
"%s" \""\$$_var"\"
215 [[ ${_value} ]] && printf '%s="%s"\n' "$_var" "$_value"
219 # normalize_path <path>
220 # Prints the normalized path, where it removes any duplicated
221 # and trailing slashes.
223 # $ normalize_path ///test/test//
227 set -- "${1//+(\/)//}"
229 printf "%s\n" "${1%/}"
232 # convert_abs_rel <from> <to>
233 # Prints the relative path, when creating a symlink to <to> from <from>.
235 # $ convert_abs_rel /usr/bin/test /bin/test-2
237 # $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test
239 local __current __absolute __abssize __cursize __newpath
242 set -- "$(normalize_path "$1")" "$(normalize_path "$2")"
244 # corner case #1 - self looping link
245 [[ "$1" == "$2" ]] && { printf "%s\n" "${1##*/}"; return; }
247 # corner case #2 - own dir link
248 [[ "${1%/*}" == "$2" ]] && { printf ".\n"; return; }
250 IFS
="/" __current
=($1)
251 IFS
="/" __absolute
=($2)
253 __abssize
=${#__absolute[@]}
254 __cursize
=${#__current[@]}
256 while [[ "${__absolute[__level]}" == "${__current[__level]}" ]]
259 if (( __level
> __abssize || __level
> __cursize
))
265 for ((__i
= __level
; __i
< __cursize-1
; __i
++))
269 __newpath
=$__newpath"/"
271 __newpath
=$__newpath".."
274 for ((__i
= __level
; __i
< __abssize
; __i
++))
276 if [[ -n $__newpath ]]
278 __newpath
=$__newpath"/"
280 __newpath
=$__newpath${__absolute[__i]}
283 printf "%s\n" "$__newpath"
286 if [[ "$(ln --help)" == *--relative* ]]; then
288 ln -sfnr "${initdir}/$1" "${initdir}/$2"
294 [[ -d "${_dest%/*}" ]] && _dest=$(readlink -f "${_dest%/*}")/${_dest##*/}
295 ln -sfn -- "$
(convert_abs_rel
"${_dest}" "${_source}")" "${initdir}/${_dest}"
299 # get_fs_env <device>
300 # Get and the ID_FS_TYPE variable from udev for a device.
302 # $ get_fs_env /dev/sda2
310 ID_FS_TYPE
=$
(blkid
-u filesystem
-o export -- "$1" \
311 |
while read line ||
[ -n "$line" ]; do
312 if [[ "$line" == TYPE\
=* ]]; then
313 printf "%s" "${line#TYPE=}";
317 if [[ $ID_FS_TYPE ]]; then
318 printf "%s" "$ID_FS_TYPE"
324 # get_maj_min <device>
325 # Prints the major and minor of a device node.
327 # $ get_maj_min /dev/sda2
330 local _maj _min _majmin
331 _majmin
="$(stat -L -c '%t:%T' "$1" 2>/dev/null)"
332 printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))"
336 # get_devpath_block <device>
337 # get the DEVPATH in /sys of a block device
338 get_devpath_block
() {
340 _majmin
=$
(get_maj_min
"$1")
342 for _i
in /sys
/block
/*/dev
/sys
/block
/*/*/dev
; do
343 [[ -e "$_i" ]] ||
continue
344 if [[ "$_majmin" == "$(<"$_i")" ]]; then
345 printf "%s" "${_i%/dev}"
352 # get a persistent path from a device
353 get_persistent_dev
() {
356 _dev
=$
(get_maj_min
"$1")
357 [ -z "$_dev" ] && return
361 /dev
/disk
/${persistent_policy:-by-uuid}/* \
362 /dev
/disk
/by-uuid
/* \
363 /dev
/disk
/by-label
/* \
364 /dev
/disk
/by-partuuid
/* \
365 /dev
/disk
/by-partlabel
/* \
367 /dev
/disk
/by-path
/* \
369 [[ -e "$i" ]] ||
continue
370 [[ $i == /dev
/mapper
/control
]] && continue
371 [[ $i == /dev
/mapper
/mpath
* ]] && continue
372 _tmp
=$
(get_maj_min
"$i")
373 if [ "$_tmp" = "$_dev" ]; then
381 expand_persistent_dev
() {
386 _dev
="/dev/disk/by-label/${_dev#LABEL=}"
391 _dev
="/dev/disk/by-uuid/${_dev}"
394 _dev
="${_dev#PARTUUID=}"
396 _dev
="/dev/disk/by-partuuid/${_dev}"
399 _dev
="/dev/disk/by-partlabel/${_dev#PARTLABEL=}"
405 shorten_persistent_dev
() {
409 printf "%s" "UUID=${_dev##*/}";;
410 /dev
/disk
/by-label
/*)
411 printf "%s" "LABEL=${_dev##*/}";;
412 /dev
/disk
/by-partuuid
/*)
413 printf "%s" "PARTUUID=${_dev##*/}";;
414 /dev
/disk
/by-partlabel
/*)
415 printf "%s" "PARTLABEL=${_dev##*/}";;
417 printf "%s" "$_dev";;
421 # find_block_device <mountpoint>
422 # Prints the major and minor number of the block device
423 # for a given mountpoint.
424 # Unless $use_fstab is set to "yes" the functions
425 # uses /proc/self/mountinfo as the primary source of the
426 # information and only falls back to /etc/fstab, if the mountpoint
427 # is not found there.
429 # $ find_block_device /usr
431 find_block_device
() {
432 local _dev _majmin _find_mpt
434 if [[ $use_fstab != yes ]]; then
435 [[ -d $_find_mpt/.
]]
436 findmnt
-e -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" |
{ \
437 while read _majmin _dev ||
[ -n "$_dev" ]; do
438 if [[ -b $_dev ]]; then
439 if ! [[ $_majmin ]] ||
[[ $_majmin == 0:* ]]; then
440 _majmin
=$
(get_maj_min
$_dev)
442 if [[ $_majmin ]]; then
443 printf "%s\n" "$_majmin"
445 printf "%s\n" "$_dev"
449 if [[ $_dev = *:* ]]; then
450 printf "%s\n" "$_dev"
453 done; return 1; } && return 0
455 # fall back to /etc/fstab
457 findmnt
-e --fstab -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" |
{ \
458 while read _majmin _dev ||
[ -n "$_dev" ]; do
459 if ! [[ $_dev ]]; then
463 if [[ -b $_dev ]]; then
464 [[ $_majmin ]] || _majmin
=$
(get_maj_min
$_dev)
465 if [[ $_majmin ]]; then
466 printf "%s\n" "$_majmin"
468 printf "%s\n" "$_dev"
472 if [[ $_dev = *:* ]]; then
473 printf "%s\n" "$_dev"
476 done; return 1; } && return 0
481 # find_mp_fstype <mountpoint>
482 # Echo the filesystem type for a given mountpoint.
483 # /proc/self/mountinfo is taken as the primary source of information
484 # and /etc/fstab is used as a fallback.
485 # No newline is appended!
487 # $ find_mp_fstype /;echo
492 if [[ $use_fstab != yes ]]; then
493 findmnt
-e -v -n -o 'FSTYPE' --target "$1" |
{ \
494 while read _fs ||
[ -n "$_fs" ]; do
495 [[ $_fs ]] ||
continue
496 [[ $_fs = "autofs" ]] && continue
499 done; return 1; } && return 0
502 findmnt
--fstab -e -v -n -o 'FSTYPE' --target "$1" |
{ \
503 while read _fs ||
[ -n "$_fs" ]; do
504 [[ $_fs ]] ||
continue
505 [[ $_fs = "autofs" ]] && continue
508 done; return 1; } && return 0
513 # find_dev_fstype <device>
514 # Echo the filesystem type for a given device.
515 # /proc/self/mountinfo is taken as the primary source of information
516 # and /etc/fstab is used as a fallback.
517 # No newline is appended!
519 # $ find_dev_fstype /dev/sda2;echo
524 if ! [[ "$_find_dev" = /dev
* ]]; then
525 [[ -b "/dev/block/$_find_dev" ]] && _find_dev
="/dev/block/$_find_dev"
528 if [[ $use_fstab != yes ]]; then
529 findmnt
-e -v -n -o 'FSTYPE' --source "$_find_dev" |
{ \
530 while read _fs ||
[ -n "$_fs" ]; do
531 [[ $_fs ]] ||
continue
532 [[ $_fs = "autofs" ]] && continue
535 done; return 1; } && return 0
538 findmnt
--fstab -e -v -n -o 'FSTYPE' --source "$_find_dev" |
{ \
539 while read _fs ||
[ -n "$_fs" ]; do
540 [[ $_fs ]] ||
continue
541 [[ $_fs = "autofs" ]] && continue
544 done; return 1; } && return 0
549 # find_mp_fsopts <mountpoint>
550 # Echo the filesystem options for a given mountpoint.
551 # /proc/self/mountinfo is taken as the primary source of information
552 # and /etc/fstab is used as a fallback.
553 # No newline is appended!
555 # $ find_mp_fsopts /;echo
556 # rw,relatime,discard,data=ordered
558 if [[ $use_fstab != yes ]]; then
559 findmnt
-e -v -n -o 'OPTIONS' --target "$1" 2>/dev
/null
&& return 0
562 findmnt
--fstab -e -v -n -o 'OPTIONS' --target "$1"
565 # find_dev_fsopts <device>
566 # Echo the filesystem options for a given device.
567 # /proc/self/mountinfo is taken as the primary source of information
568 # and /etc/fstab is used as a fallback.
570 # $ find_dev_fsopts /dev/sda2
571 # rw,relatime,discard,data=ordered
573 local _find_dev _opts
575 if ! [[ "$_find_dev" = /dev
* ]]; then
576 [[ -b "/dev/block/$_find_dev" ]] && _find_dev
="/dev/block/$_find_dev"
579 if [[ $use_fstab != yes ]]; then
580 findmnt
-e -v -n -o 'OPTIONS' --source "$_find_dev" 2>/dev
/null
&& return 0
583 findmnt
--fstab -e -v -n -o 'OPTIONS' --source "$_find_dev"
587 # finds the major:minor of the block device backing the root filesystem.
588 find_root_block_device
() { find_block_device
/; }
590 # for_each_host_dev_fs <func>
591 # Execute "<func> <dev> <filesystem>" for every "<dev> <fs>" pair found
592 # in ${host_fs_types[@]}
593 for_each_host_dev_fs
()
599 [[ "${#host_fs_types[@]}" ]] ||
return 0
601 for _dev
in "${!host_fs_types[@]}"; do
602 $_func "$_dev" "${host_fs_types[$_dev]}" && _ret
=0
609 printf "%s\n" "${host_fs_types[@]}"
612 # Walk all the slave relationships for a given block device.
613 # Stop when our helper function returns success
614 # $1 = function to call on every found block device
615 # $2 = block device in major:minor format
616 check_block_and_slaves
() {
618 [[ -b /dev
/block
/$2 ]] ||
return 1 # Not a block device? So sorry.
619 if ! lvm_internal_dev
$2; then "$1" $2 && return; fi
620 check_vol_slaves
"$@" && return 0
621 if [[ -f /sys
/dev
/block
/$2/..
/dev
]]; then
622 check_block_and_slaves
$1 $
(<"/sys/dev/block/$2/../dev") && return 0
624 [[ -d /sys
/dev
/block
/$2/slaves
]] ||
return 1
625 for _x
in /sys
/dev
/block
/$2/slaves
/*/dev
; do
626 [[ -f $_x ]] ||
continue
627 check_block_and_slaves
$1 $
(<"$_x") && return 0
632 check_block_and_slaves_all
() {
634 [[ -b /dev
/block
/$2 ]] ||
return 1 # Not a block device? So sorry.
635 if ! lvm_internal_dev
$2 && "$1" $2; then
638 check_vol_slaves
"$@" && return 0
639 if [[ -f /sys
/dev
/block
/$2/..
/dev
]]; then
640 check_block_and_slaves_all
$1 $
(<"/sys/dev/block/$2/../dev") && _ret
=0
642 [[ -d /sys
/dev
/block
/$2/slaves
]] ||
return 1
643 for _x
in /sys
/dev
/block
/$2/slaves
/*/dev
; do
644 [[ -f $_x ]] ||
continue
645 check_block_and_slaves_all
$1 $
(<"$_x") && _ret
=0
649 # for_each_host_dev_and_slaves <func>
650 # Execute "<func> <dev>" for every "<dev>" found
651 # in ${host_devs[@]} and their slaves
652 for_each_host_dev_and_slaves_all
()
658 [[ "${host_devs[@]}" ]] ||
return 0
660 for _dev
in "${host_devs[@]}"; do
661 [[ -b "$_dev" ]] ||
continue
662 if check_block_and_slaves_all
$_func $
(get_maj_min
$_dev); then
669 for_each_host_dev_and_slaves
()
674 [[ "${host_devs[@]}" ]] ||
return 0
676 for _dev
in "${host_devs[@]}"; do
677 [[ -b "$_dev" ]] ||
continue
678 check_block_and_slaves
$_func $
(get_maj_min
$_dev) && return 0
683 # ugly workaround for the lvm design
684 # There is no volume group device,
685 # so, there are no slave devices for volume groups.
686 # Logical volumes only have the slave devices they really live on,
687 # but you cannot create the logical volume without the volume group.
688 # And the volume group might be bigger than the devices the LV needs.
690 local _lv _vg _pv _dm
691 for i
in /dev
/mapper
/*; do
692 [[ $i == /dev
/mapper
/control
]] && continue
693 _lv
=$
(get_maj_min
$i)
694 _dm
=/sys
/dev
/block
/$_lv/dm
695 [[ -f $_dm/uuid
&& $
(<$_dm/uuid
) =~ LVM-
* ]] ||
continue
696 if [[ $_lv = $2 ]]; then
697 _vg
=$
(lvm lvs
--noheadings -o vg_name
$i 2>/dev
/null
)
699 _vg
=$
(printf "%s\n" "$_vg")
701 for _pv
in $
(lvm vgs
--noheadings -o pv_name
"$_vg" 2>/dev
/null
)
703 check_block_and_slaves
$1 $
(get_maj_min
$_pv) && return 0
711 # fs_get_option <filesystem options> <search for option>
712 # search for a specific option in a bunch of filesystem options
713 # and return the value
721 while [ $# -gt 0 ]; do
724 echo ${1#${_option}=}
731 if ! [[ $DRACUT_INSTALL ]]; then
732 DRACUT_INSTALL
=$
(find_binary dracut-install
)
735 if ! [[ $DRACUT_INSTALL ]] && [[ -x $dracutbasedir/dracut-install
]]; then
736 DRACUT_INSTALL
=$dracutbasedir/dracut-install
737 elif ! [[ $DRACUT_INSTALL ]] && [[ -x $dracutbasedir/install
/dracut-install
]]; then
738 DRACUT_INSTALL
=$dracutbasedir/install
/dracut-install
741 if ! [[ -x $DRACUT_INSTALL ]]; then
742 dfatal
"dracut-install not found!"
746 [[ $DRACUT_RESOLVE_LAZY ]] ||
export DRACUT_RESOLVE_DEPS
=1
748 [[ -e ${initdir}/"$1" ]] && return 0 # already there
749 $DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@"
750 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@" ||
:
754 local _hostonly_install
755 if [[ "$1" == "-H" ]]; then
756 _hostonly_install
="-H"
759 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
760 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"
761 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" ||
:
765 local _hostonly_install
766 if [[ "$1" == "-H" ]]; then
767 _hostonly_install
="-H"
770 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
771 [[ -e $1 ]] ||
return 1 # no source
772 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${_hostonly_install:+-H} "$@"
773 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${_hostonly_install:+-H} "$@" ||
:
777 local _hostonly_install
778 if [[ "$1" == "-H" ]]; then
779 _hostonly_install
="-H"
782 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
783 [[ -L $1 ]] ||
return 1
784 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"
785 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" ||
:
790 $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"
792 (($_ret != 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" ||
:
801 local _hostonly_install
802 if [[ "$1" == "-H" ]]; then
803 _hostonly_install
="-H"
806 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
807 [[ -e $1 ]] ||
return 1 # no source
808 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"
809 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" ||
:
813 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"
814 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@" ||
:
818 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"
819 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@" ||
:
824 echo "$i" >> "$initdir/lib/dracut/hostonly-files"
828 # find symlinks linked to given library file
830 # Function searches for symlinks by stripping version numbers appended to
831 # library filename, checks if it points to the same target and finally
832 # prints the list of symlinks to stdout.
835 # rev_lib_symlinks libfoo.so.8.1
836 # output: libfoo.so.8 libfoo.so
837 # (Only if libfoo.so.8 and libfoo.so exists on host system.)
839 [[ ! $1 ]] && return 0
841 local fn
="$1" orig
="$(readlink -f "$1")" links
=''
843 [[ ${fn} == *.so.
* ]] ||
return 1
845 until [[ ${fn##*.} == so
]]; do
847 [[ -L ${fn} && $(readlink -f "${fn}") == ${orig} ]] && links+=" ${fn}"
853 # attempt to install any programs specified in a udev rule
854 inst_rule_programs() {
857 if grep -qE 'PROGRAM==?"[^
"]+' "$1"; then
858 for _prog in $(grep -E 'PROGRAM==?"[^
"]+' "$1" | sed -r 's/.*PROGRAM==?"([^
"]+).*/\1/'); do
860 if [ -x ${udevdir}/$_prog ]; then
861 _bin=${udevdir}/$_prog
862 elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then
863 _bin=$(find_binary "$_prog") || {
864 dinfo "Skipping program
$_prog using
in udev rule
${1##*/} as it cannot be found
"
869 [[ $_bin ]] && inst_binary "$_bin"
872 if grep -qE 'RUN[+=]=?"[^
"]+' "$1"; then
873 for _prog in $(grep -E 'RUN[+=]=?"[^
"]+' "$1" | sed -r 's/.*RUN[+=]=?"([^
"]+).*/\1/'); do
875 if [ -x ${udevdir}/$_prog ]; then
876 _bin=${udevdir}/$_prog
877 elif [[ "${_prog/\$env\{/}" == "$_prog" ]] && [[ "${_prog}" != "/sbin
/initqueue
" ]]; then
878 _bin=$(find_binary "$_prog") || {
879 dinfo "Skipping program
$_prog using
in udev rule
${1##*/} as it cannot be found
"
884 [[ $_bin ]] && inst_binary "$_bin"
887 if grep -qE 'IMPORT\{program\}==?"[^
"]+' "$1"; then
888 for _prog in $(grep -E 'IMPORT\{program\}==?"[^
"]+' "$1" | sed -r 's/.*IMPORT\{program\}==?"([^
"]+).*/\1/'); do
890 if [ -x ${udevdir}/$_prog ]; then
891 _bin=${udevdir}/$_prog
892 elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then
893 _bin=$(find_binary "$_prog") || {
894 dinfo "Skipping program
$_prog using
in udev rule
${1##*/} as it cannot be found
"
899 [[ $_bin ]] && dracut_install "$_bin"
904 # attempt to install any programs specified in a udev rule
905 inst_rule_group_owner() {
908 if grep -qE 'OWNER=?"[^
"]+' "$1"; then
909 for i in $(grep -E 'OWNER=?"[^
"]+' "$1" | sed -r 's/.*OWNER=?"([^
"]+).*/\1/'); do
910 if ! egrep -q "^
$i:" "$initdir/etc
/passwd
" 2>/dev/null; then
911 egrep "^
$i:" /etc/passwd 2>/dev/null >> "$initdir/etc
/passwd
"
915 if grep -qE 'GROUP=?"[^
"]+' "$1"; then
916 for i in $(grep -E 'GROUP=?"[^
"]+' "$1" | sed -r 's/.*GROUP=?"([^
"]+).*/\1/'); do
917 if ! egrep -q "^
$i:" "$initdir/etc
/group
" 2>/dev/null; then
918 egrep "^
$i:" /etc/group 2>/dev/null >> "$initdir/etc
/group
"
924 inst_rule_initqueue() {
925 if grep -q -F initqueue "$1"; then
926 dracut_need_initqueue
930 # udev rules always get installed in the same place, so
931 # create a function to install them to make life simpler.
933 local _target=/etc/udev/rules.d _rule _found
935 inst_dir "${udevdir}/rules.d
"
937 for _rule in "$@
"; do
938 if [ "${_rule#/}" = "$_rule" ]; then
939 for r in ${udevdir}/rules.d ${hostonly:+/etc/udev/rules.d}; do
940 [[ -e $r/$_rule ]] || continue
942 inst_rule_programs "$_found"
943 inst_rule_group_owner "$_found"
944 inst_rule_initqueue "$_found"
945 inst_simple "$_found"
948 for r in '' $dracutbasedir/rules.d/; do
949 # skip rules without an absolute path
950 [[ "${r}$_rule" != /* ]] && continue
951 [[ -f ${r}$_rule ]] || continue
953 inst_rule_programs "$_found"
954 inst_rule_group_owner "$_found"
955 inst_rule_initqueue "$_found"
956 inst_simple "$_found" "$_target/${_found##*/}"
958 [[ $_found ]] || dinfo "Skipping udev rule
: $_rule"
962 inst_rules_wildcard() {
963 local _target=/etc/udev/rules.d _rule _found
965 inst_dir "${udevdir}/rules.d
"
967 for _rule in ${udevdir}/rules.d/$1 ${dracutbasedir}/rules.d/$1 ; do
968 [[ -e $_rule ]] || continue
969 inst_rule_programs "$_rule"
970 inst_rule_group_owner "$_rule"
971 inst_rule_initqueue "$_rule"
975 if [[ -n ${hostonly} ]] ; then
976 for _rule in ${_target}/$1 ; do
977 [[ -f $_rule ]] || continue
978 inst_rule_programs "$_rule"
979 inst_rule_group_owner "$_rule"
980 inst_rule_initqueue "$_rule"
985 [[ $_found ]] || dinfo "Skipping udev rule
: $_rule"
988 prepare_udev_rules() {
989 [ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version)
992 f="${initdir}/etc
/udev
/rules.d
/$f"
993 [ -e "$f" ] || continue
994 while read line || [ -n "$line" ]; do
995 if [ "${line%%IMPORT PATH_ID}" != "$line" ]; then
996 if [ $UDEVVERSION -ge 174 ]; then
997 printf '%sIMPORT{builtin}="path_id
"\n' "${line%%IMPORT PATH_ID}"
999 printf '%sIMPORT{program}="path_id
%%p
"\n' "${line%%IMPORT PATH_ID}"
1001 elif [ "${line%%IMPORT BLKID}" != "$line" ]; then
1002 if [ $UDEVVERSION -ge 176 ]; then
1003 printf '%sIMPORT{builtin}="blkid
"\n' "${line%%IMPORT BLKID}"
1005 printf '%sIMPORT{program}="/sbin
/blkid
-o udev
-p $tempnode"\n' "${line%%IMPORT BLKID}"
1010 done < "${f}" > "${f}.new
"
1015 # install function specialized for hooks
1016 # $1 = type of hook, $2 = hook priority (lower runs first), $3 = hook
1017 # All hooks should be POSIX/SuS compliant, they will be sourced by init.
1019 if ! [[ -f $3 ]]; then
1020 dfatal "Cannot
install a hook
($3) that does not exist.
"
1021 dfatal "Aborting initrd creation.
"
1023 elif ! [[ "$hookdirs" == *$1* ]]; then
1024 dfatal "No such hook
type $1. Aborting initrd creation.
"
1027 inst_simple "$3" "/lib
/dracut
/hooks
/${1}/${2}-${3##*/}"
1030 # install any of listed files
1032 # If first argument is '-d' and second some destination path, first accessible
1033 # source is installed into this path, otherwise it will installed in the same
1034 # path as source. If none of listed files was installed, function return 1.
1035 # On first successful installation it returns with 0 status.
1039 # inst_any -d /bin/foo /bin/bar /bin/baz
1041 # Lets assume that /bin/baz exists, so it will be installed as /bin/foo in
1046 [[ $1 = '-d' ]] && to="$2" && shift 2
1049 [[ -e $f ]] || continue
1050 [[ $to ]] && inst "$f" "$to" && return 0
1051 inst "$f" && return 0
1058 # inst_libdir_file [-n <pattern>] <file> [<file>...]
1059 # Install a <file> located on a lib directory to the initramfs image
1060 # -n <pattern> install matching files
1061 inst_libdir_file() {
1063 if [[ "$1" == "-n" ]]; then
1066 for _dir in $libdirs; do
1068 for _f in "$_dir"/$_i; do
1069 [[ "$_f" =~ $_pattern ]] || continue
1070 [[ -e "$_f" ]] && _files+="$_f "
1075 for _dir in $libdirs; do
1077 for _f in "$_dir"/$_i; do
1078 [[ -e "$_f" ]] && _files+="$_f "
1083 [[ $_files ]] && inst_multiple $_files
1087 # install function decompressing the target and handling symlinks
1088 # $@ = list of compressed (gz or bz2) files or symlinks pointing to such files
1090 # Function install targets in the same paths inside overlay but decompressed
1091 # and without extensions (.gz, .bz2).
1098 *.gz) _cmd='gzip -f -d' ;;
1099 *.bz2) _cmd='bzip2 -d' ;;
1103 # Decompress with chosen tool. We assume that tool changes name e.g.
1104 # from 'name.gz' to 'name'.
1105 ${_cmd} "${initdir}${_src}"
1109 # It's similar to above, but if file is not compressed, performs standard
1111 # $@ = list of files
1112 inst_opt_decompress
() {
1116 inst_decompress
"${_src}" || inst
"${_src}"
1120 # module_check <dracut module>
1121 # execute the check() function of module-setup.sh of <dracut module>
1122 # or the "check" script, if module-setup.sh is not found
1123 # "check $hostonly" is called
1125 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1128 local _hostonly
=$hostonly
1129 [ $# -eq 2 ] && _forced
=$2
1130 [[ -d $_moddir ]] ||
return 1
1131 if [[ ! -f $_moddir/module-setup.sh
]]; then
1132 # if we do not have a check script, we are unconditionally included
1133 [[ -x $_moddir/check
]] ||
return 0
1134 [ $_forced -ne 0 ] && unset hostonly
1135 $_moddir/check
$hostonly
1138 unset check depends cmdline
install installkernel
1140 .
$_moddir/module-setup.sh
1141 is_func check ||
return 0
1142 [ $_forced -ne 0 ] && unset hostonly
1143 moddir
=$_moddir check
$hostonly
1145 unset check depends cmdline
install installkernel
1151 # module_check_mount <dracut module>
1152 # execute the check() function of module-setup.sh of <dracut module>
1153 # or the "check" script, if module-setup.sh is not found
1154 # "mount_needs=1 check 0" is called
1155 module_check_mount
() {
1156 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1159 [[ -d $_moddir ]] ||
return 1
1160 if [[ ! -f $_moddir/module-setup.sh
]]; then
1161 # if we do not have a check script, we are unconditionally included
1162 [[ -x $_moddir/check
]] ||
return 0
1163 mount_needs
=1 $_moddir/check
0
1166 unset check depends cmdline
install installkernel
1168 .
$_moddir/module-setup.sh
1169 moddir
=$_moddir check
0
1171 unset check depends cmdline
install installkernel
1177 # module_depends <dracut module>
1178 # execute the depends() function of module-setup.sh of <dracut module>
1179 # or the "depends" script, if module-setup.sh is not found
1181 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1183 [[ -d $_moddir ]] ||
return 1
1184 if [[ ! -f $_moddir/module-setup.sh
]]; then
1185 # if we do not have a check script, we have no deps
1186 [[ -x $_moddir/check
]] ||
return 0
1190 unset check depends cmdline
install installkernel
1192 .
$_moddir/module-setup.sh
1193 moddir
=$_moddir depends
1195 unset check depends cmdline
install installkernel
1200 # module_cmdline <dracut module>
1201 # execute the cmdline() function of module-setup.sh of <dracut module>
1202 # or the "cmdline" script, if module-setup.sh is not found
1204 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1206 [[ -d $_moddir ]] ||
return 1
1207 if [[ ! -f $_moddir/module-setup.sh
]]; then
1208 [[ -x $_moddir/cmdline
]] && .
"$_moddir/cmdline"
1211 unset check depends cmdline
install installkernel
1213 .
$_moddir/module-setup.sh
1214 moddir
=$_moddir cmdline
1216 unset check depends cmdline
install installkernel
1221 # module_install <dracut module>
1222 # execute the install() function of module-setup.sh of <dracut module>
1223 # or the "install" script, if module-setup.sh is not found
1225 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1227 [[ -d $_moddir ]] ||
return 1
1228 if [[ ! -f $_moddir/module-setup.sh
]]; then
1229 [[ -x $_moddir/install ]] && .
"$_moddir/install"
1232 unset check depends cmdline
install installkernel
1234 .
$_moddir/module-setup.sh
1235 moddir
=$_moddir install
1237 unset check depends cmdline
install installkernel
1242 # module_installkernel <dracut module>
1243 # execute the installkernel() function of module-setup.sh of <dracut module>
1244 # or the "installkernel" script, if module-setup.sh is not found
1245 module_installkernel
() {
1246 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1248 [[ -d $_moddir ]] ||
return 1
1249 if [[ ! -f $_moddir/module-setup.sh
]]; then
1250 [[ -x $_moddir/installkernel
]] && .
"$_moddir/installkernel"
1253 unset check depends cmdline
install installkernel
1254 installkernel
() { true
; }
1255 .
$_moddir/module-setup.sh
1256 moddir
=$_moddir installkernel
1258 unset check depends cmdline
install installkernel
1263 # check_mount <dracut module>
1264 # check_mount checks, if a dracut module is needed for the given
1265 # device and filesystem types in "${host_fs_types[@]}"
1268 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1272 [ "${#host_fs_types[@]}" -le 0 ] && return 1
1274 # If we are already scheduled to be loaded, no need to check again.
1275 [[ " $mods_to_load " == *\
$_mod\
* ]] && return 0
1276 [[ " $mods_checked_as_dep " == *\
$_mod\
* ]] && return 1
1278 # This should never happen, but...
1279 [[ -d $_moddir ]] ||
return 1
1281 [[ $2 ]] || mods_checked_as_dep
+=" $_mod "
1283 if [[ " $omit_dracutmodules " == *\
$_mod\
* ]]; then
1287 if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\
$_mod\
* ]]; then
1288 module_check_mount
$_mod; ret
=$?
1290 # explicit module, so also accept ret=255
1291 [[ $ret = 0 ||
$ret = 255 ]] ||
return 1
1293 # module not in our list
1294 if [[ $dracutmodules = all
]]; then
1295 # check, if we can and should install this module
1296 module_check_mount
$_mod ||
return 1
1303 for _moddep
in $
(module_depends
$_mod); do
1304 # handle deps as if they were manually added
1305 [[ " $dracutmodules " == *\
$_mod\
* ]] \
1306 && [[ " $dracutmodules " != *\
$_moddep\
* ]] \
1307 && dracutmodules
+=" $_moddep "
1308 [[ " $add_dracutmodules " == *\
$_mod\
* ]] \
1309 && [[ " $add_dracutmodules " != *\
$_moddep\
* ]] \
1310 && add_dracutmodules
+=" $_moddep "
1311 [[ " $force_add_dracutmodules " == *\
$_mod\
* ]] \
1312 && [[ " $force_add_dracutmodules " != *\
$_moddep\
* ]] \
1313 && force_add_dracutmodules
+=" $_moddep "
1314 # if a module we depend on fail, fail also
1315 if ! check_module
$_moddep; then
1316 derror
"dracut module '$_mod' depends on '$_moddep', which can't be installed"
1321 [[ " $mods_to_load " == *\
$_mod\
* ]] || \
1322 mods_to_load
+=" $_mod "
1327 # check_module <dracut module> [<use_as_dep>]
1328 # check if a dracut module is to be used in the initramfs process
1329 # if <use_as_dep> is set, then the process also keeps track
1330 # that the modules were checked for the dependency tracking process
1333 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1336 # If we are already scheduled to be loaded, no need to check again.
1337 [[ " $mods_to_load " == *\
$_mod\
* ]] && return 0
1338 [[ " $mods_checked_as_dep " == *\
$_mod\
* ]] && return 1
1340 # This should never happen, but...
1341 [[ -d $_moddir ]] ||
return 1
1343 [[ $2 ]] || mods_checked_as_dep
+=" $_mod "
1345 if [[ " $omit_dracutmodules " == *\
$_mod\
* ]]; then
1346 dinfo
"dracut module '$_mod' will not be installed, because it's in the list to be omitted!"
1350 if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\
$_mod\
* ]]; then
1351 if [[ " $dracutmodules $force_add_dracutmodules " == *\
$_mod\
* ]]; then
1352 module_check
$_mod 1; ret
=$?
1354 module_check
$_mod 0; ret
=$?
1356 # explicit module, so also accept ret=255
1357 [[ $ret = 0 ||
$ret = 255 ]] ||
return 1
1359 # module not in our list
1360 if [[ $dracutmodules = all
]]; then
1361 # check, if we can and should install this module
1362 module_check
$_mod; ret
=$?
1363 if [[ $ret != 0 ]]; then
1364 [[ $2 ]] && return 1
1365 [[ $ret != 255 ]] && return 1
1373 for _moddep
in $
(module_depends
$_mod); do
1374 # handle deps as if they were manually added
1375 [[ " $dracutmodules " == *\
$_mod\
* ]] \
1376 && [[ " $dracutmodules " != *\
$_moddep\
* ]] \
1377 && dracutmodules
+=" $_moddep "
1378 [[ " $add_dracutmodules " == *\
$_mod\
* ]] \
1379 && [[ " $add_dracutmodules " != *\
$_moddep\
* ]] \
1380 && add_dracutmodules
+=" $_moddep "
1381 [[ " $force_add_dracutmodules " == *\
$_mod\
* ]] \
1382 && [[ " $force_add_dracutmodules " != *\
$_moddep\
* ]] \
1383 && force_add_dracutmodules
+=" $_moddep "
1384 # if a module we depend on fail, fail also
1385 if ! check_module
$_moddep; then
1386 derror
"dracut module '$_mod' depends on '$_moddep', which can't be installed"
1391 [[ " $mods_to_load " == *\
$_mod\
* ]] || \
1392 mods_to_load
+=" $_mod "
1397 # for_each_module_dir <func>
1398 # execute "<func> <dracut module> 1"
1399 for_each_module_dir
() {
1405 for _moddir
in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
1406 [[ -d $_moddir ]] ||
continue;
1407 [[ -e $_moddir/install ||
-e $_moddir/installkernel || \
1408 -e $_moddir/module-setup.sh
]] ||
continue
1409 _mod
=${_moddir##*/}; _mod
=${_mod#[0-9][0-9]}
1413 # Report any missing dracut modules, the user has specified
1414 _modcheck
="$add_dracutmodules $force_add_dracutmodules"
1415 [[ $dracutmodules != all
]] && _modcheck
="$_modcheck $dracutmodules"
1416 for _mod
in $_modcheck; do
1417 [[ " $mods_to_load " == *\
$_mod\
* ]] && continue
1419 [[ " $force_add_dracutmodules " != *\
$_mod\
* ]] \
1420 && [[ " $dracutmodules " != *\
$_mod\
* ]] \
1421 && [[ " $omit_dracutmodules " == *\
$_mod\
* ]] \
1424 derror
"dracut module '$_mod' cannot be found or installed."
1425 [[ " $force_add_dracutmodules " == *\
$_mod\
* ]] && exit 1
1426 [[ " $dracutmodules " == *\
$_mod\
* ]] && exit 1
1427 [[ " $add_dracutmodules " == *\
$_mod\
* ]] && exit 1
1431 # Install a single kernel module along with any firmware it may require.
1432 # $1 = full path to kernel module to install
1433 install_kmod_with_fw
() {
1434 # no need to go further if the module is already installed
1436 [[ -e "${initdir}/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" ]] \
1439 if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -e "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}" ]]; then
1440 read ret
< "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
1444 if [[ $omit_drivers ]]; then
1445 local _kmod
=${1##*/}
1448 if [[ "$_kmod" =~
$omit_drivers ]]; then
1449 dinfo
"Omitting driver $_kmod"
1452 if [[ "${1##*/lib/modules/$kernel/}" =~
$omit_drivers ]]; then
1453 dinfo
"Omitting driver $_kmod"
1458 if [[ $silent_omit_drivers ]]; then
1459 local _kmod
=${1##*/}
1462 [[ "$_kmod" =~
$silent_omit_drivers ]] && return 0
1463 [[ "${1##*/lib/modules/$kernel/}" =~
$silent_omit_drivers ]] && return 0
1466 inst_simple
"$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}"
1468 [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
1469 [[ -d "$DRACUT_KERNEL_LAZY_HASHDIR" ]] && \
1470 echo $ret > "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
1471 (($ret != 0)) && return $ret
1473 local _modname
=${1##*/} _fwdir _found _fw
1474 _modname
=${_modname%.ko*}
1475 for _fw
in $
(modinfo
-k $kernel -F firmware
$1 2>/dev
/null
); do
1477 for _fwdir
in $fw_dir; do
1478 [[ -d $_fwdir && -f $_fwdir/$_fw ]] ||
continue
1479 inst_simple
"$_fwdir/$_fw" "/lib/firmware/$_fw"
1482 if [[ $_found != yes ]]; then
1483 if ! [[ -d $
(echo /sys
/module
/${_modname//-/_}|
{ read a b
; echo $a; }) ]]; then
1484 dinfo
"Possible missing firmware \"${_fw}\" for kernel module" \
1485 "\"${_modname}.ko\""
1487 dwarn
"Possible missing firmware \"${_fw}\" for kernel module" \
1488 "\"${_modname}.ko\""
1495 # Do something with all the dependencies of a kernel module.
1496 # Note that kernel modules depend on themselves using the technique we use
1497 # $1 = function to call for each dependency we find
1498 # It will be passed the full path to the found kernel module
1499 # $2 = module to get dependencies for
1500 # rest of args = arguments to modprobe
1501 # _fderr specifies FD passed from surrounding scope
1502 for_each_kmod_dep
() {
1503 local _func
=$1 _kmod
=$2 _cmd _modpath _options
1505 modprobe
"$@" --ignore-install --show-depends $_kmod 2>&${_fderr} |
(
1506 while read _cmd _modpath _options ||
[ -n "$_cmd" ]; do
1507 [[ $_cmd = insmod
]] ||
continue
1508 $_func ${_modpath} ||
exit $?
1513 dracut_kernel_post
() {
1514 local _moddirname
=${srcmods%%/lib/modules/*}
1517 if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" ]]; then
1518 xargs -r modprobe
-a ${_moddirname:+-d ${_moddirname}/} \
1519 --ignore-install --show-depends --set-version $kernel \
1520 < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" 2>/dev
/null \
1522 |
while read _cmd _modpath _options ||
[ -n "$_cmd" ]; do
1523 [[ $_cmd = insmod
]] ||
continue
1525 done > "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
1528 if [[ $DRACUT_INSTALL ]] && [[ -z $_moddirname ]]; then
1529 xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} -a < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
1531 while read _modpath ||
[ -n "$_modpath" ]; do
1532 local _destpath
=$_modpath
1533 [[ $_moddirname ]] && _destpath
=${_destpath##$_moddirname/}
1534 _destpath
=${_destpath##*/lib/modules/$kernel/}
1535 inst_simple
"$_modpath" "/lib/modules/$kernel/${_destpath}" ||
exit $?
1536 done < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
1539 _pid
=$
(jobs -p |
while read a ||
[ -n "$a" ]; do printf ":$a";done)
1542 if [[ $DRACUT_INSTALL ]]; then
1543 xargs -r modinfo
-k $kernel -F firmware
< "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep" \
1544 |
while read line ||
[ -n "$line" ]; do
1545 for _fwdir
in $fw_dir; do
1548 done |
xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} -a -o
1550 for _fw
in $
(xargs -r modinfo
-k $kernel -F firmware
< "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"); do
1551 for _fwdir
in $fw_dir; do
1552 [[ -d $_fwdir && -f $_fwdir/$_fw ]] ||
continue
1553 inst_simple
"$_fwdir/$_fw" "/lib/firmware/$_fw"
1562 for _f
in modules.
builtin.bin modules.
builtin modules.order
; do
1563 [[ $srcmods/$_f ]] && inst_simple
"$srcmods/$_f" "/lib/modules/$kernel/$_f"
1566 # generate module dependencies for the initrd
1567 if [[ -d $initdir/lib
/modules
/$kernel ]] && \
1568 ! depmod
-a -b "$initdir" $kernel; then
1569 dfatal
"\"depmod -a $kernel\" failed."
1573 [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && rm -fr -- "$DRACUT_KERNEL_LAZY_HASHDIR"
1576 [[ "$kernel_current" ]] ||
export kernel_current
=$
(uname
-r)
1578 module_is_host_only
() {
1580 local _modenc a i _k _s _v _aliases
1583 _modenc
=${_mod//-/_}
1585 [[ " $add_drivers " == *\
${_mod}\
* ]] && return 0
1587 # check if module is loaded
1588 [[ ${host_modules["$_modenc"]} ]] && return 0
1590 [[ "$kernel_current" ]] ||
export kernel_current
=$
(uname
-r)
1592 if [[ "$kernel_current" != "$kernel" ]]; then
1593 # check if module is loadable on the current kernel
1594 # this covers the case, where a new module is introduced
1595 # or a module was renamed
1596 # or a module changed from builtin to a module
1598 if [[ -d /lib
/modules
/$kernel_current ]]; then
1599 # if the modinfo can be parsed, but the module
1600 # is not loaded, then we can safely return 1
1601 modinfo
-F filename
"$_mod" &>/dev
/null
&& return 1
1604 _aliases
=$
(modinfo
-k $kernel -F alias $_mod 2>/dev
/null
)
1606 # if the module has no aliases, install it
1607 [[ $_aliases ]] ||
return 0
1609 # finally check all modalias
1610 for a
in $_aliases; do
1611 for i
in "${!host_modalias[@]}"; do
1612 [[ $i == $a ]] && return 0
1621 find_kernel_modules_by_path
() {
1624 [[ -f "$srcmods/modules.dep" ]] ||
return 0
1628 while read a rest ||
[ -n "$a" ]; do
1629 [[ $a = */$1/* ]] ||
[[ $a = updates
/* ]] ||
continue
1630 printf "%s\n" "$srcmods/$a"
1631 done < "$srcmods/modules.dep"
1636 find_kernel_modules
() {
1637 find_kernel_modules_by_path drivers
1640 # instmods [-c [-s]] <kernel module> [<kernel module> ... ]
1641 # instmods [-c [-s]] <kernel subsystem>
1642 # install kernel modules along with all their dependencies.
1643 # <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
1645 [[ $no_kernel = yes ]] && return
1646 # called [sub]functions inherit _fderr
1650 if [[ $1 = '-c' ]]; then
1655 if [[ $1 = '-s' ]]; then
1660 function inst1mod
() {
1661 local _ret
=0 _mod
="$1"
1664 ( [[ "$_mpargs" ]] && echo $_mpargs
1665 find_kernel_modules_by_path
"${_mod#=}" ) \
1669 --*) _mpargs
+=" $_mod" ;;
1672 # Check for aliased modules
1673 _modalias
=$
(modinfo
-k $kernel -F filename
$_mod 2> /dev
/null
)
1674 _modalias
=${_modalias%.ko*}
1675 if [[ $_modalias ]] && [ "${_modalias##*/}" != "${_mod%.ko*}" ] ; then
1676 _mod
=${_modalias##*/}
1679 # if we are already installed, skip this module and go on
1681 if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
1682 [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko*}" ]]; then
1683 read _ret
<"$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko*}"
1688 if [[ $omit_drivers ]] && [[ "$_mod" =~
$omit_drivers ]]; then
1689 dinfo
"Omitting driver ${_mod##$srcmods}"
1693 # If we are building a host-specific initramfs and this
1694 # module is not already loaded, move on to the next one.
1696 && ! module_is_host_only
"$_mod" \
1699 if [[ "$_check" = "yes" ]] ||
! [[ $DRACUT_KERNEL_LAZY_HASHDIR ]]; then
1700 # We use '-d' option in modprobe only if modules prefix path
1701 # differs from default '/'. This allows us to use dracut with
1702 # old version of modprobe which doesn't have '-d' option.
1703 local _moddirname
=${srcmods%%/lib/modules/*}
1704 [[ -n ${_moddirname} ]] && _moddirname
="-d ${_moddirname}/"
1706 # ok, load the module, all its dependencies, and any firmware
1708 for_each_kmod_dep install_kmod_with_fw
$_mod \
1709 --set-version $kernel ${_moddirname} $_mpargs
1712 [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
1713 echo ${_mod%.ko*} >> "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist"
1720 function instmods_1
() {
1722 if (($# == 0)); then # filenames from stdin
1723 while read _mod ||
[ -n "$_mod" ]; do
1724 inst1mod
"${_mod%.ko*}" ||
{
1725 if [[ "$_check" == "yes" ]] && [[ "$_silent" == "no" ]]; then
1726 dfatal
"Failed to install module $_mod"
1731 while (($# > 0)); do # filenames as arguments
1732 inst1mod
${1%.ko*} ||
{
1733 if [[ "$_check" == "yes" ]] && [[ "$_silent" == "no" ]]; then
1734 dfatal
"Failed to install module $1"
1742 local _ret _filter_not_found
='FATAL: Module .* not found.'
1743 # Capture all stderr from modprobe to _fderr. We could use {var}>...
1744 # redirections, but that would make dracut require bash4 at least.
1745 eval "( instmods_1 \"\$@\" ) ${_fderr}>&1" \
1746 |
while read line ||
[ -n "$line" ]; do [[ "$line" =~
$_filter_not_found ]] ||
echo $line;done | derror
1751 check_kernel_config
()
1753 local _config_opt
="$1"
1755 [[ -f /boot
/config-
$kernel ]] \
1756 && _config_file
="/boot/config-$kernel"
1757 [[ -f /lib
/modules
/$kernel/config
]] \
1758 && _config_file
="/lib/modules/$kernel/config"
1760 # no kernel config file, so return true
1761 [[ $_config_file ]] ||
return 0
1763 grep -q -F "${_config_opt}=" "$_config_file" && return 0
1769 # Only two values are returned: AMD or Intel
1772 if grep -qE AMD
/proc
/cpuinfo
; then
1775 if grep -qE Intel
/proc
/cpuinfo
; then
1781 # Get the hosts' ucode file based on the /proc/cpuinfo
1784 local family
=`grep -E "cpu family" /proc/cpuinfo | head -1 | sed s/.*:\ //`
1785 local model
=`grep -E "model" /proc/cpuinfo |grep -v name | head -1 | sed s/.*:\ //`
1786 local stepping
=`grep -E "stepping" /proc/cpuinfo | head -1 | sed s/.*:\ //`
1788 if [[ "$(get_cpu_vendor)" == "AMD" ]]; then
1789 # If family greater or equal than 0x15
1790 if [[ $family -ge 21 ]]; then
1791 printf "microcode_amd_fam15h.bin"
1793 printf "microcode_amd.bin"
1796 if [[ "$(get_cpu_vendor)" == "Intel" ]]; then
1797 # The /proc/cpuinfo are in decimal.
1798 printf "%02x-%02x-%02x" ${family} ${model} ${stepping}
1802 # Not every device in /dev/mapper should be examined.
1803 # If it is an LVM device, touch only devices which have /dev/VG/LV symlink.
1804 lvm_internal_dev
() {
1805 local dev_dm_dir
=/sys
/dev
/block
/$1/dm
1806 [[ ! -f $dev_dm_dir/uuid || $
(<$dev_dm_dir/uuid
) != LVM-
* ]] && return 1 # Not an LVM device
1807 local DM_VG_NAME DM_LV_NAME DM_LV_LAYER
1808 eval $
(dmsetup splitname
--nameprefixes --noheadings --rows "$(<$dev_dm_dir/name)" 2>/dev
/null
)
1809 [[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] ||
return 0 # Better skip this!
1810 [[ ${DM_LV_LAYER} ]] || [[ ! -L /dev/${DM_VG_NAME}/${DM_LV_NAME} ]]
1815 btrfs device usage
"$_mp" \
1816 |
while read _dev _rest
; do
1817 str_starts
"$_dev" "/" ||
continue
1819 printf -- "%s\n" "$_dev"