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 mkdir
-p "$initdir/.kernelmodseen"
26 DRACUT_KERNEL_LAZY_HASHDIR
="$initdir/.kernelmodseen"
29 if [[ $initdir ]] && ! [[ -d $initdir ]]; then
33 # Generic substring function. If $2 is in $1, return 0.
34 strstr
() { [[ $1 = *"$2"* ]]; }
35 # Generic glob matching function. If glob pattern $2 matches anywhere in $1, OK
36 strglobin
() { [[ $1 = *$2* ]]; }
37 # Generic glob matching function. If glob pattern $2 matches all of $1, OK
38 strglob
() { [[ $1 = $2 ]]; }
40 # helper function for check() in module-setup.sh
41 # to check for required installed binaries
42 # issues a standardized warning message
44 local _module_name
="${moddir##*/}"
47 if [[ "$1" = "-m" ]]; then
53 if ! find_binary
"$cmd" &>/dev
/null
; then
54 dinfo
"dracut module '${_module_name#[0-9][0-9]}' will not be installed, because command '$cmd' could not be found!"
61 require_any_binary
() {
62 local _module_name
="${moddir##*/}"
65 if [[ "$1" = "-m" ]]; then
71 if find_binary
"$cmd" &>/dev
/null
; then
77 if (( $_ret != 0 )); then
78 dinfo
"$_module_name: Could not find any command of '$@'!"
85 # find a binary. If we were not passed the full path directly,
86 # search in the usual places to find the binary.
88 if [[ -z ${1##/*} ]]; then
89 if [[ -x $1 ]] ||
{ [[ "$1" == *.so
* ]] && ldd
"$1" &>/dev
/null
; }; then
98 if ! [[ $dracutbasedir ]]; then
99 dracutbasedir
=${BASH_SOURCE[0]%/*}
100 [[ $dracutbasedir = "dracut-functions" ]] && dracutbasedir
="."
101 [[ $dracutbasedir ]] || dracutbasedir
="."
102 dracutbasedir
="$(readlink -f $dracutbasedir)"
107 ldconfig
-pN 2>/dev
/null |
grep -E -v '/(lib|lib64|usr/lib|usr/lib64)/[^/]*$' |
sed -n 's,.* => \(.*\)/.*,\1,p' |
sort |
uniq
111 if ! [[ $libdirs ]] ; then
112 if [[ "$(ldd /bin/sh)" == */lib64
/* ]] &>/dev
/null \
113 && [[ -d /lib64
]]; then
115 [[ -d /usr
/lib64
]] && libdirs
+=" /usr/lib64"
118 [[ -d /usr
/lib
]] && libdirs
+=" /usr/lib"
121 libdirs
+=" $(ldconfig_paths)"
126 if ! [[ $kernel ]]; then
131 # Version comparision function. Assumes Linux style version scheme.
133 # $2 = comparision op (gt, ge, eq, le, lt, ne)
136 local _n1
=(${1//./ }) _op
=$2 _n2
=(${3//./ }) _i _res
140 if [[ ! ${_n1[_i]}${_n2[_i]} ]]; then _res
=0
141 elif ((${_n1[_i]:-0} > ${_n2[_i]:-0})); then _res
=1
142 elif ((${_n1[_i]:-0} < ${_n2[_i]:-0})); then _res
=2
158 srcmods
="/lib/modules/$kernel/"
160 [[ $drivers_dir ]] && {
161 if ! command -v kmod
&>/dev
/null
&& vercmp
"$(modprobe --version | cut -d' ' -f3)" lt
3.7; then
162 dfatal
'To use --kmoddir option module-init-tools >= 3.7 is required.'
165 srcmods
="$drivers_dir"
170 # Check whether $1 is a function.
172 [[ "$(type -t "$1")" = "function" ]]
175 if ! is_func dinfo
>/dev
/null
2>&1; then
176 .
"$dracutbasedir/dracut-logger.sh"
180 if ! [[ $initdir ]]; then
181 dfatal
"initdir not set"
185 # export standard hookdirs
187 hookdirs
="cmdline pre-udev pre-trigger netroot "
188 hookdirs
+="initqueue initqueue/settled initqueue/online initqueue/finished initqueue/timeout "
189 hookdirs
+="pre-mount pre-pivot cleanup mount "
190 hookdirs
+="emergency shutdown-emergency pre-shutdown shutdown "
194 dracut_need_initqueue
() {
195 >"$initdir/lib/dracut/need-initqueue"
198 dracut_module_included
() {
199 [[ " $mods_to_load $modules_loaded " == *\ $
*\
* ]]
202 # Create all subdirectories for given path without creating the last element.
205 [[ -e ${1%/*} ]] || mkdir
-m 0755 -p -- "${1%/*}"
208 # Function prints global variables in format name=value line by line.
209 # $@ = list of global variables' name
215 eval printf -v _value
"%s" \""\$$_var"\"
216 [[ ${_value} ]] && printf '%s="%s"\n' "$_var" "$_value"
220 # normalize_path <path>
221 # Prints the normalized path, where it removes any duplicated
222 # and trailing slashes.
224 # $ normalize_path ///test/test//
228 set -- "${1//+(\/)//}"
230 printf "%s\n" "${1%/}"
233 # convert_abs_rel <from> <to>
234 # Prints the relative path, when creating a symlink to <to> from <from>.
236 # $ convert_abs_rel /usr/bin/test /bin/test-2
238 # $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test
240 local __current __absolute __abssize __cursize __newpath
243 set -- "$(normalize_path "$1")" "$(normalize_path "$2")"
245 # corner case #1 - self looping link
246 [[ "$1" == "$2" ]] && { printf "%s\n" "${1##*/}"; return; }
248 # corner case #2 - own dir link
249 [[ "${1%/*}" == "$2" ]] && { printf ".\n"; return; }
251 IFS
="/" __current
=($1)
252 IFS
="/" __absolute
=($2)
254 __abssize
=${#__absolute[@]}
255 __cursize
=${#__current[@]}
257 while [[ "${__absolute[__level]}" == "${__current[__level]}" ]]
260 if (( __level
> __abssize || __level
> __cursize
))
266 for ((__i
= __level
; __i
< __cursize-1
; __i
++))
270 __newpath
=$__newpath"/"
272 __newpath
=$__newpath".."
275 for ((__i
= __level
; __i
< __abssize
; __i
++))
277 if [[ -n $__newpath ]]
279 __newpath
=$__newpath"/"
281 __newpath
=$__newpath${__absolute[__i]}
284 printf "%s\n" "$__newpath"
287 if [[ "$(ln --help)" == *--relative* ]]; then
289 ln -sfnr "${initdir}/$1" "${initdir}/$2"
295 [[ -d "${_dest%/*}" ]] && _dest=$(readlink -f "${_dest%/*}")/${_dest##*/}
296 ln -sfn -- "$
(convert_abs_rel
"${_dest}" "${_source}")" "${initdir}/${_dest}"
300 # get_fs_env <device>
301 # Get and the ID_FS_TYPE variable from udev for a device.
303 # $ get_fs_env /dev/sda2
311 ID_FS_TYPE
=$
(blkid
-u filesystem
-o export -- "$1" \
312 |
while read line ||
[ -n "$line" ]; do
313 if [[ "$line" == TYPE\
=* ]]; then
314 printf "%s" "${line#TYPE=}";
318 if [[ $ID_FS_TYPE ]]; then
319 printf "%s" "$ID_FS_TYPE"
325 # get_maj_min <device>
326 # Prints the major and minor of a device node.
328 # $ get_maj_min /dev/sda2
331 local _maj _min _majmin
332 _majmin
="$(stat -L -c '%t:%T' "$1" 2>/dev/null)"
333 printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))"
337 # get_devpath_block <device>
338 # get the DEVPATH in /sys of a block device
339 get_devpath_block
() {
341 _majmin
=$
(get_maj_min
"$1")
343 for _i
in /sys
/block
/*/dev
/sys
/block
/*/*/dev
; do
344 [[ -e "$_i" ]] ||
continue
345 if [[ "$_majmin" == "$(<"$_i")" ]]; then
346 printf "%s" "${_i%/dev}"
353 # get a persistent path from a device
354 get_persistent_dev
() {
357 _dev
=$
(get_maj_min
"$1")
358 [ -z "$_dev" ] && return
362 /dev
/disk
/${persistent_policy:-by-uuid}/* \
363 /dev
/disk
/by-uuid
/* \
364 /dev
/disk
/by-label
/* \
365 /dev
/disk
/by-partuuid
/* \
366 /dev
/disk
/by-partlabel
/* \
368 /dev
/disk
/by-path
/* \
370 [[ -e "$i" ]] ||
continue
371 [[ $i == /dev
/mapper
/control
]] && continue
372 [[ $i == /dev
/mapper
/mpath
* ]] && continue
373 _tmp
=$
(get_maj_min
"$i")
374 if [ "$_tmp" = "$_dev" ]; then
382 expand_persistent_dev
() {
387 _dev
="/dev/disk/by-label/${_dev#LABEL=}"
392 _dev
="/dev/disk/by-uuid/${_dev}"
395 _dev
="${_dev#PARTUUID=}"
397 _dev
="/dev/disk/by-partuuid/${_dev}"
400 _dev
="/dev/disk/by-partlabel/${_dev#PARTLABEL=}"
406 shorten_persistent_dev
() {
410 printf "%s" "UUID=${_dev##*/}";;
411 /dev
/disk
/by-label
/*)
412 printf "%s" "LABEL=${_dev##*/}";;
413 /dev
/disk
/by-partuuid
/*)
414 printf "%s" "PARTUUID=${_dev##*/}";;
415 /dev
/disk
/by-partlabel
/*)
416 printf "%s" "PARTLABEL=${_dev##*/}";;
418 printf "%s" "$_dev";;
422 # find_block_device <mountpoint>
423 # Prints the major and minor number of the block device
424 # for a given mountpoint.
425 # Unless $use_fstab is set to "yes" the functions
426 # uses /proc/self/mountinfo as the primary source of the
427 # information and only falls back to /etc/fstab, if the mountpoint
428 # is not found there.
430 # $ find_block_device /usr
432 find_block_device
() {
433 local _majmin _dev _majmin _find_mpt
435 if [[ $use_fstab != yes ]]; then
436 [[ -d $_find_mpt/.
]]
437 findmnt
-e -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" |
{ \
438 while read _majmin _dev ||
[ -n "$_dev" ]; do
439 if [[ -b $_dev ]]; then
440 if ! [[ $_majmin ]] ||
[[ $_majmin == 0:* ]]; then
441 _majmin
=$
(get_maj_min
$_dev)
443 if [[ $_majmin ]]; then
444 printf "%s\n" "$_majmin"
446 printf "%s\n" "$_dev"
450 if [[ $_dev = *:* ]]; then
451 printf "%s\n" "$_dev"
454 done; return 1; } && return 0
456 # fall back to /etc/fstab
458 findmnt
-e --fstab -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" |
{ \
459 while read _majmin _dev ||
[ -n "$_dev" ]; do
460 if ! [[ $_dev ]]; then
464 if [[ -b $_dev ]]; then
465 [[ $_majmin ]] || _majmin
=$
(get_maj_min
$_dev)
466 if [[ $_majmin ]]; then
467 printf "%s\n" "$_majmin"
469 printf "%s\n" "$_dev"
473 if [[ $_dev = *:* ]]; then
474 printf "%s\n" "$_dev"
477 done; return 1; } && return 0
482 # find_mp_fstype <mountpoint>
483 # Echo the filesystem type for a given mountpoint.
484 # /proc/self/mountinfo is taken as the primary source of information
485 # and /etc/fstab is used as a fallback.
486 # No newline is appended!
488 # $ find_mp_fstype /;echo
493 if [[ $use_fstab != yes ]]; then
494 findmnt
-e -v -n -o 'FSTYPE' --target "$1" |
{ \
495 while read _fs ||
[ -n "$_fs" ]; do
496 [[ $_fs ]] ||
continue
497 [[ $_fs = "autofs" ]] && continue
500 done; return 1; } && return 0
503 findmnt
--fstab -e -v -n -o 'FSTYPE' --target "$1" |
{ \
504 while read _fs ||
[ -n "$_fs" ]; do
505 [[ $_fs ]] ||
continue
506 [[ $_fs = "autofs" ]] && continue
509 done; return 1; } && return 0
514 # find_dev_fstype <device>
515 # Echo the filesystem type for a given device.
516 # /proc/self/mountinfo is taken as the primary source of information
517 # and /etc/fstab is used as a fallback.
518 # No newline is appended!
520 # $ find_dev_fstype /dev/sda2;echo
525 if ! [[ "$_find_dev" = /dev
* ]]; then
526 [[ -b "/dev/block/$_find_dev" ]] && _find_dev
="/dev/block/$_find_dev"
529 if [[ $use_fstab != yes ]]; then
530 findmnt
-e -v -n -o 'FSTYPE' --source "$_find_dev" |
{ \
531 while read _fs ||
[ -n "$_fs" ]; do
532 [[ $_fs ]] ||
continue
533 [[ $_fs = "autofs" ]] && continue
536 done; return 1; } && return 0
539 findmnt
--fstab -e -v -n -o 'FSTYPE' --source "$_find_dev" |
{ \
540 while read _fs ||
[ -n "$_fs" ]; do
541 [[ $_fs ]] ||
continue
542 [[ $_fs = "autofs" ]] && continue
545 done; return 1; } && return 0
550 # find_mp_fsopts <mountpoint>
551 # Echo the filesystem options for a given mountpoint.
552 # /proc/self/mountinfo is taken as the primary source of information
553 # and /etc/fstab is used as a fallback.
554 # No newline is appended!
556 # $ find_mp_fsopts /;echo
557 # rw,relatime,discard,data=ordered
559 if [[ $use_fstab != yes ]]; then
560 findmnt
-e -v -n -o 'OPTIONS' --target "$1" 2>/dev
/null
&& return 0
563 findmnt
--fstab -e -v -n -o 'OPTIONS' --target "$1"
566 # find_dev_fsopts <device>
567 # Echo the filesystem options for a given device.
568 # /proc/self/mountinfo is taken as the primary source of information
569 # and /etc/fstab is used as a fallback.
571 # $ find_dev_fsopts /dev/sda2
572 # rw,relatime,discard,data=ordered
574 local _find_dev _opts
576 if ! [[ "$_find_dev" = /dev
* ]]; then
577 [[ -b "/dev/block/$_find_dev" ]] && _find_dev
="/dev/block/$_find_dev"
580 if [[ $use_fstab != yes ]]; then
581 findmnt
-e -v -n -o 'OPTIONS' --source "$_find_dev" 2>/dev
/null
&& return 0
584 findmnt
--fstab -e -v -n -o 'OPTIONS' --source "$_find_dev"
588 # finds the major:minor of the block device backing the root filesystem.
589 find_root_block_device
() { find_block_device
/; }
591 # for_each_host_dev_fs <func>
592 # Execute "<func> <dev> <filesystem>" for every "<dev> <fs>" pair found
593 # in ${host_fs_types[@]}
594 for_each_host_dev_fs
()
600 [[ "${!host_fs_types[@]}" ]] ||
return 0
602 for _dev
in "${!host_fs_types[@]}"; do
603 $_func "$_dev" "${host_fs_types[$_dev]}" && _ret
=0
610 printf "%s\n" "${host_fs_types[@]}"
613 # Walk all the slave relationships for a given block device.
614 # Stop when our helper function returns success
615 # $1 = function to call on every found block device
616 # $2 = block device in major:minor format
617 check_block_and_slaves
() {
619 [[ -b /dev
/block
/$2 ]] ||
return 1 # Not a block device? So sorry.
620 if ! lvm_internal_dev
$2; then "$1" $2 && return; fi
621 check_vol_slaves
"$@" && return 0
622 if [[ -f /sys
/dev
/block
/$2/..
/dev
]]; then
623 check_block_and_slaves
$1 $
(<"/sys/dev/block/$2/../dev") && return 0
625 [[ -d /sys
/dev
/block
/$2/slaves
]] ||
return 1
626 for _x
in /sys
/dev
/block
/$2/slaves
/*/dev
; do
627 [[ -f $_x ]] ||
continue
628 check_block_and_slaves
$1 $
(<"$_x") && return 0
633 check_block_and_slaves_all
() {
635 [[ -b /dev
/block
/$2 ]] ||
return 1 # Not a block device? So sorry.
636 if ! lvm_internal_dev
$2 && "$1" $2; then
639 check_vol_slaves
"$@" && return 0
640 if [[ -f /sys
/dev
/block
/$2/..
/dev
]]; then
641 check_block_and_slaves_all
$1 $
(<"/sys/dev/block/$2/../dev") && _ret
=0
643 [[ -d /sys
/dev
/block
/$2/slaves
]] ||
return 1
644 for _x
in /sys
/dev
/block
/$2/slaves
/*/dev
; do
645 [[ -f $_x ]] ||
continue
646 check_block_and_slaves_all
$1 $
(<"$_x") && _ret
=0
650 # for_each_host_dev_and_slaves <func>
651 # Execute "<func> <dev>" for every "<dev>" found
652 # in ${host_devs[@]} and their slaves
653 for_each_host_dev_and_slaves_all
()
659 [[ "${host_devs[@]}" ]] ||
return 0
661 for _dev
in ${host_devs[@]}; do
662 [[ -b "$_dev" ]] ||
continue
663 if check_block_and_slaves_all
$_func $
(get_maj_min
$_dev); then
670 for_each_host_dev_and_slaves
()
675 [[ "${host_devs[@]}" ]] ||
return 0
677 for _dev
in ${host_devs[@]}; do
678 [[ -b "$_dev" ]] ||
continue
679 check_block_and_slaves
$_func $
(get_maj_min
$_dev) && return 0
684 # ugly workaround for the lvm design
685 # There is no volume group device,
686 # so, there are no slave devices for volume groups.
687 # Logical volumes only have the slave devices they really live on,
688 # but you cannot create the logical volume without the volume group.
689 # And the volume group might be bigger than the devices the LV needs.
691 local _lv _vg _pv _dm
692 for i
in /dev
/mapper
/*; do
693 [[ $i == /dev
/mapper
/control
]] && continue
694 _lv
=$
(get_maj_min
$i)
695 _dm
=/sys
/dev
/block
/$_lv/dm
696 [[ -f $_dm/uuid
&& $
(<$_dm/uuid
) =~ LVM-
* ]] ||
continue
697 if [[ $_lv = $2 ]]; then
698 _vg
=$
(lvm lvs
--noheadings -o vg_name
$i 2>/dev
/null
)
700 _vg
=$
(printf "%s\n" "$_vg")
702 for _pv
in $
(lvm vgs
--noheadings -o pv_name
"$_vg" 2>/dev
/null
)
704 check_block_and_slaves
$1 $
(get_maj_min
$_pv) && return 0
712 # fs_get_option <filesystem options> <search for option>
713 # search for a specific option in a bunch of filesystem options
714 # and return the value
722 while [ $# -gt 0 ]; do
725 echo ${1#${_option}=}
732 if ! [[ $DRACUT_INSTALL ]]; then
733 DRACUT_INSTALL
=$
(find_binary dracut-install
)
736 if ! [[ $DRACUT_INSTALL ]] && [[ -x $dracutbasedir/dracut-install
]]; then
737 DRACUT_INSTALL
=$dracutbasedir/dracut-install
738 elif ! [[ $DRACUT_INSTALL ]] && [[ -x $dracutbasedir/install
/dracut-install
]]; then
739 DRACUT_INSTALL
=$dracutbasedir/install
/dracut-install
742 if ! [[ -x $DRACUT_INSTALL ]]; then
743 dfatal
"dracut-install not found!"
747 [[ $DRACUT_RESOLVE_LAZY ]] ||
export DRACUT_RESOLVE_DEPS
=1
749 [[ -e ${initdir}/"$1" ]] && return 0 # already there
750 $DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@"
751 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@" ||
:
755 local _hostonly_install
756 if [[ "$1" == "-H" ]]; then
757 _hostonly_install
="-H"
760 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
761 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"
762 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" ||
:
766 local _hostonly_install
767 if [[ "$1" == "-H" ]]; then
768 _hostonly_install
="-H"
771 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
772 [[ -e $1 ]] ||
return 1 # no source
773 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${_hostonly_install:+-H} "$@"
774 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${_hostonly_install:+-H} "$@" ||
:
778 local _hostonly_install
779 if [[ "$1" == "-H" ]]; then
780 _hostonly_install
="-H"
783 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
784 [[ -L $1 ]] ||
return 1
785 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"
786 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" ||
:
791 $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"
793 (($_ret != 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" ||
:
802 local _hostonly_install
803 if [[ "$1" == "-H" ]]; then
804 _hostonly_install
="-H"
807 [[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
808 [[ -e $1 ]] ||
return 1 # no source
809 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"
810 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" ||
:
814 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"
815 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@" ||
:
819 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"
820 (($?
!= 0)) && derror
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@" ||
:
825 echo "$i" >> "$initdir/lib/dracut/hostonly-files"
829 # find symlinks linked to given library file
831 # Function searches for symlinks by stripping version numbers appended to
832 # library filename, checks if it points to the same target and finally
833 # prints the list of symlinks to stdout.
836 # rev_lib_symlinks libfoo.so.8.1
837 # output: libfoo.so.8 libfoo.so
838 # (Only if libfoo.so.8 and libfoo.so exists on host system.)
840 [[ ! $1 ]] && return 0
842 local fn
="$1" orig
="$(readlink -f "$1")" links
=''
844 [[ ${fn} == *.so.
* ]] ||
return 1
846 until [[ ${fn##*.} == so
]]; do
848 [[ -L ${fn} && $(readlink -f "${fn}") == ${orig} ]] && links+=" ${fn}"
854 # attempt to install any programs specified in a udev rule
855 inst_rule_programs() {
858 if grep -qE 'PROGRAM==?"[^
"]+' "$1"; then
859 for _prog in $(grep -E 'PROGRAM==?"[^
"]+' "$1" | sed -r 's/.*PROGRAM==?"([^
"]+).*/\1/'); do
861 if [ -x ${udevdir}/$_prog ]; then
862 _bin=${udevdir}/$_prog
863 elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then
864 _bin=$(find_binary "$_prog") || {
865 dinfo "Skipping program
$_prog using
in udev rule
${1##*/} as it cannot be found
"
870 [[ $_bin ]] && inst_binary "$_bin"
873 if grep -qE 'RUN[+=]=?"[^
"]+' "$1"; then
874 for _prog in $(grep -E 'RUN[+=]=?"[^
"]+' "$1" | sed -r 's/.*RUN[+=]=?"([^
"]+).*/\1/'); do
876 if [ -x ${udevdir}/$_prog ]; then
877 _bin=${udevdir}/$_prog
878 elif [[ "${_prog/\$env\{/}" == "$_prog" ]] && [[ "${_prog}" != "/sbin
/initqueue
" ]]; then
879 _bin=$(find_binary "$_prog") || {
880 dinfo "Skipping program
$_prog using
in udev rule
${1##*/} as it cannot be found
"
885 [[ $_bin ]] && inst_binary "$_bin"
888 if grep -qE 'IMPORT\{program\}==?"[^
"]+' "$1"; then
889 for _prog in $(grep -E 'IMPORT\{program\}==?"[^
"]+' "$1" | sed -r 's/.*IMPORT\{program\}==?"([^
"]+).*/\1/'); do
891 if [ -x ${udevdir}/$_prog ]; then
892 _bin=${udevdir}/$_prog
893 elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then
894 _bin=$(find_binary "$_prog") || {
895 dinfo "Skipping program
$_prog using
in udev rule
${1##*/} as it cannot be found
"
900 [[ $_bin ]] && dracut_install "$_bin"
905 # attempt to install any programs specified in a udev rule
906 inst_rule_group_owner() {
909 if grep -qE 'OWNER=?"[^
"]+' "$1"; then
910 for i in $(grep -E 'OWNER=?"[^
"]+' "$1" | sed -r 's/.*OWNER=?"([^
"]+).*/\1/'); do
911 if ! egrep -q "^
$i:" "$initdir/etc
/passwd
" 2>/dev/null; then
912 egrep "^
$i:" /etc/passwd 2>/dev/null >> "$initdir/etc
/passwd
"
916 if grep -qE 'GROUP=?"[^
"]+' "$1"; then
917 for i in $(grep -E 'GROUP=?"[^
"]+' "$1" | sed -r 's/.*GROUP=?"([^
"]+).*/\1/'); do
918 if ! egrep -q "^
$i:" "$initdir/etc
/group
" 2>/dev/null; then
919 egrep "^
$i:" /etc/group 2>/dev/null >> "$initdir/etc
/group
"
925 inst_rule_initqueue() {
926 if grep -q -F initqueue "$1"; then
927 dracut_need_initqueue
931 # udev rules always get installed in the same place, so
932 # create a function to install them to make life simpler.
934 local _target=/etc/udev/rules.d _rule _found
936 inst_dir "${udevdir}/rules.d
"
938 for _rule in "$@
"; do
939 if [ "${_rule#/}" = "$_rule" ]; then
940 for r in ${udevdir}/rules.d ${hostonly:+/etc/udev/rules.d}; do
941 if [[ -e $r/$_rule ]]; then
943 inst_rule_programs "$_found"
944 inst_rule_group_owner "$_found"
945 inst_rule_initqueue "$_found"
946 inst_simple "$_found"
950 for r in '' $dracutbasedir/rules.d/; do
951 # skip rules without an absolute path
952 [[ "${r}$_rule" != /* ]] && continue
954 if [[ -f ${r}$_rule ]]; then
956 inst_rule_programs "$_found"
957 inst_rule_group_owner "$_found"
958 inst_rule_initqueue "$_found"
959 inst_simple "$_found" "$_target/${_found##*/}"
962 [[ $_found ]] || dinfo "Skipping udev rule
: $_rule"
966 inst_rules_wildcard() {
967 local _target=/etc/udev/rules.d _rule _found
969 inst_dir "${udevdir}/rules.d
"
971 for _rule in ${udevdir}/rules.d/$1 ${dracutbasedir}/rules.d/$1 ; do
972 if [[ -e $_rule ]]; then
973 inst_rule_programs "$_rule"
974 inst_rule_group_owner "$_rule"
975 inst_rule_initqueue "$_rule"
980 if [[ -n ${hostonly} ]] ; then
981 for _rule in ${_target}/$1 ; do
982 if [[ -f $_rule ]]; then
983 inst_rule_programs "$_rule"
984 inst_rule_group_owner "$_rule"
985 inst_rule_initqueue "$_rule"
991 [[ $_found ]] || dinfo "Skipping udev rule
: $_rule"
994 prepare_udev_rules() {
995 [ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version)
998 f="${initdir}/etc
/udev
/rules.d
/$f"
999 [ -e "$f" ] || continue
1000 while read line || [ -n "$line" ]; do
1001 if [ "${line%%IMPORT PATH_ID}" != "$line" ]; then
1002 if [ $UDEVVERSION -ge 174 ]; then
1003 printf '%sIMPORT{builtin}="path_id
"\n' "${line%%IMPORT PATH_ID}"
1005 printf '%sIMPORT{program}="path_id
%%p
"\n' "${line%%IMPORT PATH_ID}"
1007 elif [ "${line%%IMPORT BLKID}" != "$line" ]; then
1008 if [ $UDEVVERSION -ge 176 ]; then
1009 printf '%sIMPORT{builtin}="blkid
"\n' "${line%%IMPORT BLKID}"
1011 printf '%sIMPORT{program}="/sbin
/blkid
-o udev
-p $tempnode"\n' "${line%%IMPORT BLKID}"
1016 done < "${f}" > "${f}.new
"
1021 # install function specialized for hooks
1022 # $1 = type of hook, $2 = hook priority (lower runs first), $3 = hook
1023 # All hooks should be POSIX/SuS compliant, they will be sourced by init.
1025 if ! [[ -f $3 ]]; then
1026 dfatal "Cannot
install a hook
($3) that does not exist.
"
1027 dfatal "Aborting initrd creation.
"
1029 elif ! [[ "$hookdirs" == *$1* ]]; then
1030 dfatal "No such hook
type $1. Aborting initrd creation.
"
1033 inst_simple "$3" "/lib
/dracut
/hooks
/${1}/${2}-${3##*/}"
1036 # install any of listed files
1038 # If first argument is '-d' and second some destination path, first accessible
1039 # source is installed into this path, otherwise it will installed in the same
1040 # path as source. If none of listed files was installed, function return 1.
1041 # On first successful installation it returns with 0 status.
1045 # inst_any -d /bin/foo /bin/bar /bin/baz
1047 # Lets assume that /bin/baz exists, so it will be installed as /bin/foo in
1052 [[ $1 = '-d' ]] && to="$2" && shift 2
1055 if [[ -e $f ]]; then
1056 [[ $to ]] && inst "$f" "$to" && return 0
1057 inst "$f" && return 0
1065 # inst_libdir_file [-n <pattern>] <file> [<file>...]
1066 # Install a <file> located on a lib directory to the initramfs image
1067 # -n <pattern> install matching files
1068 inst_libdir_file() {
1070 if [[ "$1" == "-n" ]]; then
1073 for _dir in $libdirs; do
1075 for _f in "$_dir"/$_i; do
1076 [[ "$_f" =~ $_pattern ]] || continue
1077 [[ -e "$_f" ]] && _files+="$_f "
1082 for _dir in $libdirs; do
1084 for _f in "$_dir"/$_i; do
1085 [[ -e "$_f" ]] && _files+="$_f "
1090 [[ $_files ]] && inst_multiple $_files
1094 # install function decompressing the target and handling symlinks
1095 # $@ = list of compressed (gz or bz2) files or symlinks pointing to such files
1097 # Function install targets in the same paths inside overlay but decompressed
1098 # and without extensions (.gz, .bz2).
1105 *.gz) _cmd='gzip -f -d' ;;
1106 *.bz2) _cmd='bzip2 -d' ;;
1110 # Decompress with chosen tool. We assume that tool changes name e.g.
1111 # from 'name.gz' to 'name'.
1112 ${_cmd} "${initdir}${_src}"
1116 # It's similar to above, but if file is not compressed, performs standard
1118 # $@ = list of files
1119 inst_opt_decompress
() {
1124 inst_decompress
"${_src}" || inst
"${_src}"
1128 # module_check <dracut module>
1129 # execute the check() function of module-setup.sh of <dracut module>
1130 # or the "check" script, if module-setup.sh is not found
1131 # "check $hostonly" is called
1133 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1136 local _hostonly
=$hostonly
1137 [ $# -eq 2 ] && _forced
=$2
1138 [[ -d $_moddir ]] ||
return 1
1139 if [[ ! -f $_moddir/module-setup.sh
]]; then
1140 # if we do not have a check script, we are unconditionally included
1141 [[ -x $_moddir/check
]] ||
return 0
1142 [ $_forced -ne 0 ] && unset hostonly
1143 $_moddir/check
$hostonly
1146 unset check depends cmdline
install installkernel
1148 .
$_moddir/module-setup.sh
1149 is_func check ||
return 0
1150 [ $_forced -ne 0 ] && unset hostonly
1151 moddir
=$_moddir check
$hostonly
1153 unset check depends cmdline
install installkernel
1159 # module_check_mount <dracut module>
1160 # execute the check() function of module-setup.sh of <dracut module>
1161 # or the "check" script, if module-setup.sh is not found
1162 # "mount_needs=1 check 0" is called
1163 module_check_mount
() {
1164 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1167 [[ -d $_moddir ]] ||
return 1
1168 if [[ ! -f $_moddir/module-setup.sh
]]; then
1169 # if we do not have a check script, we are unconditionally included
1170 [[ -x $_moddir/check
]] ||
return 0
1171 mount_needs
=1 $_moddir/check
0
1174 unset check depends cmdline
install installkernel
1176 .
$_moddir/module-setup.sh
1177 moddir
=$_moddir check
0
1179 unset check depends cmdline
install installkernel
1185 # module_depends <dracut module>
1186 # execute the depends() function of module-setup.sh of <dracut module>
1187 # or the "depends" script, if module-setup.sh is not found
1189 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1191 [[ -d $_moddir ]] ||
return 1
1192 if [[ ! -f $_moddir/module-setup.sh
]]; then
1193 # if we do not have a check script, we have no deps
1194 [[ -x $_moddir/check
]] ||
return 0
1198 unset check depends cmdline
install installkernel
1200 .
$_moddir/module-setup.sh
1201 moddir
=$_moddir depends
1203 unset check depends cmdline
install installkernel
1208 # module_cmdline <dracut module>
1209 # execute the cmdline() function of module-setup.sh of <dracut module>
1210 # or the "cmdline" script, if module-setup.sh is not found
1212 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1214 [[ -d $_moddir ]] ||
return 1
1215 if [[ ! -f $_moddir/module-setup.sh
]]; then
1216 [[ -x $_moddir/cmdline
]] && .
"$_moddir/cmdline"
1219 unset check depends cmdline
install installkernel
1221 .
$_moddir/module-setup.sh
1222 moddir
=$_moddir cmdline
1224 unset check depends cmdline
install installkernel
1229 # module_install <dracut module>
1230 # execute the install() function of module-setup.sh of <dracut module>
1231 # or the "install" script, if module-setup.sh is not found
1233 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1235 [[ -d $_moddir ]] ||
return 1
1236 if [[ ! -f $_moddir/module-setup.sh
]]; then
1237 [[ -x $_moddir/install ]] && .
"$_moddir/install"
1240 unset check depends cmdline
install installkernel
1242 .
$_moddir/module-setup.sh
1243 moddir
=$_moddir install
1245 unset check depends cmdline
install installkernel
1250 # module_installkernel <dracut module>
1251 # execute the installkernel() function of module-setup.sh of <dracut module>
1252 # or the "installkernel" script, if module-setup.sh is not found
1253 module_installkernel
() {
1254 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1256 [[ -d $_moddir ]] ||
return 1
1257 if [[ ! -f $_moddir/module-setup.sh
]]; then
1258 [[ -x $_moddir/installkernel
]] && .
"$_moddir/installkernel"
1261 unset check depends cmdline
install installkernel
1262 installkernel
() { true
; }
1263 .
$_moddir/module-setup.sh
1264 moddir
=$_moddir installkernel
1266 unset check depends cmdline
install installkernel
1271 # check_mount <dracut module>
1272 # check_mount checks, if a dracut module is needed for the given
1273 # device and filesystem types in "${host_fs_types[@]}"
1276 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1280 [ "${#host_fs_types[*]}" -le 0 ] && return 1
1282 # If we are already scheduled to be loaded, no need to check again.
1283 [[ " $mods_to_load " == *\
$_mod\
* ]] && return 0
1284 [[ " $mods_checked_as_dep " == *\
$_mod\
* ]] && return 1
1286 # This should never happen, but...
1287 [[ -d $_moddir ]] ||
return 1
1289 [[ $2 ]] || mods_checked_as_dep
+=" $_mod "
1291 if [[ " $omit_dracutmodules " == *\
$_mod\
* ]]; then
1295 if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\
$_mod\
* ]]; then
1296 module_check_mount
$_mod; ret
=$?
1298 # explicit module, so also accept ret=255
1299 [[ $ret = 0 ||
$ret = 255 ]] ||
return 1
1301 # module not in our list
1302 if [[ $dracutmodules = all
]]; then
1303 # check, if we can and should install this module
1304 module_check_mount
$_mod ||
return 1
1311 for _moddep
in $
(module_depends
$_mod); do
1312 # handle deps as if they were manually added
1313 [[ " $dracutmodules " == *\
$_mod\
* ]] \
1314 && [[ " $dracutmodules " != *\
$_moddep\
* ]] \
1315 && dracutmodules
+=" $_moddep "
1316 [[ " $add_dracutmodules " == *\
$_mod\
* ]] \
1317 && [[ " $add_dracutmodules " != *\
$_moddep\
* ]] \
1318 && add_dracutmodules
+=" $_moddep "
1319 [[ " $force_add_dracutmodules " == *\
$_mod\
* ]] \
1320 && [[ " $force_add_dracutmodules " != *\
$_moddep\
* ]] \
1321 && force_add_dracutmodules
+=" $_moddep "
1322 # if a module we depend on fail, fail also
1323 if ! check_module
$_moddep; then
1324 derror
"dracut module '$_mod' depends on '$_moddep', which can't be installed"
1329 [[ " $mods_to_load " == *\
$_mod\
* ]] || \
1330 mods_to_load
+=" $_mod "
1335 # check_module <dracut module> [<use_as_dep>]
1336 # check if a dracut module is to be used in the initramfs process
1337 # if <use_as_dep> is set, then the process also keeps track
1338 # that the modules were checked for the dependency tracking process
1341 local _moddir
=$
(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
1344 # If we are already scheduled to be loaded, no need to check again.
1345 [[ " $mods_to_load " == *\
$_mod\
* ]] && return 0
1346 [[ " $mods_checked_as_dep " == *\
$_mod\
* ]] && return 1
1348 # This should never happen, but...
1349 [[ -d $_moddir ]] ||
return 1
1351 [[ $2 ]] || mods_checked_as_dep
+=" $_mod "
1353 if [[ " $omit_dracutmodules " == *\
$_mod\
* ]]; then
1354 dinfo
"dracut module '$_mod' will not be installed, because it's in the list to be omitted!"
1358 if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\
$_mod\
* ]]; then
1359 if [[ " $dracutmodules $force_add_dracutmodules " == *\
$_mod\
* ]]; then
1360 module_check
$_mod 1; ret
=$?
1362 module_check
$_mod 0; ret
=$?
1364 # explicit module, so also accept ret=255
1365 [[ $ret = 0 ||
$ret = 255 ]] ||
return 1
1367 # module not in our list
1368 if [[ $dracutmodules = all
]]; then
1369 # check, if we can and should install this module
1370 module_check
$_mod; ret
=$?
1371 if [[ $ret != 0 ]]; then
1372 [[ $2 ]] && return 1
1373 [[ $ret != 255 ]] && return 1
1381 for _moddep
in $
(module_depends
$_mod); do
1382 # handle deps as if they were manually added
1383 [[ " $dracutmodules " == *\
$_mod\
* ]] \
1384 && [[ " $dracutmodules " != *\
$_moddep\
* ]] \
1385 && dracutmodules
+=" $_moddep "
1386 [[ " $add_dracutmodules " == *\
$_mod\
* ]] \
1387 && [[ " $add_dracutmodules " != *\
$_moddep\
* ]] \
1388 && add_dracutmodules
+=" $_moddep "
1389 [[ " $force_add_dracutmodules " == *\
$_mod\
* ]] \
1390 && [[ " $force_add_dracutmodules " != *\
$_moddep\
* ]] \
1391 && force_add_dracutmodules
+=" $_moddep "
1392 # if a module we depend on fail, fail also
1393 if ! check_module
$_moddep; then
1394 derror
"dracut module '$_mod' depends on '$_moddep', which can't be installed"
1399 [[ " $mods_to_load " == *\
$_mod\
* ]] || \
1400 mods_to_load
+=" $_mod "
1405 # for_each_module_dir <func>
1406 # execute "<func> <dracut module> 1"
1407 for_each_module_dir
() {
1413 for _moddir
in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
1414 [[ -d $_moddir ]] ||
continue;
1415 [[ -e $_moddir/install ||
-e $_moddir/installkernel || \
1416 -e $_moddir/module-setup.sh
]] ||
continue
1417 _mod
=${_moddir##*/}; _mod
=${_mod#[0-9][0-9]}
1421 # Report any missing dracut modules, the user has specified
1422 _modcheck
="$add_dracutmodules $force_add_dracutmodules"
1423 [[ $dracutmodules != all
]] && _modcheck
="$_modcheck $dracutmodules"
1424 for _mod
in $_modcheck; do
1425 [[ " $mods_to_load " == *\
$_mod\
* ]] && continue
1427 [[ " $force_add_dracutmodules " != *\
$_mod\
* ]] \
1428 && [[ " $dracutmodules " != *\
$_mod\
* ]] \
1429 && [[ " $omit_dracutmodules " == *\
$_mod\
* ]] \
1432 derror
"dracut module '$_mod' cannot be found or installed."
1433 [[ " $force_add_dracutmodules " == *\
$_mod\
* ]] && exit 1
1434 [[ " $dracutmodules " == *\
$_mod\
* ]] && exit 1
1435 [[ " $add_dracutmodules " == *\
$_mod\
* ]] && exit 1
1439 # Install a single kernel module along with any firmware it may require.
1440 # $1 = full path to kernel module to install
1441 install_kmod_with_fw
() {
1442 # no need to go further if the module is already installed
1444 [[ -e "${initdir}/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" ]] \
1447 if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -e "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}" ]]; then
1448 read ret
< "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
1452 if [[ $omit_drivers ]]; then
1453 local _kmod
=${1##*/}
1456 if [[ "$_kmod" =~
$omit_drivers ]]; then
1457 dinfo
"Omitting driver $_kmod"
1460 if [[ "${1##*/lib/modules/$kernel/}" =~
$omit_drivers ]]; then
1461 dinfo
"Omitting driver $_kmod"
1466 if [[ $silent_omit_drivers ]]; then
1467 local _kmod
=${1##*/}
1470 [[ "$_kmod" =~
$silent_omit_drivers ]] && return 0
1471 [[ "${1##*/lib/modules/$kernel/}" =~
$silent_omit_drivers ]] && return 0
1474 inst_simple
"$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}"
1476 [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
1477 [[ -d "$DRACUT_KERNEL_LAZY_HASHDIR" ]] && \
1478 echo $ret > "$DRACUT_KERNEL_LAZY_HASHDIR/${1##*/}"
1479 (($ret != 0)) && return $ret
1481 local _modname
=${1##*/} _fwdir _found _fw
1482 _modname
=${_modname%.ko*}
1483 for _fw
in $
(modinfo
-k $kernel -F firmware
$1 2>/dev
/null
); do
1485 for _fwdir
in $fw_dir; do
1486 if [[ -d $_fwdir && -f $_fwdir/$_fw ]]; then
1487 inst_simple
"$_fwdir/$_fw" "/lib/firmware/$_fw"
1491 if [[ $_found != yes ]]; then
1492 if ! [[ -d $
(echo /sys
/module
/${_modname//-/_}|
{ read a b
; echo $a; }) ]]; then
1493 dinfo
"Possible missing firmware \"${_fw}\" for kernel module" \
1494 "\"${_modname}.ko\""
1496 dwarn
"Possible missing firmware \"${_fw}\" for kernel module" \
1497 "\"${_modname}.ko\""
1504 # Do something with all the dependencies of a kernel module.
1505 # Note that kernel modules depend on themselves using the technique we use
1506 # $1 = function to call for each dependency we find
1507 # It will be passed the full path to the found kernel module
1508 # $2 = module to get dependencies for
1509 # rest of args = arguments to modprobe
1510 # _fderr specifies FD passed from surrounding scope
1511 for_each_kmod_dep
() {
1512 local _func
=$1 _kmod
=$2 _cmd _modpath _options
1514 modprobe
"$@" --ignore-install --show-depends $_kmod 2>&${_fderr} |
(
1515 while read _cmd _modpath _options ||
[ -n "$_cmd" ]; do
1516 [[ $_cmd = insmod
]] ||
continue
1517 $_func ${_modpath} ||
exit $?
1522 dracut_kernel_post
() {
1523 local _moddirname
=${srcmods%%/lib/modules/*}
1526 if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" ]]; then
1527 xargs -r modprobe
-a ${_moddirname:+-d ${_moddirname}/} \
1528 --ignore-install --show-depends --set-version $kernel \
1529 < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" 2>/dev
/null \
1531 |
while read _cmd _modpath _options ||
[ -n "$_cmd" ]; do
1532 [[ $_cmd = insmod
]] ||
continue
1534 done > "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
1537 if [[ $DRACUT_INSTALL ]] && [[ -z $_moddirname ]]; then
1538 xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} -a < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
1540 while read _modpath ||
[ -n "$_modpath" ]; do
1541 local _destpath
=$_modpath
1542 [[ $_moddirname ]] && _destpath
=${_destpath##$_moddirname/}
1543 _destpath
=${_destpath##*/lib/modules/$kernel/}
1544 inst_simple
"$_modpath" "/lib/modules/$kernel/${_destpath}" ||
exit $?
1545 done < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
1548 _pid
=$
(jobs -p |
while read a ||
[ -n "$a" ]; do printf ":$a";done)
1551 if [[ $DRACUT_INSTALL ]]; then
1552 xargs -r modinfo
-k $kernel -F firmware
< "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep" \
1553 |
while read line ||
[ -n "$line" ]; do
1554 for _fwdir
in $fw_dir; do
1557 done |
xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} -a -o
1559 for _fw
in $
(xargs -r modinfo
-k $kernel -F firmware
< "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"); do
1560 for _fwdir
in $fw_dir; do
1561 if [[ -d $_fwdir && -f $_fwdir/$_fw ]]; then
1562 inst_simple
"$_fwdir/$_fw" "/lib/firmware/$_fw"
1572 for _f
in modules.
builtin.bin modules.
builtin modules.order
; do
1573 [[ $srcmods/$_f ]] && inst_simple
"$srcmods/$_f" "/lib/modules/$kernel/$_f"
1576 # generate module dependencies for the initrd
1577 if [[ -d $initdir/lib
/modules
/$kernel ]] && \
1578 ! depmod
-a -b "$initdir" $kernel; then
1579 dfatal
"\"depmod -a $kernel\" failed."
1583 [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && rm -fr -- "$DRACUT_KERNEL_LAZY_HASHDIR"
1586 [[ "$kernel_current" ]] ||
export kernel_current
=$
(uname
-r)
1588 module_is_host_only
() {
1590 local _modenc a i _k _s _v _aliases
1593 _modenc
=${_mod//-/_}
1595 [[ " $add_drivers " == *\
${_mod}\
* ]] && return 0
1597 # check if module is loaded
1598 [[ ${host_modules["$_modenc"]} ]] && return 0
1600 [[ "$kernel_current" ]] ||
export kernel_current
=$
(uname
-r)
1602 if [[ "$kernel_current" != "$kernel" ]]; then
1603 # check if module is loadable on the current kernel
1604 # this covers the case, where a new module is introduced
1605 # or a module was renamed
1606 # or a module changed from builtin to a module
1608 if [[ -d /lib
/modules
/$kernel_current ]]; then
1609 # if the modinfo can be parsed, but the module
1610 # is not loaded, then we can safely return 1
1611 modinfo
-F filename
"$_mod" &>/dev
/null
&& return 1
1614 _aliases
=$
(modinfo
-k $kernel -F alias $_mod 2>/dev
/null
)
1616 # if the module has no aliases, install it
1617 [[ $_aliases ]] ||
return 0
1619 # finally check all modalias
1620 for a
in $_aliases; do
1621 for i
in "${!host_modalias[@]}"; do
1622 [[ $i == $a ]] && return 0
1631 find_kernel_modules_by_path
() {
1634 [[ -f "$srcmods/modules.dep" ]] ||
return 0
1638 while read a rest ||
[ -n "$a" ]; do
1639 [[ $a = */$1/* ]] ||
[[ $a = updates
/* ]] ||
continue
1640 printf "%s\n" "$srcmods/$a"
1641 done < "$srcmods/modules.dep"
1646 find_kernel_modules
() {
1647 find_kernel_modules_by_path drivers
1650 # instmods [-c [-s]] <kernel module> [<kernel module> ... ]
1651 # instmods [-c [-s]] <kernel subsystem>
1652 # install kernel modules along with all their dependencies.
1653 # <kernel subsystem> can be e.g. "=block" or "=drivers/usb/storage"
1655 [[ $no_kernel = yes ]] && return
1656 # called [sub]functions inherit _fderr
1660 if [[ $1 = '-c' ]]; then
1665 if [[ $1 = '-s' ]]; then
1670 function inst1mod
() {
1671 local _ret
=0 _mod
="$1"
1674 ( [[ "$_mpargs" ]] && echo $_mpargs
1675 find_kernel_modules_by_path
"${_mod#=}" ) \
1679 --*) _mpargs
+=" $_mod" ;;
1682 # Check for aliased modules
1683 _modalias
=$
(modinfo
-k $kernel -F filename
$_mod 2> /dev
/null
)
1684 _modalias
=${_modalias%.ko*}
1685 if [[ $_modalias ]] && [ "${_modalias##*/}" != "${_mod%.ko*}" ] ; then
1686 _mod
=${_modalias##*/}
1689 # if we are already installed, skip this module and go on
1691 if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
1692 [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko*}" ]]; then
1693 read _ret
<"$DRACUT_KERNEL_LAZY_HASHDIR/${_mod%.ko*}"
1698 if [[ $omit_drivers ]] && [[ "$_mod" =~
$omit_drivers ]]; then
1699 dinfo
"Omitting driver ${_mod##$srcmods}"
1703 # If we are building a host-specific initramfs and this
1704 # module is not already loaded, move on to the next one.
1706 && ! module_is_host_only
"$_mod" \
1709 if [[ "$_check" = "yes" ]] ||
! [[ $DRACUT_KERNEL_LAZY_HASHDIR ]]; then
1710 # We use '-d' option in modprobe only if modules prefix path
1711 # differs from default '/'. This allows us to use dracut with
1712 # old version of modprobe which doesn't have '-d' option.
1713 local _moddirname
=${srcmods%%/lib/modules/*}
1714 [[ -n ${_moddirname} ]] && _moddirname
="-d ${_moddirname}/"
1716 # ok, load the module, all its dependencies, and any firmware
1718 for_each_kmod_dep install_kmod_with_fw
$_mod \
1719 --set-version $kernel ${_moddirname} $_mpargs
1722 [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && \
1723 echo ${_mod%.ko*} >> "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist"
1730 function instmods_1
() {
1732 if (($# == 0)); then # filenames from stdin
1733 while read _mod ||
[ -n "$_mod" ]; do
1734 inst1mod
"${_mod%.ko*}" ||
{
1735 if [[ "$_check" == "yes" ]] && [[ "$_silent" == "no" ]]; then
1736 dfatal
"Failed to install module $_mod"
1741 while (($# > 0)); do # filenames as arguments
1742 inst1mod
${1%.ko*} ||
{
1743 if [[ "$_check" == "yes" ]] && [[ "$_silent" == "no" ]]; then
1744 dfatal
"Failed to install module $1"
1752 local _ret _filter_not_found
='FATAL: Module .* not found.'
1753 # Capture all stderr from modprobe to _fderr. We could use {var}>...
1754 # redirections, but that would make dracut require bash4 at least.
1755 eval "( instmods_1 \"\$@\" ) ${_fderr}>&1" \
1756 |
while read line ||
[ -n "$line" ]; do [[ "$line" =~
$_filter_not_found ]] ||
echo $line;done | derror
1761 check_kernel_config
()
1763 local _config_opt
="$1"
1765 [[ -f /boot
/config-
$kernel ]] \
1766 && _config_file
="/boot/config-$kernel"
1767 [[ -f /lib
/modules
/$kernel/config
]] \
1768 && _config_file
="/lib/modules/$kernel/config"
1770 # no kernel config file, so return true
1771 [[ $_config_file ]] ||
return 0
1773 grep -q -F "${_config_opt}=" "$_config_file" && return 0
1779 # Only two values are returned: AMD or Intel
1782 if grep -qE AMD
/proc
/cpuinfo
; then
1785 if grep -qE Intel
/proc
/cpuinfo
; then
1791 # Get the hosts' ucode file based on the /proc/cpuinfo
1794 local family
=`grep -E "cpu family" /proc/cpuinfo | head -1 | sed s/.*:\ //`
1795 local model
=`grep -E "model" /proc/cpuinfo |grep -v name | head -1 | sed s/.*:\ //`
1796 local stepping
=`grep -E "stepping" /proc/cpuinfo | head -1 | sed s/.*:\ //`
1798 if [[ "$(get_cpu_vendor)" == "AMD" ]]; then
1799 # If family greater or equal than 0x15
1800 if [[ $family -ge 21 ]]; then
1801 printf "microcode_amd_fam15h.bin"
1803 printf "microcode_amd.bin"
1806 if [[ "$(get_cpu_vendor)" == "Intel" ]]; then
1807 # The /proc/cpuinfo are in decimal.
1808 printf "%02x-%02x-%02x" ${family} ${model} ${stepping}
1812 # Not every device in /dev/mapper should be examined.
1813 # If it is an LVM device, touch only devices which have /dev/VG/LV symlink.
1814 lvm_internal_dev
() {
1815 local dev_dm_dir
=/sys
/dev
/block
/$1/dm
1816 [[ ! -f $dev_dm_dir/uuid || $
(<$dev_dm_dir/uuid
) != LVM-
* ]] && return 1 # Not an LVM device
1817 local DM_VG_NAME DM_LV_NAME DM_LV_LAYER
1818 eval $
(dmsetup splitname
--nameprefixes --noheadings --rows "$(<$dev_dm_dir/name)" 2>/dev
/null
)
1819 [[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] ||
return 0 # Better skip this!
1820 [[ ${DM_LV_LAYER} ]] || [[ ! -L /dev/${DM_VG_NAME}/${DM_LV_NAME} ]]