#!/bin/bash
#
# Copyright (C) Citrix Systems Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; version 2.1 only.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
#
# Ensures the correct symlinks are present in /dev if rood device
# is multipathed
set -e
MP_UTIL=/usr/sbin/mpathconf

#
# 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

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

# 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
exit 0
