File kdump-get-multipath-wwid-from-sysfs.patch of Package kdump.624

From: Petr Tesarik <ptesarik@suse.cz>
Date: Mon Sep 22 17:23:49 2014 +0200
Subject: Get required multipath wwids from sysfs
References: bnc#883883
Patch-mainline: v0.8.16
Git-commit: 4aa46801a53070dc0b0c27f4247cdc8e2b678694
Git-commit: bb073caafcecfe667fba528c170f89bb29447a1d

The dracut code path must use for_each_host_dev_and_slaves_all to
find multipath devices that are "hidden" beneath e.g. an LVM volume.
That will iterate over all devices in the chain down to each physical
device. Note that /lib/udev/scsi_id sends a low-level SCSI command to
the device to find out the WWID. If it sends it to an unreachable
device in an active-passive multipath setup, it may hang indefinitely.

But the WWID is already available as the name of the multipath device,
so we can get it from the kernel via sysfs.

Signed-off-by: Petr Tesarik <ptesarik@suse.cz>

---
 init/module-setup.sh       |   18 +++++++++++++++++-
 init/setup-kdump.functions |   41 +++++++++++++++++++++++++++--------------
 init/setup-kdump.sh        |   16 +++++++++++++++-
 3 files changed, 59 insertions(+), 16 deletions(-)

--- a/init/module-setup.sh
+++ b/init/module-setup.sh
@@ -11,12 +11,28 @@ depends() {
     echo drm
 }
 
+kdump_add_mpath_dev() {
+    local _major=${1%:*}
+    local _minor=${1#*:}
+    local _wwid
+
+    eval _wwid=\$kdump_mpath_wwid_${_major}_${_minor}
+    if [ -n "$_wwid" ] ; then
+	kdump_mpath_wwids+=$(printf "%q " "wwid $_wwid")
+    fi
+}
+
 install() {
     # Get configuration
     kdump_get_config || return 1
     kdump_import_targets
 
-    kdump_setup_files "$initdir" "${!host_fs_types[*]}"
+    # Get a list of required multipath devices
+    local kdump_mpath_wwids
+    kdump_map_mpath_wwid
+    for_each_host_dev_and_slaves_all kdump_add_mpath_dev
+
+    kdump_setup_files "$initdir" "$kdump_mpath_wwids"
 
     if dracut_module_included "systemd" ; then
 	rm -f "${initdir}/$systemdutildir"/system-generators/dracut-rootfs-generator
--- a/init/setup-kdump.functions
+++ b/init/setup-kdump.functions
@@ -542,24 +542,36 @@ function kdump_modify_config()						   #
 }									   # }}}
 
 #
+# Build a mapping between multipath devices and their wwid
+# This map would be best stored in an associative array, but
+# then bash 4.0+ would be needed (and SLES11 has bash 3.2).
+#
+# Output variables:
+#   kdump_mpath_wwid_$major_$minor  wwid of the given major/minor device
+function kdump_map_mpath_wwid()						   # {{{
+{
+    local f _dir _uuid _wwid _dev
+    for f in /sys/block/*/dm/uuid ; do
+	eval "_uuid=\$(<$f)" 2>/dev/null
+	[[ "$_uuid" = mpath-* ]] || continue
+	_dir="${f%/dm/uuid}"
+	_wwid=$(<"$_dir"/dm/name)
+	_dev=$(<"$_dir"/dev)
+	eval kdump_mpath_wwid_${_dev/:/_}=\$_wwid
+    done
+}									   # }}}
+
+#
 # Keep only required devices in multipath.conf
 #
 # Parameters:
-#   1) devices: list of all required block devices
+#   1) devices: list of all required devices (multipath.conf syntax)
 # Output:
 #   filtered multipath.conf
 function kdump_modify_multipath()					   # {{{
 {
-    local devices="$1"
-    local i bd scsi_id
     local -a wwids
-
-    i=0
-    for bd in $devices ; do
-	scsi_id=$(/lib/udev/scsi_id --whitelisted --device="$bd")
-	[ -z "$scsi_id" ] && continue
-	wwids[i++]="wwid "\""$scsi_id"\"
-    done
+    eval wwids="($1)"
     kdumptool multipath "${wwids[@]}" \
 	< /etc/multipath.conf
 }									   # }}}
@@ -633,8 +645,9 @@ function kdump_init_dirs()						   # {{{
 #
 # Set up or create all necessary files
 # Parameters:
-#   1) outdir:   initrd temporary root
-#   2) dumpdevs: space-separated list of all block devices required by kdump
+#   1) outdir:    initrd temporary root
+#   2) mpathdevs: space-separated list of all multipath devices required
+#                 by kdump (using multipath.conf syntax)
 # Input variables:
 #   KDUMP_*      see kdump_get_config
 #   kdump_mnt[]  mountpoints in kdump environment
@@ -643,7 +656,7 @@ function kdump_init_dirs()						   # {{{
 function kdump_setup_files()						   # {{{
 {
     local outdir="${1%/}"
-    local dumpdevs="$2"
+    local mpathdevs="$2"
     local kdump_over_ssh
 
     #
@@ -673,7 +686,7 @@ function kdump_setup_files()						   # {
     # create modified multipath.conf
     #
     if [ -e /etc/multipath.conf ] ; then
-	kdump_modify_multipath "$dumpdevs" > "${outdir}/etc/multipath.conf"
+	kdump_modify_multipath "$mpathdevs" > "${outdir}/etc/multipath.conf"
     fi
 
     return 0
--- a/init/setup-kdump.sh
+++ b/init/setup-kdump.sh
@@ -28,9 +28,23 @@ fi
 # /lib/kdump/setup-kdump.functions was sourced from setup-kdumpfs.sh already
 
 #
+# Get a list of required multipath devices
+#
+mpath_wwids=
+kdump_map_mpath_wwid
+for bd in $blockdev ; do
+    update_blockdev $bd
+    [ $blockmajor -ge 0 -a $blockminor -ge 0 ] || continue
+    eval _wwid=\$kdump_mpath_wwid_${blockmajor}_${blockminor}
+    if [ -n "$_wwid" ] ; then
+	mpath_wwids="$mpath_wwids"$(printf "%q " "wwid $_wwid")
+    fi
+done
+
+#
 # Copy or create all necessary files for the initrd
 #
-kdump_setup_files "$tmp_mnt" "$blockdev"
+kdump_setup_files "$tmp_mnt" "$mpath_wwids"
 
 #
 # check if extra modules are needed