Blob Blame History Raw
From 1b7fd0fa3eded954ed5baad7aee49507a607275b Mon Sep 17 00:00:00 2001
From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Tue, 20 Dec 2011 14:09:57 +0800
Subject: [PATCH] Check module dependencies of mount points

Like -H, we need to poll every module to check if it is needed
to mount a specific device in '--mount'.

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 dracut                                  |    5 ++-
 dracut-functions                        |   68 +++++++++++++++++++++++++++++-
 modules.d/00bootchart/module-setup.sh   |    1 +
 modules.d/10i18n/module-setup.sh        |    1 +
 modules.d/10rpmversion/module-setup.sh  |    1 +
 modules.d/50plymouth/module-setup.sh    |    1 +
 modules.d/90btrfs/module-setup.sh       |    2 +-
 modules.d/90crypt/module-setup.sh       |    2 +-
 modules.d/90dmraid/module-setup.sh      |    2 +-
 modules.d/90lvm/module-setup.sh         |    2 +-
 modules.d/90mdraid/module-setup.sh      |    2 +-
 modules.d/95fcoe/module-setup.sh        |    2 +-
 modules.d/95nfs/module-setup.sh         |    2 +-
 modules.d/97biosdevname/module-setup.sh |    1 +
 modules.d/98usrmount/module-setup.sh    |    1 +
 15 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/dracut b/dracut
index 04dc8ec..c3584c0 100755
--- a/dracut
+++ b/dracut
@@ -633,9 +633,12 @@ else
     done
 fi
 
+mods_to_load=""
 # check all our modules to see if they should be sourced.
 # This builds a list of modules that we will install next.
-check_module_dir
+for_each_module_dir check_module
+for_each_module_dir check_mount
+
 modules_loaded=" "
 # source our modules.
 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
diff --git a/dracut-functions b/dracut-functions
index 8944430..2f9e713 100755
--- a/dracut-functions
+++ b/dracut-functions
@@ -783,6 +783,67 @@ module_installkernel() {
     fi
 }
 
+module_check_mount() {
+    local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
+    local _ret
+    mount_needs=1
+    [[ -d $_moddir ]] || return 1
+    if [[ ! -f $_moddir/module-setup.sh ]]; then
+        # if we do not have a check script, we are unconditionally included
+        [[ -x $_moddir/check ]] || return 0
+        mount_needs=1 $_moddir/check 0
+        _ret=$?
+    else
+        unset check depends install installkernel
+        . $_moddir/module-setup.sh
+        is_func check || return 1
+        check 0
+        _ret=$?
+        unset check depends install installkernel
+    fi
+    unset mount_needs
+    return $_ret
+}
+
+check_mount() {
+    local _mod=$1
+    local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
+    local _ret
+    local _moddep
+    # If we are already scheduled to be loaded, no need to check again.
+    strstr " $mods_to_load " " $_mod " && return 0
+    strstr " $mods_checked_as_dep " " $_mod " && return 1
+
+    # This should never happen, but...
+    [[ -d $_moddir ]] || return 1
+
+    [[ $2 ]] || mods_checked_as_dep+=" $_mod "
+
+    strstr " $omit_dracutmodules " " $_mod " && return 1
+
+    if [ "${#host_fs_types[*]}" -gt 0 ]; then
+        module_check_mount $_mod || return 1
+    else
+        # skip this module
+        return 1
+    fi
+
+    for _moddep in $(module_depends $_mod); do
+        # handle deps as if they were manually added
+        strstr " $add_dracutmodules " " $_moddep " || \
+            add_dracutmodules+=" $_moddep "
+        strstr " $force_add_dracutmodules " " $_moddep " || \
+            force_add_dracutmodules+=" $_moddep "
+        # if a module we depend on fail, fail also
+        check_module $_moddep || return 1
+    done
+
+    strstr " $mods_to_load " " $_mod " || \
+        mods_to_load+=" $_mod "
+
+    return 0
+}
+
 check_module() {
     local _mod=$1
     local _moddir=$(echo ${dracutbasedir}/modules.d/??${1})
@@ -834,14 +895,15 @@ check_module() {
     return 0
 }
 
-check_module_dir() {
+for_each_module_dir() {
     local _modcheck
     local _mod
     local _moddir
-    mods_to_load=""
+    local _func
+    _func=$1
     for _moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
         _mod=${_moddir##*/}; _mod=${_mod#[0-9][0-9]}
-        check_module $_mod 1
+        $_func $_mod 1
     done
 
     # Report any missing dracut modules, the user has specified
diff --git a/modules.d/00bootchart/module-setup.sh b/modules.d/00bootchart/module-setup.sh
index bf71b14..17dd137 100755
--- a/modules.d/00bootchart/module-setup.sh
+++ b/modules.d/00bootchart/module-setup.sh
@@ -3,6 +3,7 @@
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 
 check() {
+    [[ "$mount_needs" ]] && return 1
     [ -x /sbin/bootchartd ] || return 1
     return 255
 }
diff --git a/modules.d/10i18n/module-setup.sh b/modules.d/10i18n/module-setup.sh
index 8342fb4..37c7c09 100755
--- a/modules.d/10i18n/module-setup.sh
+++ b/modules.d/10i18n/module-setup.sh
@@ -3,6 +3,7 @@
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 
 check() {
+    [[ "$mount_needs" ]] && return 1
     return 0
 }
 
diff --git a/modules.d/10rpmversion/module-setup.sh b/modules.d/10rpmversion/module-setup.sh
index 676775f..4c021ad 100755
--- a/modules.d/10rpmversion/module-setup.sh
+++ b/modules.d/10rpmversion/module-setup.sh
@@ -3,6 +3,7 @@
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 
 check() {
+    [[ "$mount_needs" ]] && return 1
     [ -f /etc/redhat-release ]
 }
 
diff --git a/modules.d/50plymouth/module-setup.sh b/modules.d/50plymouth/module-setup.sh
index df0e8d6..eedc842 100755
--- a/modules.d/50plymouth/module-setup.sh
+++ b/modules.d/50plymouth/module-setup.sh
@@ -3,6 +3,7 @@
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 
 check() {
+    [[ "$mount_needs" ]] && return 1
     [[ -x /sbin/plymouthd && -x /bin/plymouth && -x /usr/sbin/plymouth-set-default-theme ]]
 }
 
diff --git a/modules.d/90btrfs/module-setup.sh b/modules.d/90btrfs/module-setup.sh
index d4abbaf..a141dda 100755
--- a/modules.d/90btrfs/module-setup.sh
+++ b/modules.d/90btrfs/module-setup.sh
@@ -11,7 +11,7 @@ check() {
     . $dracutfunctions
     [[ $debug ]] && set -x
 
-    [[ $hostonly ]] && {
+    [[ $hostonly ]] || [[ $mount_needs ]] && {
         local _found
         for fs in $host_fs_types; do
             [[ "$fs" = "|btrfs" ]] && _found="1"
diff --git a/modules.d/90crypt/module-setup.sh b/modules.d/90crypt/module-setup.sh
index 42c6b48..a92c187 100755
--- a/modules.d/90crypt/module-setup.sh
+++ b/modules.d/90crypt/module-setup.sh
@@ -23,7 +23,7 @@ check() {
         echo " rd.luks.uuid=${ID_FS_UUID} " >> "${initdir}/etc/cmdline.d/90crypt.conf"
     }
 
-    [[ $hostonly ]] && {
+    [[ $hostonly ]] || [[ $mount_needs ]] && {
         [[ -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
diff --git a/modules.d/90dmraid/module-setup.sh b/modules.d/90dmraid/module-setup.sh
index 9de6c63..19f2ce6 100755
--- a/modules.d/90dmraid/module-setup.sh
+++ b/modules.d/90dmraid/module-setup.sh
@@ -38,7 +38,7 @@ check() {
         echo " rd.dm.uuid=${DM_NAME} " >> "${initdir}/etc/cmdline.d/90dmraid.conf"
     }
 
-    [[ $hostonly ]] && {
+    [[ $hostonly ]] || [[ $mount_needs ]] && {
         [[ -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
diff --git a/modules.d/90lvm/module-setup.sh b/modules.d/90lvm/module-setup.sh
index 87751cb..c910f13 100755
--- a/modules.d/90lvm/module-setup.sh
+++ b/modules.d/90lvm/module-setup.sh
@@ -23,7 +23,7 @@ check() {
         echo " rd.lvm.lv=${DM_LV_NAME} " >> "${initdir}/etc/cmdline.d/90lvm.conf"
     }
 
-    [[ $hostonly ]] && {
+    [[ $hostonly ]] || [[ $mount_needs ]] && {
         [[ -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
diff --git a/modules.d/90mdraid/module-setup.sh b/modules.d/90mdraid/module-setup.sh
index 05e0127..8c3e2bb 100755
--- a/modules.d/90mdraid/module-setup.sh
+++ b/modules.d/90mdraid/module-setup.sh
@@ -38,7 +38,7 @@ check() {
         echo " rd.md.uuid=${MD_UUID} " >> "${initdir}/etc/cmdline.d/90mdraid.conf"
     }
 
-    [[ $hostonly ]] && {
+    [[ $hostonly ]] || [[ $mount_needs ]] && {
         [[ -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
diff --git a/modules.d/95fcoe/module-setup.sh b/modules.d/95fcoe/module-setup.sh
index b4cee97..e66798b 100755
--- a/modules.d/95fcoe/module-setup.sh
+++ b/modules.d/95fcoe/module-setup.sh
@@ -6,7 +6,7 @@ check() {
     # FIXME
     # If hostonly was requested, fail the check until we have some way of
     # knowing we are booting from FCoE
-    [[ $hostonly ]] && return 1
+    [[ $hostonly ]] || [[ $mount_needs ]] && return 1
 
     return 0
 }
diff --git a/modules.d/95nfs/module-setup.sh b/modules.d/95nfs/module-setup.sh
index bb3b793..641d917 100755
--- a/modules.d/95nfs/module-setup.sh
+++ b/modules.d/95nfs/module-setup.sh
@@ -7,7 +7,7 @@ check() {
     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 ]] && {
+    [[ $hostonly ]] || [[ $mount_needs ]] && {
         for fs in ${host_fs_types[@]}; do
             strstr "$fs" "|nfs"  && return 0
             strstr "$fs" "|nfs3" && return 0
diff --git a/modules.d/97biosdevname/module-setup.sh b/modules.d/97biosdevname/module-setup.sh
index 834831f..4d492a9 100755
--- a/modules.d/97biosdevname/module-setup.sh
+++ b/modules.d/97biosdevname/module-setup.sh
@@ -3,6 +3,7 @@
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 
 check() {
+    [[ "$mount_needs" ]] && return 1
     type -P biosdevname >/dev/null || return 1
     return 0
 }
diff --git a/modules.d/98usrmount/module-setup.sh b/modules.d/98usrmount/module-setup.sh
index 8f7be10..5844383 100755
--- a/modules.d/98usrmount/module-setup.sh
+++ b/modules.d/98usrmount/module-setup.sh
@@ -3,6 +3,7 @@
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 
 check() {
+    [[ $mount_needs ]] && return 1
     return 0
 }