From 480d772f22a2f690928c59c7c0ebfa7dc00332ea Mon Sep 17 00:00:00 2001 From: Harald Hoyer 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"