From: Petr Tesarik <ptesarik@suse.com>
Date: Fri, 20 Apr 2018 17:26:22 +0200
Subject: Handle additional mounts in the kdump dracut module
References: bsc#1094581, bsc#1072711
Upstream: merged
Git-commit: bd3cc31f3b91e81e6acc00f314142bbda9ace495

This change is needed to fix FADUMP, because in that case the kdump
initrd is also used during normal boot, so it can get overwritten
with an invocation of "mkinitrd".

Currently, dracut does not provide an API to add more mounts from a
module, so part of the logic which sets up host devices and
filesystem mappings must be copied to the kdump module.

The approach is not clean, but probably still better than passing
some variables from mkdumprd to the kdump dracut module through
environment variables, which was done before. Yes, this means that
the ugly export/import functions can be removed and forgotten.

Signed-off-by: Petr Tesarik <ptesarik@suse.com>
Signed-off-by: Michal Koutny <mkoutny@suse.com>
---
 init/mkdumprd              |   14 --------
 init/module-setup.sh       |   75 +++++++++++++++++++++++++++++++++++++--------
 init/setup-kdump.functions |   53 -------------------------------
 3 files changed, 62 insertions(+), 80 deletions(-)

--- a/init/mkdumprd
+++ b/init/mkdumprd
@@ -128,20 +128,6 @@ function run_dracut()
 	KERNELVERSION=$(get_kernel_version "$KERNEL")
     fi
 
-    # add mount points
-    kdump_get_mountpoints || return 1
-    i=0
-    while [ $i -lt ${#kdump_mnt[@]} ]
-    do
-	if [ -n "${kdump_mnt[i]}" ] ; then
-	    DRACUT_ARGS="$DRACUT_ARGS --mount '${kdump_dev[i]} ${kdump_mnt[i]} ${kdump_fstype[i]} ${kdump_opts[i]}'"
-	fi
-	i=$((i+1))
-    done
-
-    # Make resolved variables visible to the dracut module
-    kdump_export_targets
-
     DRACUT_ARGS="$DRACUT_ARGS --add 'kdump' $INITRD $KERNELVERSION"
     echo "Regenerating kdump initrd ..." >&2
     eval "bash -$- $DRACUT $DRACUT_ARGS"
--- a/init/module-setup.sh
+++ b/init/module-setup.sh
@@ -40,10 +40,71 @@ kdump_check_net() {
     kdump_ifname_config "$kdump_host_if"
 }
 
+kdump_get_fs_type() {
+    local _dev="/dev/block/$1"
+    local _fstype
+    if [ -b "$_dev" ] && _fstype=$(get_fs_env "$_dev") ; then
+        host_fs_types["$(readlink -f "$_dev")"]="$_fstype"
+    elif _fstype=$(find_dev_fstype "$_dev"); then
+        host_fs_types["$_dev"]="$_fstype"
+    fi
+    return 1
+}
+
+kdump_add_host_dev() {
+    local _dev=$1
+    [[ " ${host_devs[@]} " == *" $_dev "* ]] && return
+    host_devs+=( "$_dev" )
+    check_block_and_slaves_all kdump_get_fs_type "$(get_maj_min "$_dev")"
+}
+
+kdump_add_mnt() {
+    local _idx=$1
+    local _dev="${kdump_dev[_idx]}"
+    local _mp="${kdump_mnt[_idx]}"
+
+    # Convert system root mounts to bind mounts
+    if [ "$KDUMP_FADUMP" = "yes" -a "${_mp%/*}" = "/kdump" ] ; then
+        mkdir -p "$initdir/etc"
+        echo "/sysroot $_mp none bind 0 0" >> "$initdir/etc/fstab"
+        return
+    fi
+
+    case "$_dev" in
+        UUID=*|LABEL=*|PARTUUID=*|PARTLABLE=*)
+            _dev=$(blkid -l -t "$_dev" -o device)
+            ;;
+    esac
+    kdump_add_host_dev "$_dev"
+    host_fs_types["$_dev"]="${kdump_fstype[_idx]}"
+    if [ "${kdump_fstype[_idx]}" = btrfs ] ; then
+        for _dev in $() ; do
+            kdump_add_host_dev "$_dev"
+        done
+    fi
+
+    mkdir -p "$initdir/etc"
+    local _passno=2
+    [ "${kdump_fstype[_idx]}" = nfs ] && _passno=0
+    echo "${kdump_dev[_idx]} ${kdump_mnt[_idx]} ${kdump_fstype[_idx]} ${kdump_opts[_idx]} 0 $_passno" >> "$initdir/etc/fstab"
+}
+
 check() {
     # Get configuration
-    kdump_import_targets || return 1
     kdump_get_config || return 1
+
+    # add mount points
+    if ! [[ $mount_needs ]] ; then
+        kdump_get_mountpoints || return 1
+
+        local _i=0
+        while [ $_i -lt ${#kdump_mnt[@]} ]
+        do
+	    [ -n "${kdump_mnt[_i]}" ] && kdump_add_mnt $_i
+	    _i=$((_i+1))
+        done
+    fi
+
     kdump_check_net
 
     return 255
@@ -183,18 +244,6 @@ install() {
     kdump_map_mpath_wwid
     for_each_host_dev_and_slaves_all kdump_add_mpath_dev
 
-    # Convert system root mounts to bind mounts
-    if [ "$KDUMP_FADUMP" = "yes" ] ; then
-	local i line
-	for i in "${!fstab_lines[@]}"
-	do
-	    line=( ${fstab_lines[i]} )
-	    if [ "${line[1]%/*}" = "/kdump" ] ; then
-		fstab_lines[i]="/sysroot ${line[1]} none bind 0 0"
-	    fi
-	done
-    fi
-
     kdump_setup_files "$initdir" "$kdump_mpath_wwids"
 
     inst_hook cmdline 50 "$moddir/kdump-root.sh"
--- a/init/setup-kdump.functions
+++ b/init/setup-kdump.functions
@@ -633,59 +633,6 @@ function kdump_get_targets()						   # {
 }									   # }}}
 
 #
-# Print array content so that it can be used as bash input
-#
-# Parameters:
-#   1) name  array variable to be printed
-# Output:
-#   shell code that can be passed to eval to restore the array
-function kdump_print_array()
-{
-    local name="$1"
-    local i
-    echo -n "( "
-    for i in $(eval printf \"%q \" \"\${!$name[@]}\")
-    do
-	printf "[%s]=%q " "$i" "$(eval echo \"\${$name[i]}\")"
-    done
-    echo ")"
-}
-
-#
-# Export kdump_*[] arrays, returned by kdump_get_targets.
-#
-# Input variables:
-#   kdump_URL[], kdump_Protocol[], kdump_Host[], kdump_Realpath,
-#   kdump_mnt[]
-# Output variables (exported):
-#   KDUMP_x_URL, KDUMP_x_Protocol, KDUMP_x_Host, KDUMP_x_Realpath,
-#   KDUMP_x_mnt
-function kdump_export_targets()						   # {{{
-{
-    export KDUMP_x_URL=$( kdump_print_array kdump_URL )
-    export KDUMP_x_Protocol=$( kdump_print_array kdump_Protocol )
-    export KDUMP_x_Host=$( kdump_print_array kdump_Host )
-    export KDUMP_x_Realpath=$( kdump_print_array kdump_Realpath )
-    export KDUMP_x_mnt=$( kdump_print_array kdump_mnt )
-    export kdump_max
-}									   # }}}
-
-#
-# Import kdump_*[] arrays from environment.
-#
-# Input/Output Variables:
-#   reverse of kdump_export_arrays
-function kdump_import_targets()						   # {{{
-{
-    eval "kdump_URL=$KDUMP_x_URL"
-    eval "kdump_Protocol=$KDUMP_x_Protocol"
-    eval "kdump_Host=$KDUMP_x_Host"
-    eval "kdump_Realpath=$KDUMP_x_Realpath"
-    eval "kdump_mnt=$KDUMP_x_mnt"
-    test ${#kdump_URL[@]} -gt 0
-}									   # }}}
-
-#
 # Read and normalize /etc/fstab and /proc/mounts (if exists).
 # The following transformations are done:
 #   - initial TABs and SPACEs are removed
