#!/bin/sh
#
# description: Loads and configures the EMC PowerPath drivers.
#
# ###################################################################
# Copyright (c) 2000, EMC Corporation. All Rights Reserved.
#
# Most Recent Author: Raghu Adabala
# Previous Authors: Raghu Adabala and Ed Goggin
#
# Contents:
# Loads and configures the EMC PowerPath drivers.
# ###################################################################
#

# @(#) $Header: /cvs/source/master/pxmobility/src/pkg/i386_linux/bin_install/.options/distribution/RedHat/PowerPath,v 1.30.2.3.2.9 2005/06/20 14:24:02 gswamy Exp $

#
# Source function library.
#

#. /etc/init.d/functions

MKNOD()
{
DEV=/dev

minor=0
major=8
for dev in a b c d e f g h i j k l m n o p 
do
	mknod ${DEV}/sd$dev b $major $minor 2>/dev/null
	minor=`expr $minor + 16`
done

major=65
minor=0
for dev in q r s t u v w x y z aa ab ac ad ae af
do
	mknod ${DEV}/sd$dev b $major $minor 2>/dev/null
	minor=`expr $minor + 16`
done

major=66
minor=0
for dev in ag ah ai aj ak al am an ao ap aq ar as at au av
do
	mknod ${DEV}/sd$dev b $major $minor 2>/dev/null
	minor=`expr $minor + 16`
done

major=67
minor=0
for dev in aw ax ay az ba bb bc bd be bf bg bh bi bj bk bl
do
	mknod ${DEV}/sd$dev b $major $minor 2>/dev/null
	minor=`expr $minor + 16`
done

major=68
minor=0
for dev in bm bn bo bp bq br bs bt bu bv bw bx by bz ca cb 
do
	mknod ${DEV}/sd$dev b $major $minor 2>/dev/null
	minor=`expr $minor + 16`
done

major=69
minor=0
for dev in cc cd ce cf cg ch ci cj ck cl cm cn co cp cq cr
do
	mknod ${DEV}/sd$dev b $major $minor 2>/dev/null
	minor=`expr $minor + 16`
done

major=70
minor=0
for dev in cs ct cu cv cw cx cy cz da db dc dd de df dg dh 
do
	mknod ${DEV}/sd$dev b $major $minor 2>/dev/null
	minor=`expr $minor + 16`
done

major=71
minor=0
for dev in di dj dk dl dm dn do dp dq dr ds dt du dv dw dx
do
	mknod ${DEV}/sd$dev b $major $minor 2>/dev/null
	minor=`expr $minor + 16`
done
}

pp_stop_lvm()
{
    if test -d /etc/lvmtab.d -a -x /sbin/vgchange ; then
        open_vol=""
        vgname=`/sbin/vgdisplay | grep "VG Name" | sed -e 's/VG Name/ /g'`
        for i in $vgname
        do
                #echo "Physical volumes in $i"
                pv=`/sbin/vgdisplay -v $i | grep "PV Name"  | awk '{ print $4 }'`
                err_stop=`/sbin/vgchange -a n $i  2>&1 | grep "open logical volume"`
                if [ "$err_stop" != "" ]; then
                    if [ "$open_vol" = "" ]; then
                        echo "Following LVM volume groups are in use:"
                        open_vol=$err_stop
                    fi
                    echo "      Volume Group: $i (`echo $pv`)"
                fi
        done
        if [ "$open_vol" != "" ]; then
            echo "If any of these open logical volume devices use LUNs from Powerpath managed devices,"
            echo "please re-issue the command after closing these volumes."
        fi
        if test -s /etc/pvpath.cfg -a -x /sbin/pvpathrestore; then
                /sbin/pvpathrestore > /dev/null 2>&1
        fi
    fi
}

pp_start_lvm()
{
   if test -x /sbin/vgchange -a -x /sbin/vgscan ; then
      ##echo "Scanning for LVM devices to start ..."
      /sbin/vgscan > /dev/null 2>&1
      /sbin/vgchange -a y > /dev/null 2>&1
   fi
}

restart_navi()
{
    #
    ## Restart naviagent if we stopped it earlier
    #
    if [ $1 = TRUE ]; then
        $2 start > /dev/null 2>&1
        ps -C naviagent > /dev/null 2>&1
        if [ $? -eq 1 ]; then
                echo "Unable to restart naviagent.  Please restart it manually."
        fi
    fi
}

remove_hba_dependencies()
{
    found=`grep "power_path" /etc/modules.conf`
    if [ ! "$found" = "" ]; then
        /bin/sed -e '/add below emcp .*/d' /etc/modules.conf > /etc/opt/emcpower/.modules.conf.tmp
        mv /etc/modules.conf /etc/opt/emcpower/.modules.conf.orig
        mv /etc/opt/emcpower/.modules.conf.tmp /etc/modules.conf
        # Re-calculate the kernel module dependencies.
        depmod -aq
    fi
}

do_success()
{
#
# If DEVFS is configured on this host to manage
# the /dev directory, then when the devfs file
# system is mounted on /dev the emcpower
# device is covered and cannot be seen.  We
# need to create this device in this virtual
# file system on every reboot in this case.
#
#    if [ ! -e /dev/emcpower ]; then
#        mknod /dev/emcpower c 233 255
#        #
#        # Create sd dev files in /dev if they do
#        # not already exist since PowerPath is not
#        # integrated with DEVFS.
#        #
#        MKNOD
#    fi

    linux249=`uname -r | grep "2.4.9"`
    if [ "$linux249" != "" ]
    then
        varyiosym=`/sbin/ksyms -a|grep blkdev_varyio|awk '{print $1}'`
        /sbin/powermt varyio $varyiosym
    fi

    if [ -f /etc/emcp_devicesDB.dat ]; then 
        if [ -f /etc/emcp_devicesDB.idx ]; then
               /etc/opt/emcpower/emcpmgr map -p > /dev/null 2>&1
        fi
    fi


    /sbin/powermt config > /dev/null 2>&1
    /sbin/powermt load > /dev/null 2>&1
    /etc/opt/emcpower/emcpmgr map > /dev/null 2>&1
    /etc/opt/emcpower/powercf -C > /dev/null 2>&1
    # /sbin/powermt save > /dev/null 2>&1

    retval=0
}

retval=1
script_name=PowerPath

case "$1" in
    start)

    echo "Starting $script_name: "
    linux2421=`uname -r | grep "2.4.21"`
    DEVLABELDONE=TRUE
    if [ "$linux2421" != "" ]
    then
        #Avoid race conditions with devlabel on RHEL 30
        #OPT#: 167305
        DEVLABELDONE=FALSE
        for i in 1 2 3 4 5 6 7 8 9 10 11 12
        do
                devlabel=`/bin/ps -ef|grep devlabel|grep -v grep`
                scsi_unique_id=`/bin/ps -ef|grep scsi_unique_id|grep -v grep`
                hotplug=`/bin/ps -ef|grep /etc/hotplug|grep -v grep`
                sfdisk=`/bin/ps -ef|grep sfdisk|grep -v grep`
                DEVLABELDONE=TRUE

                if [ "$devlabel" != "" -o "$scsi_unique_id" != "" -o "$hotplug" != "" -o "$sfdisk" != "" ]
                then
                        sleep 5
                        DEVLABELDONE=FALSE
                fi

                if [ $DEVLABELDONE = "TRUE" ]
                then
                       break;
                fi
        done
    fi

    if [ $DEVLABELDONE = "FALSE" ]
    then
                echo "Please run '/etc/init.d/PowerPath start' manually."
                exit 1
    fi

    #
    # Release LVM claim to existing devices.
    #
    pp_stop_lvm

    # Introduced the line below to fix OPT 205739
    mknod /dev/emcpower c 233 255 >/dev/null 2>&1
    #
    # Load the filter first
    #
    /sbin/modprobe -q -s -a ppfilter > /dev/null 2>&1
    if [ ! $? -eq 0 ]; then
        insmod_opt=""
        lver=`uname -r | grep "2.4.21"`
        if [ "$lver" != "" ]; then
           # -N introduced in 2.4.21
           insmod_opt=-N
        else
           insmod_opt=-f
        fi

        if [ -e /lib/modules/`uname -r`/kernel/drivers/addon/emcpower ]; then
            emcpowerd=/lib/modules/`uname -r`/kernel/drivers/addon/emcpower
        else
            emcpowerd=/lib/modules/`uname -r`/kernel/drivers/scsi
        fi
        modulefile=/etc/modules.conf
        options=`sed -n -e "s/options[  ][  ]*emcpsf[     ][  ]*//p" $modulefile 2>/dev/null`

        /sbin/insmod --quiet ${insmod_opt} ${emcpowerd}/emcpsf.o $options > /dev/null 2>&1
        if [ ! $? -eq 0 ]; then
            echo "Can't load emcpsf"
        else
            if [ "`grep scsi_ppfilteradapter /etc/modules.conf`" != "" ]; then
                /sbin/modprobe -q -s -a scsi_ppfilteradapter 2>&1
            fi
        fi
    else
        if [ "`grep scsi_ppfilteradapter /etc/modules.conf`" != "" ]; then
            /sbin/modprobe -q -s -a scsi_ppfilteradapter 2>&1
        fi
    fi

    #    
    # Try modprobe, if that fails, use insmod to force load modules
    # one by one in case customer has disabled the CONFIG_MODVERSIONS
    # linux kernel config directive and is trying to load the PowerPath
    # driver modules on an IBM summit kernel configuration.
    #
    /sbin/modprobe -q -s -a power_path > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        do_success
    else
        insmod_opt=""
        lver=`uname -r | grep "2.4.21"`
        if [ "$lver" != "" ]; then
           # -N introduced in 2.4.21
           insmod_opt=-N
	else
	   insmod_opt=-f
        fi

        if [ -e /lib/modules/`uname -r`/kernel/drivers/addon/emcpower ]; then
            emcpowerd=/lib/modules/`uname -r`/kernel/drivers/addon/emcpower
        else
            emcpowerd=/lib/modules/`uname -r`/kernel/drivers/scsi
        fi
        modulefile=/etc/modules.conf
        options=`sed -n -e "s/options[ 	][ 	]*emcp[ 	][ 	]*//p" $modulefile 2>/dev/null`

	awk '/^add below emcp/{print $4;exit}' $modulefile | xargs modprobe -q -s -a > /dev/null 2>&1

        /sbin/insmod --quiet ${insmod_opt} ${emcpowerd}/emcp.o $options > /dev/null 2>&1
        if [ $? -eq 0 ]; then
              options=`sed -n -e "s/options[ 	][ 	]*emcpmp[ 	][ 	]*//p" $modulefile 2>/dev/null`
              /sbin/insmod ${insmod_opt} ${emcpowerd}/emcpmp.o $options    > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                  options=`sed -n -e "s/options[ 	][ 	]*emcpmpc[	][ 	]*//p" $modulefile 2>/dev/null`
                  /sbin/insmod ${insmod_opt} ${emcpowerd}/emcpmpc.o $options > /dev/null 2>&1
                if [ $? -eq 0 ]; then
                      options=`sed -n -e "s/options[ 	][ 	]*emcpmpaa[	][ 	]*//p" $modulefile 2>/dev/null`
                      /sbin/insmod ${insmod_opt} ${emcpowerd}/emcpmpaa.o $options > /dev/null 2>&1
                    if [ $? -eq 0 ]; then
                          options=`sed -n -e "s/options[ 	][ 	]*emcpmpap[	][ 	]*//p" $modulefile 2>/dev/null`
                          /sbin/insmod ${insmod_opt} ${emcpowerd}/emcpmpap.o $options > /dev/null 2>&1
                        if [ $? -eq 0 ]; then
                              options=`sed -n -e "s/options[ 	][ 	]*emcphr[	][ 	]*//p" $modulefile 2>/dev/null`
                              /sbin/insmod ${insmod_opt} ${emcpowerd}/emcphr.o $options > /dev/null 2>&1
                           if [ $? -eq 0 ]; then
                               /sbin/insmod ${insmod_opt} ${emcpowerd}/emcpioc.o > /dev/null 2>&1
                              if [ $? -eq 0 ]; then
                                  rmmod emcpioc
                                  do_success
                              fi
                          fi
                       fi
                    fi
                fi
            fi
        fi
    fi

    # The only way the retval will be 1 is if one of the modules failed to load.
    # If any of the modules failed to load then we will unload all PP modules.
    if [ "$retval" = 1 ]; then
        echo "Unable to load the PowerPath modules."
        /sbin/modprobe -r power_path > /dev/null 2>&1
        /sbin/rmmod emcpsf > /dev/null 2>&1
    fi

    #
    # Reactivate unused (unmounted) volume groups.
    #

    pp_start_lvm

    #
    # Check return value to see if the start failed.
    #
    if [ "$retval" = 1 ]; then
        echo "$script_name start failed."
    fi
    ;;

    stop)
        echo "Stopping $script_name: "
	navi_running=FALSE
	naviloc=/etc/init.d/naviagent
        ps -C powermt >> /dev/null 2>&1
        if [ $? -eq 0 ]; then
            echo "The powermt command is running."
            echo "Please stop powermt and then re-issue $script_name stop."
        else  
    	    #
            ## Stop navigent if it is running 
            #
            ps -C naviagent > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                if [ -f $naviloc ]; then
                    $naviloc stop > /dev/null 2>&1
                    ps -C naviagent > /dev/null 2>&1
                    if [ $? -eq 1 ]; then
                        navi_running=TRUE
                    fi
                fi
            fi
            ps -C naviagent > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                echo "Navisphere agent is running."
                echo "Please stop the agent and then re-issue $script_name stop."
            else
                #
	        # Release LVM claim to existing devices.
	        #
	        pp_stop_lvm

                #
                # Remove HBA dependencies so we will not unload the HBA drivers.
                #
                remove_hba_dependencies

                /sbin/powermt save > /dev/null 2>&1
                /sbin/powermt remove dev=all > /dev/null 2>&1
                /sbin/modprobe -q -s -r power_path > /dev/null 2>&1
		#
		# If modprobe -r fails it returns 0; therefore,
		# check to see if the power_path modules are loaded 
		# with lsmod.
		#
		if [ "`/sbin/lsmod | grep emcp | grep -v emcpsf`" = "" ]; then 
		    #
		    # Now try to unload the filter driver
		    #
                    /sbin/modprobe -q -s -r emcpsf > /dev/null 2>&1
                    if [ "`/sbin/lsmod | grep emcpsf`" = "" ]; then
                        retval=0;
                    else
                        /sbin/rmmod emcpsf > /dev/null 2>&1
                        if [ $? -eq 0 ]; then
                            retval=0;
			else
			     #
			     # Unable to load the filter friver
			     #
	 		    echo "Failed to unload the emcpsf modules."
                        fi
                    fi
                else
		    #
		    # If powermt display is unable to check the devices it will 
		    # return -1. If it returns 0; check to see if it displayed 
	 	    # any devices.
		    #
		    /sbin/powermt display dev=all > /dev/null 2>&1
                    if [ $? -eq 0 ]; then
		        if [ "`powermt display dev=all 2>&1 | grep "not found"`" = "" ]; then
                            echo "PowerPath devices are open."
                            echo "Please close these devices and then re-issue $script_name stop."
                        else
	                    echo "Failed to unload the PowerPath modules." 
			fi
		    else
			echo "Failed to unload the PowerPath modules."
                    fi
                fi

                #
                # Restore HBA dependencies
                #
                mv /etc/opt/emcpower/.modules.conf.orig /etc/modules.conf
                depmod -aq

            fi
	    # Introduced the line below to fix OPT 205739
        if [ "`/sbin/lsmod | grep emcp`" = "" ]; then
    	    rm -f /dev/emcpower >/dev/null 2>&1
        fi
    	    #
      	    ## Restart naviagent if we stopped it earlier
    	    #
    	    if [ $navi_running = TRUE ]; then
                $naviloc start > /dev/null 2>&1
                ps -C naviagent > /dev/null 2>&1
                if [ $? -eq 1 ]; then
                    echo "Unable to restart naviagent.  Please restart it manually."
                fi
            fi
        fi	

	#
	# Reactivate unused (unmounted) volume groups.
	#
        pp_start_lvm

	#
	# Check return value to see if the stop failed.
	#
	if [ "$retval" = 1 ]; then
	    echo "$script_name stop failed."
	fi
    ;;
    *)
    echo "Usage: $0 {start|stop}"
    ;;
esac

exit $retval
