#!/bin/bash
#
# sm-multipath	 Support function for multipath in SM
#
# chkconfig: 2345 16 77
# description: Create proper symlinks in /dev/ if root is multipathed

### BEGIN INIT INFO
# Provides: sm-multipath
# Required-Start:
# Required-Stop:
# Default-Start:
# Default-Stop:
# Short-Description: Support function for multipath in SM
# Description: Create proper symlinks in /dev/ if
#         root is multipathed
### END INIT INFO

DAEMON=/usr/sbin/multipathd
MP_UTIL=/usr/sbin/mpathconf
prog=sm-multipath
initdir=/etc/rc.d/init.d

. $initdir/functions

RETVAL=0

#
# See how we were called.
#

#
# This block of functions is taken from dracut
#
find_block_device() {
    local rootdev blkdev fs type opts misc
    while read blkdev fs type opts misc; do
        [[ $blkdev = rootfs ]] && continue # skip rootfs entry
        [[ $fs = $1 ]] && { rootdev=$blkdev; break; } # we have a winner!
    done < /proc/mounts
    [[ -b $rootdev ]] || return 1 # oops, not a block device.
    # get major/minor for the device
    ls -nLl "$rootdev" | \
        (read x x x x maj min x; maj=${maj//,/}; echo $maj:$min)
}

find_root_block_device() { find_block_device /; }

find_root_wwid() {
    local rootdev blkdev fs type opts misc
    while read blkdev fs type opts misc; do
        [[ $blkdev = rootfs ]] && continue # skip rootfs entry
        [[ $fs = '/' ]] && { rootdev=$blkdev; break; } # we have a winner!
    done < /proc/mounts
    [[ -b $rootdev ]] || return 1 # oops, not a block device.
    /usr/lib/udev/scsi_id -g $rootdev
}

is_mpath() {
    [ -e /sys/dev/block/$1/dm/uuid ] || return 1
    # we modified the matching pattern: ^mpath did not work
    [[ $(cat /sys/dev/block/$1/dm/uuid) =~ mpath- ]] && return 0
    return 1
}

#
# End of block


start() {
	# We want to be sure multipathd is running with modules
	$MP_UTIL --enable --with_module y
	echo -n $"Multipath check for root device: "
	success

	# Create an mpInuse symlink for the root device if that is multipath.
	ROOT_PART=$(find_root_block_device)
	if is_mpath $ROOT_PART; then
		ROOT_PART_MINOR=${ROOT_PART#[[:digit:]]*:}
		ROOT_PART_SLAVE=$(/bin/ls /sys/block/dm-$ROOT_PART_MINOR/slaves)
		ROOT_DISK_MINOR=${ROOT_PART_SLAVE#dm-}
		MPATH_NODES="$(dmsetup ls --target multipath --exec ls)"
		for n in $MPATH_NODES ; do
			# stat %T returns value in hex, convert to decimal before comparing
			NODE_MINOR="$((0x$(stat -L --format=%T $n)))"
			if [ "$ROOT_DISK_MINOR" = "$NODE_MINOR" ] ; then
				mkdir -p /dev/disk/mpInuse
				ln -sf $n /dev/disk/mpInuse
			fi
		done
	fi

	echo
}

generate-bfs() {

	# We want to be sure multipathd is running with modules
	$MP_UTIL --enable --with_module y

	echo -n $"generate-bfs"

	# Ensure its wwid is not blacklisted
	WWID=$(find_root_wwid)
	/usr/sbin/multipath -a $WWID

	mkdir -p /dev/disk/mpInuse
	ln -sf $WWID /dev/disk/mpInuse

	# Block to handle FCoE
	if [ -n "$1" -a "$1" = "fcoe" ]; then
		cat <<EndOfBlock >> /etc/multipath.conf
# Added during installation for FCoE
multipaths {
	multipath {
		wwid "${WWID}"
		no_path_retry "queue"
	}
}
EndOfBlock
	fi
	# End FCoE block

	echo
	success
}

stop() {
	echo -n $"Stopping $prog daemon: "
	success
	echo
}

restart() {
	stop
	start
}

case "$1" in
start)
	start
	;;
stop)
	stop
	;;
restart)
	restart
	;;
generate-bfs)
	generate-bfs
	;;
generate-fcoe)
	generate-bfs fcoe
	;;
*)
	echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}"
	RETVAL=2
esac

exit $RETVAL
