Blob Blame History Raw
From 480d772f22a2f690928c59c7c0ebfa7dc00332ea Mon Sep 17 00:00:00 2001
From: Harald Hoyer <harald@redhat.com>
Date: Thu, 8 Dec 2011 10:43:29 +0100
Subject: [PATCH] */module-setup.sh: use host_fs_types host_devs

For the $hostonly case, use $host_fs_types and $host_devs to determine,
if a module has to be included in the initramfs.
---
 dracut                                     |   16 +++++---
 dracut-functions                           |   31 +++++++++++++---
 modules.d/90btrfs/module-setup.sh          |   16 ++++----
 modules.d/90crypt/module-setup.sh          |   26 ++++++++-----
 modules.d/90dmraid/module-setup.sh         |   40 +++++++++++++++------
 modules.d/90kernel-modules/module-setup.sh |    6 +++-
 modules.d/90lvm/module-setup.sh            |   25 ++++++++-----
 modules.d/90mdraid/module-setup.sh         |   40 +++++++++++++++-----
 modules.d/95fstab-sys/module-setup.sh      |    2 +-
 modules.d/95nfs/module-setup.sh            |   14 +++++--
 modules.d/99base/module-setup.sh           |    1 +
 modules.d/99fs-lib/module-setup.sh         |   55 ++++++++++++++--------------
 12 files changed, 179 insertions(+), 93 deletions(-)

diff --git a/dracut b/dracut
index 3d08680..46694f8 100755
--- a/dracut
+++ b/dracut
@@ -508,15 +508,19 @@ trap 'exit 1;' SIGINT
 chmod 755 "$initdir"
 
 if [[ $hostonly ]]; then
+    # in hostonly mode, determine all devices, which have to be accessed
+    # and examine them for filesystem types
+
+    unset host_fs_types
 
     _get_fs_type() (
         [[ $1 ]] || return
         if [[ -b /dev/block/$1 ]] && get_fs_env /dev/block/$1; then
-            echo -n "$ID_FS_TYPE "
+            echo "$1|$ID_FS_TYPE"
             return 1
         fi
-        if find_dev_fstype $1; then
-            echo -n " "
+        if fstype=$(find_dev_fstype $1); then
+            echo "$1|$fstype"
             return 1
         fi
         return 1
@@ -532,7 +536,6 @@ if [[ $hostonly ]]; then
         "/usr/lib64" \
         "/boot"
 
-    host_fs_types=""
     for mp in "${host_mp[@]}"; do
         mountpoint "$mp" >/dev/null 2>&1 || continue
         push host_devs $(find_block_device "$mp")
@@ -541,11 +544,12 @@ if [[ $hostonly ]]; then
         unset fs_type
         for fstype in $(_get_fs_type $dev) \
             $(check_block_and_slaves _get_fs_type $dev); do
-            strstr " $host_fs_types " "$fstype" || host_fs_types+="$fstype "
+            if ! strstr " ${host_fs_types[*]} " " $fstype ";then
+                push host_fs_types "$fstype"
+            fi
         done
     done
 fi
-echo "host_fs_types=$host_fs_types"
 
 export initdir dracutbasedir dracutmodules drivers \
     fw_dir drivers_dir debug no_kernel kernel_only \
diff --git a/dracut-functions b/dracut-functions
index 258d376..d95df14 100755
--- a/dracut-functions
+++ b/dracut-functions
@@ -177,6 +177,14 @@ get_fs_uuid() (
     echo $ID_FS_UUID
 )
 
+
+get_maj_min() {
+    local _dev
+    _dev=$(stat -c '$((0x%T)):$((0x%t))' "$1" 2>/dev/null)
+    _dev=$(eval "echo $_dev")
+    echo $_dev
+}
+
 find_block_device() {
     local _x _mpt _majmin _dev _fs _maj _min
     if [[ $use_fstab != yes ]]; then
@@ -186,11 +194,8 @@ find_block_device() {
             [[ $_fs = nfs3 ]] && { echo $_dev; return 0;}
             [[ $_fs = nfs4 ]] && { echo $_dev; return 0;}
             [[ $_fs = btrfs ]] && {
-                ls -nLl "$_dev" | {
-                    read _x _x _x _x _maj _min _x
-                    _maj=${_maj//,/}
-                    echo $_maj:$_min
-                } && return 0
+                get_maj_min $_dev
+                return 0;
             }
             if [[ ${_majmin#0:} = $_majmin ]]; then
                 echo $_majmin
@@ -239,6 +244,22 @@ find_dev_fstype() {
 # finds the major:minor of the block device backing the root filesystem.
 find_root_block_device() { find_block_device /; }
 
+for_each_host_dev_fs()
+{
+    local _func="$1"
+    for f in ${host_fs_types[@]}; do
+        OLDIFS="$IFS"
+        IFS="|"
+        set -- $f
+        IFS="$OLDIFS"
+        dev=$1
+        [[ -b /dev/block/$dev ]] && dev="/dev/block/$dev"
+        [[ -b $dev ]] || continue
+        fs="$2"
+        $_func $dev $fs
+    done
+}
+
 # Walk all the slave relationships for a given block device.
 # Stop when our helper function returns success
 # $1 = function to call on every found block device
diff --git a/modules.d/90btrfs/module-setup.sh b/modules.d/90btrfs/module-setup.sh
index 7b0b424..f89713f 100755
--- a/modules.d/90btrfs/module-setup.sh
+++ b/modules.d/90btrfs/module-setup.sh
@@ -11,14 +11,14 @@ check() {
     . $dracutfunctions
     [[ $debug ]] && set -x
 
-    is_btrfs() { get_fs_type /dev/block/$1 | grep -q btrfs; }
-
-    if [[ $hostonly ]]; then
-        _rootdev=$(find_root_block_device)
-        if [[ $_rootdev ]]; then
-            is_btrfs "$_rootdev" || return 1
-        fi
-    fi
+    [[ $hostonly ]] && {
+        local _found
+        for fs in $host_fs_types; do
+            [[ "$fs" = "|btrfs" ]] && _found="1"
+        done
+        [[ $_found ]] || return 1
+        unset _found
+    }
 
     return 0
 }
diff --git a/modules.d/90crypt/module-setup.sh b/modules.d/90crypt/module-setup.sh
index 2a8268f..42c6b48 100755
--- a/modules.d/90crypt/module-setup.sh
+++ b/modules.d/90crypt/module-setup.sh
@@ -9,18 +9,24 @@ check() {
 
     . $dracutfunctions
 
-    is_crypt() { [[ $(get_fs_type /dev/block/$1) = crypto_LUKS ]]; }
+    check_crypt() {
+        local dev=$1 fs=$2
+        [[ $fs = "crypto_LUKS" ]] || continue
+        ID_FS_UUID=$(udevadm info --query=property --name=$dev \
+            | while read line; do
+                [[ ${line#ID_FS_UUID} = $line ]] && continue
+                eval "$line"
+                echo $ID_FS_UUID
+                break
+                done)
+        [[ ${ID_FS_UUID} ]] || continue
+        echo " rd.luks.uuid=${ID_FS_UUID} " >> "${initdir}/etc/cmdline.d/90crypt.conf"
+    }
 
     [[ $hostonly ]] && {
-        _rootdev=$(find_root_block_device)
-        if [[ $_rootdev ]]; then
-            # root lives on a block device, so we can be more precise about
-            # hostonly checking
-            check_block_and_slaves is_crypt "$_rootdev" || return 1
-        else
-            # root is not on a block device, use the shotgun approach
-            blkid | grep -q crypto\?_LUKS || return 1
-        fi
+        [[ -d "${initdir}/etc/cmdline.d" ]] || mkdir -p "${initdir}/etc/cmdline.d"
+        for_each_host_dev_fs check_crypt
+        [ -f "${initdir}/etc/cmdline.d/90crypt.conf" ] || return 1
     }
 
     return 0
diff --git a/modules.d/90dmraid/module-setup.sh b/modules.d/90dmraid/module-setup.sh
index 87a4d1e..9de6c63 100755
--- a/modules.d/90dmraid/module-setup.sh
+++ b/modules.d/90dmraid/module-setup.sh
@@ -11,19 +11,37 @@ check() {
     . $dracutfunctions
     [[ $debug ]] && set -x
 
-    is_dmraid() { get_fs_type /dev/block/$1 |grep -v linux_raid_member | \
-        grep -q _raid_member; }
+    check_dmraid() {
+        local dev=$1 fs=$2 holder DEVPATH DM_NAME
+        [[ "$fs" = "linux_raid_member" ]] && continue
+        [[ "$fs" = "${fs%%_raid_member}" ]] && continue
+
+        DEVPATH=$(udevadm info --query=property --name=$dev \
+            | while read line; do
+                [[ ${line#DEVPATH} = $line ]] && continue
+                eval "$line"
+                echo $DEVPATH
+                break
+                done)
+        for holder in /sys/$DEVPATH/holders/*; do
+            [[ -e $holder ]] || continue
+            DM_NAME=$(udevadm info --query=property --path=$holder \
+                | while read line; do
+                    [[ ${line#DM_NAME} = $line ]] && continue
+                    eval "$line"
+                    echo $DM_NAME
+                    break
+                    done)
+        done
+
+        [[ ${DM_NAME} ]] || continue
+        echo " rd.dm.uuid=${DM_NAME} " >> "${initdir}/etc/cmdline.d/90dmraid.conf"
+    }
 
     [[ $hostonly ]] && {
-        _rootdev=$(find_root_block_device)
-        if [[ $_rootdev ]]; then
-        # root lives on a block device, so we can be more precise about
-        # hostonly checking
-            check_block_and_slaves is_dmraid "$_rootdev" || return 1
-        else
-        # root is not on a block device, use the shotgun approach
-            dmraid -r | grep -q ok || return 1
-        fi
+        [[ -d "${initdir}/etc/cmdline.d" ]] || mkdir -p "${initdir}/etc/cmdline.d"
+        for_each_host_dev_fs check_dmraid
+        [ -f "${initdir}/etc/cmdline.d/90dmraid.conf" ] || return 1
     }
 
     return 0
diff --git a/modules.d/90kernel-modules/module-setup.sh b/modules.d/90kernel-modules/module-setup.sh
index d7aadd8..8d2ab91 100755
--- a/modules.d/90kernel-modules/module-setup.sh
+++ b/modules.d/90kernel-modules/module-setup.sh
@@ -50,7 +50,11 @@ installkernel() {
                 rm -fr ${initdir}/lib/modules/*/kernel/fs/ocfs2
             fi
         else
-            hostonly='' instmods $(get_fs_type "/dev/block/$(find_root_block_device)")
+            inst_fs() {
+                [[ $2 ]] || return 1
+                hostonly='' instmods $2
+            }
+            for_each_host_dev_fs inst_fs
         fi
     else
         hostonly='' instmods $drivers
diff --git a/modules.d/90lvm/module-setup.sh b/modules.d/90lvm/module-setup.sh
index 40dc350..87751cb 100755
--- a/modules.d/90lvm/module-setup.sh
+++ b/modules.d/90lvm/module-setup.sh
@@ -10,18 +10,23 @@ check() {
     . $dracutfunctions
     [[ $debug ]] && set -x
 
-    is_lvm() { [[ $(get_fs_type /dev/block/$1) = LVM2_member ]]; }
+    check_lvm() {
+        local dev=$1
+        DM_LV_NAME=$(udevadm info --query=property --name=$dev \
+            | while read line; do
+                [[ ${line#DM_LV_NAME} = $line ]] && continue
+                eval "$line"
+                echo $DM_LV_NAME
+                break
+                done)
+        [[ ${DM_LV_NAME} ]] || continue
+        echo " rd.lvm.lv=${DM_LV_NAME} " >> "${initdir}/etc/cmdline.d/90lvm.conf"
+    }
 
     [[ $hostonly ]] && {
-        _rootdev=$(find_root_block_device)
-        if [[ $_rootdev ]]; then
-            # root lives on a block device, so we can be more precise about
-            # hostonly checking
-            check_block_and_slaves is_lvm "$_rootdev" || return 1
-        else
-            # root is not on a block device, use the shotgun approach
-            blkid | grep -q LVM2_member || return 1
-        fi
+        [[ -d "${initdir}/etc/cmdline.d" ]] || mkdir -p "${initdir}/etc/cmdline.d"
+        for_each_host_dev_fs check_lvm
+        [ -f "${initdir}/etc/cmdline.d/90lvm.conf" ] || return 1
     }
 
     return 0
diff --git a/modules.d/90mdraid/module-setup.sh b/modules.d/90mdraid/module-setup.sh
index 029d667..05e0127 100755
--- a/modules.d/90mdraid/module-setup.sh
+++ b/modules.d/90mdraid/module-setup.sh
@@ -10,18 +10,38 @@ check() {
     . $dracutfunctions
     [[ $debug ]] && set -x
 
-    is_mdraid() { [[ -d "/sys/dev/block/$1/md" ]]; }
+    check_mdraid() {
+        local dev=$1 fs=$2 holder DEVPATH MD_UUID
+        [[ "$fs" = "linux_raid_member" ]] && continue
+        [[ "$fs" = "${fs%%_raid_member}" ]] && continue
+
+        DEVPATH=$(udevadm info --query=property --name=$dev \
+            | while read line; do
+                [[ ${line#DEVPATH} = $line ]] && continue
+                eval "$line"
+                echo $DEVPATH
+                break
+                done)
+
+        for holder in /sys/$DEVPATH/holders/*; do
+            [[ -e $holder ]] || continue
+            MD_UUID=$(udevadm info --query=property --path=$holder \
+                | while read line; do
+                    [[ ${line#MD_UUID} = $line ]] && continue
+                    eval "$line"
+                    echo $MD_UUID
+                    break
+                    done)
+        done
+
+        [[ ${MD_UUID} ]] || continue
+        echo " rd.md.uuid=${MD_UUID} " >> "${initdir}/etc/cmdline.d/90mdraid.conf"
+    }
 
     [[ $hostonly ]] && {
-        _rootdev=$(find_root_block_device)
-        if [[ $_rootdev ]]; then
-            # root lives on a block device, so we can be more precise about
-            # hostonly checking
-            check_block_and_slaves is_mdraid "$_rootdev" || return 1
-        else
-            # root is not on a block device, use the shotgun approach
-            blkid | egrep -q '(linux|isw|ddf)_raid' || return 1
-        fi
+        [[ -d "${initdir}/etc/cmdline.d" ]] || mkdir -p "${initdir}/etc/cmdline.d"
+        for_each_host_dev_fs check_mdraid
+        [[ -f "${initdir}/etc/cmdline.d/90mdraid.conf" ]] || return 1
     }
 
     return 0
diff --git a/modules.d/95fstab-sys/module-setup.sh b/modules.d/95fstab-sys/module-setup.sh
index c22b047..ea9db83 100755
--- a/modules.d/95fstab-sys/module-setup.sh
+++ b/modules.d/95fstab-sys/module-setup.sh
@@ -11,6 +11,6 @@ depends() {
 }
 
 install() {
-    dracut_install /etc/fstab.sys
+    inst /etc/fstab.sys /etc/fstab
     inst_hook pre-pivot 00 "$moddir/mount-sys.sh"
 }
diff --git a/modules.d/95nfs/module-setup.sh b/modules.d/95nfs/module-setup.sh
index c5f97c9..bb3b793 100755
--- a/modules.d/95nfs/module-setup.sh
+++ b/modules.d/95nfs/module-setup.sh
@@ -3,13 +3,19 @@
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 
 check() {
-    # If hostonly was requested, fail the check if we are not actually
-    # booting from root.
-    [ $hostonly ] && ! egrep -q '/ nfs[34 ]' /proc/mounts && return 1
-
     # If our prerequisites are not met, fail anyways.
     type -P rpcbind >/dev/null || type -P portmap >/dev/null || return 1
     type -P rpc.statd mount.nfs mount.nfs4 umount >/dev/null || return 1
+
+    [[ $hostonly ]] && {
+        for fs in ${host_fs_types[@]}; do
+            strstr "$fs" "|nfs"  && return 0
+            strstr "$fs" "|nfs3" && return 0
+            strstr "$fs" "|nfs4" && return 0
+        done
+        return 255
+    }
+
     return 0
 }
 
diff --git a/modules.d/99base/module-setup.sh b/modules.d/99base/module-setup.sh
index f6dc920..5297a9d 100755
--- a/modules.d/99base/module-setup.sh
+++ b/modules.d/99base/module-setup.sh
@@ -38,6 +38,7 @@ install() {
     dracut_install switch_root || dfatal "Failed to install switch_root"
 
     inst "$moddir/dracut-lib.sh" "/lib/dracut-lib.sh"
+    inst "$moddir/mount-hook.sh" "/usr/bin/mount-hook"
     inst_hook cmdline 10 "$moddir/parse-root-opts.sh"
     mkdir -p "${initdir}/var"
     [ -x /lib/systemd/systemd-timestamp ] && inst /lib/systemd/systemd-timestamp
diff --git a/modules.d/99fs-lib/module-setup.sh b/modules.d/99fs-lib/module-setup.sh
index 04b63f1..9c900cc 100755
--- a/modules.d/99fs-lib/module-setup.sh
+++ b/modules.d/99fs-lib/module-setup.sh
@@ -10,6 +10,32 @@ depends() {
     return 0
 }
 
+
+echo_fs_helper() {
+    local dev=$1 fs=$2
+    case "$fs" in
+        xfs)
+            echo -n " xfs_db xfs_repair xfs_check "
+            ;;
+        ext?)
+            echo -n " e2fsck "
+            ;;
+        jfs)
+            echo -n " jfs_fsck "
+            ;;
+        reiserfs)
+            echo -n " reiserfsck "
+            ;;
+        btrfs)
+            echo -n " btrfsck "
+            ;;
+        *)
+            [[ -x fsck.$fs ]] && echo -n " fsck.$fs "
+            ;;
+    esac
+}
+
+
 install() {
     local _helpers
 
@@ -25,33 +51,8 @@ install() {
             e2fsck jfs_fsck reiserfsck btrfsck
         "
         if [[ $hostonly ]]; then
-            print_fs_type() { get_fs_type /dev/block/$1; }
-            _rootdev=$(find_root_block_device)
-            if [[ $_rootdev ]]; then
-                _helpers="umount mount "
-                for fs in $(check_block_and_slaves print_fs_type  "$_rootdev"); do
-                    case "$fs" in
-                        xfs)
-                            _helpers+=" xfs_db xfs_repair xfs_check "
-                            ;;
-                        ext?)
-                            _helpers+=" e2fsck "
-                            ;;
-                        jfs)
-                            _helpers+=" jfs_fsck "
-                            ;;
-                        reiserfs)
-                            _helpers+=" reiserfsck "
-                            ;;
-                        btrfs)
-                            _helpers+=" btrfsck "
-                            ;;
-                        *)
-                            [[ -x fsck.$fs ]] && _helpers+= " fsck.$fs "
-                            ;;
-                    esac
-                done
-            fi
+            _helpers="umount mount "
+            _helpers+=$(for_each_host_dev_fs echo_fs_helper)
         fi
     else
         _helpers="$fscks"