#!/bin/sh
-#
# geninitrd mod: dm-multipath
+USE_MULTIPATH=${USE_MULTIPATH:-yes}
# if we should init dm-multipath at boot
have_multipath=no
-if [ -x /sbin/multipath ]; then
- USE_MULTIPATH=yes
-else
- USE_MULTIPATH=no
-fi
-
# dm-multipath wwid which is used for rootfs
MPATH_WWID=
+# setup geninitrd module
+# @access public
+setup_mod_multipath() {
+ if [ ! -x /sbin/multipath ]; then
+ USE_MULTIPATH=no
+ fi
+}
+
# return true if node is multipath controlled
# @param string $node device node to be examined
# @access public
local devpath="$1"
# multipath disabled
- if ! is_yes "$USE_MULTIPATH"; then
+ if is_no "$USE_MULTIPATH"; then
return 1
fi
DM_NAME=
eval $(dm_export "$devpath")
if [ -z "$DM_NAME" ]; then
- die "dm_export failed unexpectedly"
+ die "Couldn't extract DM_NAME from $devpath"
fi
local MPATH_WWID=${DM_UUID##*-}
+
+ # just check if it is valid.
local info=$(multipath -l $MPATH_WWID)
if [ -z "$info" ]; then
return 1
DM_NAME=
eval $(dm_export "$devpath")
if [ -z "$DM_NAME" ]; then
- die "dm_export failed unexpectedly"
+ die "Couldn't extract DM_NAME from $devpath"
fi
# Partition:
return 1
fi
- debug "Finding modules for dm-multipath (WWID=$MPATH_WWID)"
+ verbose "Finding modules for dm-multipath (WWID=$MPATH_WWID)"
have_multipath=yes
- local dev phydevs=$(echo "$info" | awk '$2 ~ /^[0-9]+:[0-9]+:[0-9]+:[0-9]+$/{printf("/dev/%s\n", $3)}')
- for dev in $phydevs; do
- find_modules_for_devpath $dev
- lvm_ignore_devices="$lvm_ignore_devices $dev"
+
+ local p list
+ list=$(mp_parse_devs "$info")
+ for p in $list; do
+ find_modules_for_devpath $p
+ lvm_ignore_devices="$lvm_ignore_devices $p"
done
- local hw hwhandlers=$(echo "$info" | awk '/hwhandler=1/{sub(/.*hwhandler=1 /, ""); sub(/\]$/, ""); print}')
- for hw in $hwhandlers; do
- find_module "dm-$hw"
+ list=$(mp_parse_hwhandler "$info")
+ for p in $list; do
+ find_module "$p"
done
- local target targets=$(echo "$info" | awk '/prio=/{print $2}' | sort -u)
- for target in $targets; do
- find_module "dm-$target"
+ list=$(mp_parse_policy "$info")
+ for p in $list; do
+ find_module "dm-$p"
done
find_module "dm-mod"
# generate initrd fragment
# @access public
initrd_gen_multipath() {
+ if ! is_yes "$have_multipath"; then
+ return
+ fi
+
inst_d /sbin /lib/udev /etc/multipath
inst_exec /sbin/kpartx /sbin
inst_exec /sbin/multipath /sbin
# for udev callouts
- inst_exec /sbin/scsi_id /lib/udev
- inst_exec /sbin/mpath* /sbin
- egrep -v '^([ ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
+ local scsi_id=$(find_tool $(get_libdir /LIBDIR/udev/scsi_id) /lib/udev/scsi_id /sbin/scsi_id)
+ inst_exec $scsi_id /lib/udev
+
+ local installed=0
+ for _lib in $(get_libdir LIBDIR); do
+ if [ -d /$_lib/multipath ]; then
+ inst_d /$_lib/multipath
+ inst_exec /$_lib/multipath/* /$_lib/multipath
+ installed=1
+ break
+ fi
+ done
+ if [ "$installed" -eq 0 ]; then
+ inst_exec /sbin/mpath* /sbin
+ fi
+
+ grep -Ev '^([ ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
if [ -f /etc/multipath/bindings ]; then
- egrep -v '^([ ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
+ grep -Ev '^([ ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
else
touch $DESTDIR/etc/multipath/bindings
fi
esac
}
+# parse blockdevices behind multipath device
+# takes 'multipath -l' output as input
+mp_parse_devs() {
+ local info="$1"
+
+ # parse "0:0:1:0 sdf" -> /dev/sdf
+ #
+ # multipath-tools-0.4.8-0.12.amd64
+ # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
+ # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
+ # \_ round-robin 0 [prio=0][active]
+ # \_ 0:0:0:0 sda 8:0 [active][undef]
+ # \_ round-robin 0 [prio=0][enabled]
+ # \_ 0:0:1:0 sdf 8:80 [active][undef]
+ #
+ # multipath-tools-0.4.8-9.x86_64
+ # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
+ # size=7.0G features='0' hwhandler='0' wp=rw
+ # |-+- policy='round-robin 0' prio=-1 status=enabled
+ # | `- #:#:#:# sde 8:64 failed undef running
+ # `-+- policy='round-robin 0' prio=-1 status=active
+ # `- #:#:#:# sdb 8:16 active undef running
+
+ echo "$info" | awk '{
+ if (match($0, /[#0-9]+:[#0-9]+:[#0-9]+:[#0-9]+ [^ ]+ [0-9]+:[0-9]/)) {
+ # take whole matched part into "l" variable
+ l = substr($0, RSTART, RLENGTH);
+ split(l, a, " ");
+ printf("/dev/%s\n", a[2])
+ }
+ }'
+}
+
+# parse policy output for each device
+# takes 'multipath -l' output as input
+mp_parse_policy() {
+ local info="$1"
+
+ # multipath-tools-0.4.8-0.12.amd64
+ # LUN-02 (36006016002c11800ce520d27c6ebda11) dm-0 DGC ,RAID 10
+ # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
+ # \_ round-robin 0 [prio=0][active]
+ # \_ 0:0:0:0 sda 8:0 [active][undef]
+ # \_ round-robin 0 [prio=0][enabled]
+ # \_ 0:0:1:0 sdf 8:80 [active][undef]
+ #
+ # multipath-tools-0.4.8-9.x86_64
+ # LUN-14 (36006016002c118006f4f8bccc7fada11) dm-3 ,
+ # size=7.0G features='0' hwhandler='0' wp=rw
+ # |-+- policy='round-robin 0' prio=-1 status=enabled
+ # | `- #:#:#:# sde 8:64 failed undef running
+ # `-+- policy='round-robin 0' prio=-1 status=active
+ # `- #:#:#:# sdb 8:16 active undef running
+
+ echo "$info" | awk '
+ # multipath-tools-0.4.8-0.12.amd64
+ /\[prio=/{
+ print $2
+ }
+ # multipath-tools-0.4.8-9.x86_64
+ /policy=/{
+ if (match($0, /policy=[^ ]+/)) {
+ # take whole matched part into "l" variable
+ l = substr($0, RSTART, RLENGTH);
+ # remove policy= and single quote,
+ # which we can not use in this awk inline script, therefore the %c hack
+ sub(sprintf("^policy=%c?", 39), "", l);
+ print l
+ }
+ }
+ ' | sort -u
+}
+
+# parse hwhandler from multipath output
+# takes 'multipath -l' output as input
+mp_parse_hwhandler() {
+ local info="$1"
+
+ # TODO: actually the dm-emc vs scsi-dh-emc is dependant on kernel version
+ # not version of the tools installed
+
+ # multipath-tools-0.4.8-0.12.amd64
+ # [size=12G][features=1 queue_if_no_path][hwhandler=1 emc]
+ #
+ # multipath-tools-0.4.8-11.x86_64
+ # size=7.0G features='0' hwhandler='0' wp=rw
+ # size=2.0G features='1 queue_if_no_path' hwhandler='1 emc' wp=rw
+ echo "$info" | sed -ne "
+ # multipath-tools-0.4.8-0.12.amd64
+ /\[hwhandler=1/{
+ s,^.*\[hwhandler=1 \([^]]*\)\].*$,dm-\1,
+ p
+ }
+ # multipath-tools-0.4.8-11.x86_64
+ /hwhandler='1/{
+ s,^.*hwhandler='1 \([^']*\)'.*$,scsi-dh-\1,
+ p
+ }
+ " | sort -u
+}