#!/usr/bin/ksh -p
#*******************************************************************************
#  Copyright 1999 LSI Logic Inc.  All Rights reserved.                         *
#*******************************************************************************

#*******************************************************************************
#
# NAME:		set_drivers
# VERSION:	1
# UPDATE DATE:	%date_modified: Mon Aug 20 14:24:02 2001 %
# INSPECTED ON:
#
# CONTACTS:
#   Originator: jbeadles
#   Owner: jbeadles
#   Backup: awilner
#   Updater:	%created_by:    awilner %
#
# DESCRIPTION:
#   See help function below.
#
# NOTES:
#
#
# REFERENCE:
# 1.  Source Code Integrity Measures
#
#
# CODING STANDARD WAIVERS:
#
#
#*******************************************************************************

#*******************************************************************************
# PROCEDURE:
#	help
#
# DESCRIPTION:
#	The help function displays a "manual page" for the set_drivers script.
#
# SYNTAX:
#   help
#
# NOTES:
#	None.
#
# RETURNS:
#	Nothing.
#

help()
{
    cat <<!
SET_DRIVERS

NAME
    set_drivers - set drivers

SYNOPSIS
    set_drivers [ -i inject_list ] [-x]
    set_drivers [-h]

DESCRIPTION
    Set_drivers is a script that checks the device nodes associated with
    the devices in the module name file (mnf) to determine which native
    driver controls them. It builds a list of the native drivers that are
    in use. It edits the rmparams file to set the appropriate value in the
    Rdac_NativeScsiDrivers parameter. Finally, it edits the /etc/system
    file to cause the appropriate drivers to be loaded.

    If the -h option is specified, rmparmsutil prints this manual page,
    and takes no further action.

    If the -i parameter is specified, specific types of nodes are injected
    for debugging purposes. If the inject list contains "sd" or "ssd",
    entries of that type are injected.

    If the -x option is specfied, the script is run with the -x option
    set, causing every line that is executed to be listed on the
    standard error.

FILES
    mnf           Module name file
    rmparams      Raid manager parameters file
    /etc/system   System specification file

SEE ALSO
    rmparams, system.
!
}

#*******************************************************************************
# PROCEDURE:
#	inject_entries
#
# DESCRIPTION:
#	The inject_entries function is used for debugging purposes only.
#	Depending on the selected options, it causes the system to appear to
#	have only sd devices, only ssd devices, or a mixture of both.
#
# SYNTAX:
#	inject_entries file
#
# NOTES:
#	None.
#
# RETURNS:
#	Nothing.
#

inject_entries()
{
	if [ "$x" -eq 1 ]
	then
		set -x
	fi

	tmp1=$1

	echo >$tmp1

	for driver in $inject_list
	do
		case "$driver" in
		sd)
			echo "lrwxrwxrwx   1 jon      other         58 Apr 16 15:15 c1t1d0s7 -> ../../devices/io-unit@f,e0200000/sbi@0,0/fcaw@2,0/sd@1,0:h" >>$tmp1
			;;
		ssd)
			echo "lrwxrwxrwx   1 jon      other         58 Apr 16 15:15 c1t1d0s7 -> ../../devices/io-unit@f,e0200000/sbi@0,0/fcaw@2,0/ssd@1,0:h" >>$tmp1
			;;
		*)
			# not debugging - do nothing
			;;
		esac
	done
}

#*******************************************************************************
# PROCEDURE:
#	main
#
# DESCRIPTION:
#	The main procedure scans the syntax and controls the overall
#	operation of the set_drivers script.
#
# SYNTAX:
#	set_drivers [ -i inject_list ] [-x]
#	set_drivers [-h]
#
# NOTES:
#	For more details, see the help function above.
#
# RETURNS:
#	0 - good
#	1 - syntax error
#	2 - found no nodes controlled by known native drivers
#

# main

debug=0

status=0
i=0
h=0
x=0
inject_list=""

for parameter in $*
do
    letter=`echo x$parameter | cut -c2`
    if [ "$letter" = "-" ]
    then
        parameter=`echo x$parameter | cut -c3-`
        while [ "$parameter" != "" ]
        do
            letter=`echo "x$parameter" | cut -c2`
            parameter=`echo "x$parameter" | cut -c3-`

            case "$letter" in
            i)
                i=1
				previous=-i
				if [ "$parameter" != "" ]
				then
					if [ "$parameter" = "sd" -o "$parameter" = "ssd" ]
					then
						inject_list=$parameter
					else
						echo "invalid driver $parameter"
						echo
						status=1
					fi
					parameter=""
				fi
				;;
			h)
				h=1
				previous=-h
				;;
			x)
				x=1
				previous=-x
				;;
            *)
                echo "invalid option -$letter"
                echo
                status=1
                ;;
            esac
        done
    else
        case "$previous" in
		-i)
			inject_list="$inject_list $parameter"
			;;
        *)
            echo "invalid parameter $parameter"
            echo
            status=1
            previous=""
            ;;
        esac
    fi
done

if [ "$i" -eq 1 -a "$inject_list" = "" ]
then
	echo "no inject_list specified"
	echo
	status=1
fi

if [ "$status" -ne 0 ]
then
	help
	exit 1
fi

if [ "$h" -eq 1 ]
then
	help
	exit 0
fi

if [ "$x" -eq 1 ]
then
	set -x
fi

if [ "$debug" -eq 1 ]
then
	echo "h = $h"
	echo "i = $i"
	echo "x = $x"
	echo "inject_list = $inject_list"
	exit 0
fi

ls_all_cxtx()
{
	if [ "$x" -eq 1 ]
	then
		set -x
	fi

	cxtx_list=$*

	for cxtx in $cxtx_list
	do
		for path in /dev/dsk /dev/rdsk /dev/${pkg_name}/dev/dsk /dev/${pkg_name}/dev/rdsk
		do
			ls -l ${path}/${cxtx}* 2>/dev/null
		done
	done
}
	
tmp1=/tmp/set_drivers.1.$$
tmp2=/tmp/set_drivers.2.$$

trap 'rm -f $tmp1 $tmp2; exit 0' 0 1 2 3 14 15

if [ -d /dev/osa ]
then
	pkg_name=osa
else
	pkg_name=symsm
fi

sd_total=0
ssd_total=0

cat /etc/${pkg_name}/mnf |
while read line
do
	A_controller=`echo "$line" | cut -d"~" -f9`
	B_controller=`echo "$line" | cut -d"~" -f10`

	ls_all_cxtx $A_controller $B_controller >$tmp1

	if [ "$i" -eq 1 ]
	then
		# we are debugging
		inject_entries $tmp1
	fi

	sd_count=`egrep -c "/sd@" $tmp1`
	ssd_count=`egrep -c "/ssd@" $tmp1`

	sd_total=`expr $sd_total + $sd_count`
	ssd_total=`expr $ssd_total + $ssd_count`

	if [ "$sd_total" -ne 0 -a "$ssd_total" -ne 0 ]
	then
		break
	fi
done

if [ "$sd_total" -ne 0 -o "$ssd_total" -ne 0 ]
then
	# Figure out native_drivers string
	native_drivers=""

	if [ "$sd_total" -ne 0 ]
	then
		native_drivers="sd:"
	fi

	if [ "$ssd_total" -ne 0 ]
	then
		native_drivers="${native_drivers}ssd:"
	fi

	# Take sd and ssd out of the rmparams file
	sed -e "/Rdac_NativeScsiDrivers:/s/:sd:/:/" -e "/Rdac_NativeScsiDrivers:/s/:ssd:/:/" </etc/${pkg_name}/rmparams >$tmp1

	# Put the appropriate drivers in the rmparams file
	sed -e "/Rdac_NativeScsiDrivers:/s/:/:${native_drivers}/" <$tmp1 >$tmp2

	mv $tmp2 /etc/${pkg_name}/rmparams
	chmod 644 /etc/${pkg_name}/rmparams
	chown root /etc/${pkg_name}/rmparams
	chgrp sys /etc/${pkg_name}/rmparams

	nawk -v sd_total=$sd_total -v ssd_total=$ssd_total </etc/system >$tmp1 '
	BEGIN {
		state = 0
	}
	{
		if ( state == 0 )
		{
			print
			if ( $0 == "* BEGIN RAID Manager addition" )
			{
				state = 1
			}
			next
		}
		if ( state == 1 )
		{
			print
			if ( $0 == "* DO NOT EDIT from BEGIN above to END below..." )
			{
				if ( sd_total != 0 )
				{
					printf "forceload: drv/sd\n"
				}
				if ( ssd_total != 0 )
				{
					printf "forceload: drv/ssd\n"
				}
				state = 2
			}
			next
		}
		if ( state == 2 )
		{
			if ( $0 == "forceload: drv/sd" )
			{
				next
			}
			if ( $0 == "forceload: drv/ssd" )
			{
				next
			}
			print
			if ( $0 == "* END RAID Manager addition" )
			{
				state = 3
			}
			next
		}
		if ( state == 3 )
		{
			print
			next
		}
	}
	'

	mv $tmp1 /etc/system
	chmod 644 /etc/system
	chown root /etc/system
	chgrp sys /etc/system

	status=0
else
	# Leave the rmparams file and the /etc/system file alone

	echo "WARNING: set_drivers: No arrays were found that are controlled by either the sd or the ssd driver" 1>&2

	status=2
fi

exit $status
