]> git.ipfire.org Git - thirdparty/dracut.git/blobdiff - dracut-functions.sh
Merge pull request #172 from haraldh/RHEL-7
[thirdparty/dracut.git] / dracut-functions.sh
index 6c7e693d83c661168d6ac3c88bf3b021b1d788b0..61726e44e7f38c96d1b3598bd68263bea6530a79 100755 (executable)
 export LC_MESSAGES=C
 
 if [[ $DRACUT_KERNEL_LAZY ]] && ! [[ $DRACUT_KERNEL_LAZY_HASHDIR ]]; then
-    if [[ -d "$initdir/.kernelmodseen" ]]; then
-        mkdir -p "$initdir/.kernelmodseen"
+    if [[ -d "$initdir/.kernelmodseen" ]]; then
+        DRACUT_KERNEL_LAZY_HASHDIR="$initdir/.kernelmodseen"
     fi
-    DRACUT_KERNEL_LAZY_HASHDIR="$initdir/.kernelmodseen"
-fi
-
-if [[ $initdir ]] && ! [[ -d $initdir ]]; then
-    mkdir -p "$initdir"
 fi
 
 # Generic substring function.  If $2 is in $1, return 0.
 strstr() { [[ $1 = *$2* ]]; }
+# returns OK if $1 contains literal string $2 at the beginning, and isn't empty
+str_starts() { [ "${1#"$2"*}" != "$1" ]; }
+# returns OK if $1 contains literal string $2 at the end, and isn't empty
+str_ends() { [ "${1%*"$2"}" != "$1" ]; }
+
+# helper function for check() in module-setup.sh
+# to check for required installed binaries
+# issues a standardized warning message
+require_binaries() {
+    local _module_name="${moddir##*/}"
+    local _ret=0
+
+    if [[ "$1" = "-m" ]]; then
+        _module_name="$2"
+        shift 2
+    fi
+
+    for cmd in "$@"; do
+        if ! find_binary "$cmd" &>/dev/null; then
+            dinfo "dracut module '${_module_name#[0-9][0-9]}' will not be installed, because command '$cmd' could not be found!"
+            ((_ret++))
+        fi
+    done
+    return $_ret
+}
+
+require_any_binary() {
+    local _module_name="${moddir##*/}"
+    local _ret=1
+
+    if [[ "$1" = "-m" ]]; then
+        _module_name="$2"
+        shift 2
+    fi
+
+    for cmd in "$@"; do
+        if find_binary "$cmd" &>/dev/null; then
+            _ret=0
+            break
+        fi
+    done
+
+    if (( $_ret != 0 )); then
+        dinfo "$_module_name: Could not find any command of '$@'!"
+        return 1
+    fi
+
+    return 0
+}
 
 # find a binary.  If we were not passed the full path directly,
 # search in the usual places to find the binary.
@@ -57,17 +101,7 @@ fi
 
 ldconfig_paths()
 {
-    local a i
-    declare -A a
-    for i in $(
-        ldconfig -pN 2>/dev/null | while read a b c d; do
-            [[ "$c" != "=>" ]] && continue
-            printf "%s\n" ${d%/*};
-        done
-    ); do
-        a["$i"]=1;
-    done;
-    printf "%s\n" ${!a[@]}
+    ldconfig -pN 2>/dev/null | grep -E -v '/(lib|lib64|usr/lib|usr/lib64)/[^/]*$' | sed -n 's,.* => \(.*\)/.*,\1,p' | sort | uniq
 }
 
 # Detect lib paths
@@ -81,7 +115,7 @@ if ! [[ $libdirs ]] ; then
         [[ -d /usr/lib ]] && libdirs+=" /usr/lib"
     fi
 
-    libdirs+="$(ldconfig_paths)"
+    libdirs+=" $(ldconfig_paths)"
 
     export libdirs
 fi
@@ -129,7 +163,13 @@ srcmods="/lib/modules/$kernel/"
 }
 export srcmods
 
-if ! type dinfo >/dev/null 2>&1; then
+# is_func <command>
+# Check whether $1 is a function.
+is_func() {
+    [[ "$(type -t "$1")" = "function" ]]
+}
+
+if ! is_func dinfo >/dev/null 2>&1; then
     . "$dracutbasedir/dracut-logger.sh"
     dlog_init
 fi
@@ -162,12 +202,6 @@ mksubdirs() {
     [[ -e ${1%/*} ]] || mkdir -m 0755 -p -- "${1%/*}"
 }
 
-# is_func <command>
-# Check whether $1 is a function.
-is_func() {
-    [[ "$(type -t "$1")" = "function" ]]
-}
-
 # Function prints global variables in format name=value line by line.
 # $@ = list of global variables' name
 print_vars() {
@@ -175,7 +209,7 @@ print_vars() {
 
     for _var in "$@"
     do
-        eval printf -v _value "%s" "\$$_var"
+        eval printf -v _value "%s" \""\$$_var"\"
         [[ ${_value} ]] && printf '%s="%s"\n' "$_var" "$_value"
     done
 }
@@ -296,6 +330,23 @@ get_maj_min() {
     printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))"
 }
 
+
+# get_devpath_block <device>
+# get the DEVPATH in /sys of a block device
+get_devpath_block() {
+    local _majmin _i
+    _majmin=$(get_maj_min "$1")
+
+    for _i in /sys/block/*/dev /sys/block/*/*/dev; do
+        [[ -e "$_i" ]] || continue
+        if [[ "$_majmin" == "$(<"$_i")" ]]; then
+            printf "%s" "${_i%/dev}"
+            return 0
+        fi
+    done
+    return 1
+}
+
 # get a persistent path from a device
 get_persistent_dev() {
     local i _tmp _dev
@@ -313,6 +364,7 @@ get_persistent_dev() {
         /dev/disk/by-id/* \
         /dev/disk/by-path/* \
         ; do
+        [[ -e "$i" ]] || continue
         [[ $i == /dev/mapper/control ]] && continue
         [[ $i == /dev/mapper/mpath* ]] && continue
         _tmp=$(get_maj_min "$i")
@@ -332,12 +384,12 @@ expand_persistent_dev() {
             ;;
         UUID=*)
             _dev="${_dev#UUID=}"
-            _dev="$(tr "[:upper:]" "[:lower:]" <<< "$_dev" )"
+            _dev="${_dev,,}"
             _dev="/dev/disk/by-uuid/${_dev}"
             ;;
         PARTUUID=*)
             _dev="${_dev#PARTUUID=}"
-            _dev="$(tr "[:upper:]" "[:lower:]"  <<< "$_dev" )"
+            _dev="${_dev,,}"
             _dev="/dev/disk/by-partuuid/${_dev}"
             ;;
         PARTLABEL=*)
@@ -561,7 +613,7 @@ host_fs_all()
 check_block_and_slaves() {
     local _x
     [[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
-    "$1" $2 && return
+    if ! lvm_internal_dev $2; then "$1" $2 && return; fi
     check_vol_slaves "$@" && return 0
     if [[ -f /sys/dev/block/$2/../dev ]]; then
         check_block_and_slaves $1 $(<"/sys/dev/block/$2/../dev") && return 0
@@ -577,10 +629,10 @@ check_block_and_slaves() {
 check_block_and_slaves_all() {
     local _x _ret=1
     [[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
-    if "$1" $2; then
+    if ! lvm_internal_dev $2 && "$1" $2; then
         _ret=0
     fi
-    check_vol_slaves "$@" && return 0
+    check_vol_slaves_all "$@" && return 0
     if [[ -f /sys/dev/block/$2/../dev ]]; then
         check_block_and_slaves_all $1 $(<"/sys/dev/block/$2/../dev") && _ret=0
     fi
@@ -639,7 +691,7 @@ check_vol_slaves() {
         if [[ $_lv = $2 ]]; then
             _vg=$(lvm lvs --noheadings -o vg_name $i 2>/dev/null)
             # strip space
-            _vg=$(printf "%s\n" "$_vg")
+            _vg="${_vg//[[:space:]]/}"
             if [[ $_vg ]]; then
                 for _pv in $(lvm vgs --noheadings -o pv_name "$_vg" 2>/dev/null)
                 do
@@ -651,6 +703,29 @@ check_vol_slaves() {
     return 1
 }
 
+check_vol_slaves_all() {
+    local _lv _vg _pv
+    for i in /dev/mapper/*; do
+        [[ $i == /dev/mapper/control ]] && continue
+        _lv=$(get_maj_min $i)
+        if [[ $_lv = $2 ]]; then
+            _vg=$(lvm lvs --noheadings -o vg_name $i 2>/dev/null)
+            # strip space
+            _vg="${_vg//[[:space:]]/}"
+            if [[ $_vg ]]; then
+                for _pv in $(lvm vgs --noheadings -o pv_name "$_vg" 2>/dev/null)
+                do
+                    check_block_and_slaves_all $1 $(get_maj_min $_pv)
+                done
+                return 0
+            fi
+        fi
+    done
+    return 1
+}
+
+
+
 # fs_get_option <filesystem options> <search for option>
 # search for a specific option in a bunch of filesystem options
 # and return the value
@@ -688,37 +763,37 @@ fi
 [[ $DRACUT_RESOLVE_LAZY ]] || export DRACUT_RESOLVE_DEPS=1
 inst_dir() {
     [[ -e ${initdir}/"$1" ]] && return 0  # already there
-    $DRACUT_INSTALL ${initdir+-D "$initdir"} -d "$@"
-    (($? != 0)) && derror $DRACUT_INSTALL ${initdir+-D "$initdir"} -d "$@" || :
+    $DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@"
+    (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@" || :
 }
 
 inst() {
     [[ -e ${initdir}/"${2:-$1}" ]] && return 0  # already there
         #dinfo "$DRACUT_INSTALL -l $@"
-    $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l} ${DRACUT_FIPS_MODE+-H} "$@"
-    (($? != 0)) && derror $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l} ${DRACUT_FIPS_MODE+-H} "$@" || :
+    $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@"
+    (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-H} "$@" || :
 }
 
 inst_simple() {
     [[ -e ${initdir}/"${2:-$1}" ]] && return 0  # already there
     [[ -e $1 ]] || return 1  # no source
-    $DRACUT_INSTALL ${initdir+-D "$initdir"} "$@"
-    (($? != 0)) && derror $DRACUT_INSTALL ${initdir+-D "$initdir"} "$@" || :
+    $DRACUT_INSTALL ${initdir:+-D "$initdir"} "$@"
+    (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} "$@" || :
 }
 
 inst_symlink() {
     [[ -e ${initdir}/"${2:-$1}" ]] && return 0  # already there
     [[ -L $1 ]] || return 1
-    $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@"
-    (($? != 0)) && derror $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@" || :
+    $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@"
+    (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@" || :
 }
 
 inst_multiple() {
     local ret
         #dinfo "initdir=$initdir $DRACUT_INSTALL -l $@"
-    $DRACUT_INSTALL ${initdir+-D "$initdir"} -a ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@"
+    $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@"
     ret=$?
-    (($ret != 0)) && derror $DRACUT_INSTALL ${initdir+-D "$initdir"} -a ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@" || :
+    (($ret != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@" || :
     return $ret
 }
 
@@ -729,18 +804,18 @@ dracut_install() {
 inst_library() {
     [[ -e ${initdir}/"${2:-$1}" ]] && return 0  # already there
     [[ -e $1 ]] || return 1  # no source
-    $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@"
-    (($? != 0)) && derror $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@" || :
+    $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@"
+    (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@" || :
 }
 
 inst_binary() {
-    $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@"
-    (($? != 0)) && derror $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@" || :
+    $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@"
+    (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@" || :
 }
 
 inst_script() {
-    $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@"
-    (($? != 0)) && derror $DRACUT_INSTALL ${initdir+-D "$initdir"} ${DRACUT_RESOLVE_DEPS+-l}  ${DRACUT_FIPS_MODE+-H} "$@" || :
+    $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@"
+    (($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${DRACUT_RESOLVE_DEPS:+-l}  ${DRACUT_FIPS_MODE:+-H} "$@" || :
 }
 
 # find symlinks linked to given library file
@@ -854,8 +929,8 @@ inst_rules() {
     inst_dir "$_target"
     for _rule in "$@"; do
         if [ "${_rule#/}" = "$_rule" ]; then
-            for r in ${udevdir}/rules.d /etc/udev/rules.d; do
-                if [[ -f $r/$_rule ]]; then
+            for r in ${udevdir}/rules.d ${hostonly:+/etc/udev/rules.d}; do
+                if [[ -e $r/$_rule ]]; then
                     _found="$r/$_rule"
                     inst_rule_programs "$_found"
                     inst_rule_group_owner "$_found"
@@ -864,7 +939,10 @@ inst_rules() {
                 fi
             done
         fi
-        for r in '' ./ $dracutbasedir/rules.d/; do
+        for r in '' $dracutbasedir/rules.d/; do
+            # skip rules without an absolute path
+            [[ "${r}$_rule" != /* ]] && continue
+
             if [[ -f ${r}$_rule ]]; then
                 _found="${r}$_rule"
                 inst_rule_programs "$_found"
@@ -1034,7 +1112,7 @@ module_check() {
         . $_moddir/module-setup.sh
         is_func check || return 0
         [ $_forced -ne 0 ] && unset hostonly
-        check $hostonly
+        moddir=$_moddir check $hostonly
         _ret=$?
         unset check depends cmdline install installkernel
     fi
@@ -1060,7 +1138,7 @@ module_check_mount() {
         unset check depends cmdline install installkernel
         check() { false; }
         . $_moddir/module-setup.sh
-        check 0
+        moddir=$_moddir check 0
         _ret=$?
         unset check depends cmdline install installkernel
     fi
@@ -1084,7 +1162,7 @@ module_depends() {
         unset check depends cmdline install installkernel
         depends() { true; }
         . $_moddir/module-setup.sh
-        depends
+        moddir=$_moddir depends
         _ret=$?
         unset check depends cmdline install installkernel
         return $_ret
@@ -1105,7 +1183,7 @@ module_cmdline() {
         unset check depends cmdline install installkernel
         cmdline() { true; }
         . $_moddir/module-setup.sh
-        cmdline
+        moddir=$_moddir cmdline
         _ret=$?
         unset check depends cmdline install installkernel
         return $_ret
@@ -1126,7 +1204,7 @@ module_install() {
         unset check depends cmdline install installkernel
         install() { true; }
         . $_moddir/module-setup.sh
-        install
+        moddir=$_moddir install
         _ret=$?
         unset check depends cmdline install installkernel
         return $_ret
@@ -1147,7 +1225,7 @@ module_installkernel() {
         unset check depends cmdline install installkernel
         installkernel() { true; }
         . $_moddir/module-setup.sh
-        installkernel
+        moddir=$_moddir installkernel
         _ret=$?
         unset check depends cmdline install installkernel
         return $_ret
@@ -1194,13 +1272,17 @@ check_mount() {
         fi
     fi
 
-
     for _moddep in $(module_depends $_mod); do
         # handle deps as if they were manually added
-        [[ " $add_dracutmodules " == *\ $_moddep\ * ]] || \
-            add_dracutmodules+=" $_moddep "
-        [[ " $force_add_dracutmodules " == *\ $_moddep\ * ]] || \
-            force_add_dracutmodules+=" $_moddep "
+        [[ " $dracutmodules " == *\ $_mod\ * ]] \
+            && [[ " $dracutmodules " != *\ $_moddep\ * ]] \
+            && dracutmodules+=" $_moddep "
+        [[ " $add_dracutmodules " == *\ $_mod\ * ]] \
+            && [[ " $add_dracutmodules " != *\ $_moddep\ * ]] \
+            && add_dracutmodules+=" $_moddep "
+        [[ " $force_add_dracutmodules " == *\ $_mod\ * ]] \
+            && [[ " $force_add_dracutmodules " != *\ $_moddep\ * ]] \
+            && force_add_dracutmodules+=" $_moddep "
         # if a module we depend on fail, fail also
         if ! check_module $_moddep; then
             derror "dracut module '$_mod' depends on '$_moddep', which can't be installed"
@@ -1238,7 +1320,7 @@ check_module() {
     fi
 
     if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\ $_mod\ * ]]; then
-        if [[ " $force_add_dracutmodules " == *\ $_mod\ * ]]; then
+        if [[ " $dracutmodules $force_add_dracutmodules " == *\ $_mod\ * ]]; then
             module_check $_mod 1; ret=$?
         else
             module_check $_mod 0; ret=$?
@@ -1249,7 +1331,11 @@ check_module() {
         # module not in our list
         if [[ $dracutmodules = all ]]; then
             # check, if we can and should install this module
-            module_check $_mod || return 1
+            module_check $_mod; ret=$?
+            if [[ $ret != 0 ]]; then
+                [[ $2 ]] && return 1
+                [[ $ret != 255 ]] && return 1
+            fi
         else
             # skip this module
             return 1
@@ -1258,10 +1344,15 @@ check_module() {
 
     for _moddep in $(module_depends $_mod); do
         # handle deps as if they were manually added
-        [[ " $add_dracutmodules " == *\ $_moddep\ * ]] || \
-            add_dracutmodules+=" $_moddep "
-        [[ " $force_add_dracutmodules " == *\ $_moddep\ * ]] || \
-            force_add_dracutmodules+=" $_moddep "
+        [[ " $dracutmodules " == *\ $_mod\ * ]] \
+            && [[ " $dracutmodules " != *\ $_moddep\ * ]] \
+            && dracutmodules+=" $_moddep "
+        [[ " $add_dracutmodules " == *\ $_mod\ * ]] \
+            && [[ " $add_dracutmodules " != *\ $_moddep\ * ]] \
+            && add_dracutmodules+=" $_moddep "
+        [[ " $force_add_dracutmodules " == *\ $_mod\ * ]] \
+            && [[ " $force_add_dracutmodules " != *\ $_moddep\ * ]] \
+            && force_add_dracutmodules+=" $_moddep "
         # if a module we depend on fail, fail also
         if ! check_module $_moddep; then
             derror "dracut module '$_mod' depends on '$_moddep', which can't be installed"
@@ -1284,17 +1375,28 @@ for_each_module_dir() {
     local _func
     _func=$1
     for _moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
+        [[ -d $_moddir ]] || continue;
+        [[ -e $_moddir/install || -e $_moddir/installkernel || \
+            -e $_moddir/module-setup.sh ]] || continue
         _mod=${_moddir##*/}; _mod=${_mod#[0-9][0-9]}
         $_func $_mod 1
     done
 
     # Report any missing dracut modules, the user has specified
     _modcheck="$add_dracutmodules $force_add_dracutmodules"
-    [[ $dracutmodules != all ]] && _modcheck="$m $dracutmodules"
+    [[ $dracutmodules != all ]] && _modcheck="$_modcheck $dracutmodules"
     for _mod in $_modcheck; do
         [[ " $mods_to_load " == *\ $_mod\ * ]] && continue
-        [[ " $omit_dracutmodules " == *\ $_mod\ * ]] && continue
+
+        [[ " $force_add_dracutmodules " != *\ $_mod\ * ]] \
+            && [[ " $dracutmodules " != *\ $_mod\ * ]] \
+            && [[ " $omit_dracutmodules " == *\ $_mod\ * ]] \
+            && continue
+
         derror "dracut module '$_mod' cannot be found or installed."
+        [[ " $force_add_dracutmodules " == *\ $_mod\ * ]] && exit 1
+        [[ " $dracutmodules " == *\ $_mod\ * ]] && exit 1
+        [[ " $add_dracutmodules " == *\ $_mod\ * ]] && exit 1
     done
 }
 
@@ -1386,7 +1488,7 @@ dracut_kernel_post() {
     local _pid
 
     if [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && [[ -f "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" ]]; then
-        xargs -r modprobe -a ${_moddirname+-d ${_moddirname}/} \
+        xargs -r modprobe -a ${_moddirname:+-d ${_moddirname}/} \
             --ignore-install --show-depends --set-version $kernel \
             < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist" 2>/dev/null \
             | sort -u \
@@ -1397,7 +1499,7 @@ dracut_kernel_post() {
 
         (
             if [[ $DRACUT_INSTALL ]] && [[ -z $_moddirname ]]; then
-                xargs -r $DRACUT_INSTALL ${initdir+-D "$initdir"} -a < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
+                xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"
             else
                 while read _modpath; do
                     local _destpath=$_modpath
@@ -1416,7 +1518,7 @@ dracut_kernel_post() {
                 for _fwdir in $fw_dir; do
                     echo $_fwdir/$line;
                 done;
-            done | xargs -r $DRACUT_INSTALL ${initdir+-D "$initdir"} -a -o
+            done | xargs -r $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a -o
         else
             for _fw in $(xargs -r modinfo -k $kernel -F firmware < "$DRACUT_KERNEL_LAZY_HASHDIR/lazylist.dep"); do
                 for _fwdir in $fw_dir; do
@@ -1431,13 +1533,6 @@ dracut_kernel_post() {
         wait $_pid
     fi
 
-    for _f in modules.builtin.bin modules.builtin; do
-        [[ $srcmods/$_f ]] && break
-    done || {
-        dfatal "No modules.builtin.bin and modules.builtin found!"
-        return 1
-    }
-
     for _f in modules.builtin.bin modules.builtin modules.order; do
         [[ $srcmods/$_f ]] && inst_simple "$srcmods/$_f" "/lib/modules/$kernel/$_f"
     done
@@ -1452,23 +1547,47 @@ dracut_kernel_post() {
     [[ $DRACUT_KERNEL_LAZY_HASHDIR ]] && rm -fr -- "$DRACUT_KERNEL_LAZY_HASHDIR"
 }
 
+[[ "$kernel_current" ]] || export kernel_current=$(uname -r)
+
 module_is_host_only() {
     local _mod=$1
+    local _modenc a i _k _s _v _aliases
     _mod=${_mod##*/}
     _mod=${_mod%.ko}
+    _modenc=${_mod//-/_}
 
     [[ " $add_drivers " == *\ ${_mod}\ * ]] && return 0
 
     # check if module is loaded
-    for i in /sys/module/${_mod//-/_}; do
-        [[ -d $i ]] && return 0
-    done
+    [[ ${host_modules["$_modenc"]} ]] && return 0
+
+    [[ "$kernel_current" ]] || export kernel_current=$(uname -r)
+
+    if [[ "$kernel_current" != "$kernel" ]]; then
+        # check if module is loadable on the current kernel
+        # this covers the case, where a new module is introduced
+        # or a module was renamed
+        # or a module changed from builtin to a module
 
-    # check if module is loadable on the current kernel
-    # this covers the case, where a new module is introduced
-    # or a module was renamed
-    # or a module changed from builtin to a module
-    modinfo -F filename "$_mod" &>/dev/null || return 0
+        if [[ -d /lib/modules/$kernel_current ]]; then
+            # if the modinfo can be parsed, but the module
+            # is not loaded, then we can safely return 1
+            modinfo -F filename "$_mod" &>/dev/null && return 1
+        fi
+
+        _aliases=$(modinfo -k $kernel -F alias $_mod 2>/dev/null)
+
+        # if the module has no aliases, install it
+        [[ $_aliases ]] || return 0
+
+        # finally check all modalias
+        for a in $_aliases; do
+            for i in "${!host_modalias[@]}"; do
+                [[ $i == $a ]]  && return 0
+            done
+        done
+
+    fi
 
     return 1
 }
@@ -1481,7 +1600,7 @@ find_kernel_modules_by_path () {
     _OLDIFS=$IFS
     IFS=:
     while read a rest; do
-        [[ $a = */$1/* ]] || continue
+        [[ $a = */$1/* ]] || [[ $a = updates/* ]] || [[ $a = extra/* ]] || [[ $a = weak-updates/* ]] ||continue
         printf "%s\n" "$srcmods/$a"
     done < "$srcmods/modules.dep"
     IFS=$_OLDIFS
@@ -1630,3 +1749,15 @@ get_ucode_file ()
         printf "%02x-%02x-%02x" ${family} ${model} ${stepping}
     fi
 }
+
+# Not every device in /dev/mapper should be examined.
+# If it is an LVM device, touch only devices which have /dev/VG/LV symlink.
+lvm_internal_dev() {
+    local dev_dm_dir=/sys/dev/block/$1/dm
+    [[ ! -f $dev_dm_dir/uuid || $(<$dev_dm_dir/uuid) != LVM-* ]] && return 1 # Not an LVM device
+    local DM_VG_NAME DM_LV_NAME DM_LV_LAYER
+    eval $(dmsetup splitname --nameprefixes --noheadings --rows "$(<$dev_dm_dir/name)" 2>/dev/null)
+    [[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] || return 0 # Better skip this!
+    [[ ${DM_LV_LAYER} ]] || [[ ! -L /dev/${DM_VG_NAME}/${DM_LV_NAME} ]]
+}
+