#!/bin/sh
#*******************************************************************************
#
# NAME:		rdacctrl
# SUMMARY:	%description%
# COMPONENT:	solsysd
# VERSION:	43
# UPDATE DATE:	%date_modified: Tue Jan 09 10:51:41 2001 %
# PROGRAMMER:	%created_by:    bmyers %
# 
#		Copyright 1996, 1997, 1998 by Symbios Logic Inc.
#
# DESCRIPTION:
# This script performs RDAC initialization and shutdown, depending on the
# arguments ("start" or "stop").  Initializing includes automatically generating
# the necessary driver ".conf" files, loading the RDAC driver, and starting
# the RDAC daemons.  Shutdown includes stopping the RDAC daemons.
#
# NOTES:
#
# REFERENCE:
# 1.  PRD0001A.DOC, Notes on Portable RDAC Prototype
# 2.  PRD0002A.DOC, RDAC Driver-Resolution-Daemon I/O Control Message-ing
#     Interface
# 3.  PRD0003A.DOC, Notes on Portable RDAC Resolution Daemon
# 4.  PRD0004A.DOC, Productization of RDAC Prototype
# 5.  PRD0006A.DOC, Feature Enhancement:  Solaris RDAC Root/Boot
# 6.  PRD0007A.DOC, Implementation of Standard Device Name Support in Solaris
#     RDAC
#
# CODING STANDARD WAIVERS:
#
#*******************************************************************************


#*******************************************************************************
# PROCEDURE:	GenRdriverConf	
# SUMMARY:	Generate the "rdriver.conf" file
#
# DESCRIPTION:
# GenRdriverConf calls symconf to generate the rdriver.conf file.  In
# addition, it has certain special provisions:  (1) it tries to cope with the
# fact that the Solaris bus numbering skips over busses that have no targets
# on them - it does this via an intermediate stage where it generates all
# LUNs for both controllers regardless of LUN ownership, then runs "disks",
# forcing Solaris to see the bus and number it then regenerates rdriver.conf
# with the true configuration, and the next time disks is run, the non-exist-
# ent nodes go away and the nodes that are left have the right names.  (2) The
# other special provision of this routine is to revert to installing rdriver
# as a pseudo driver for the case where there are no arrays on the system.
# (If this is not done, unexpected results occur on boot -r with no arrays
# attached.)
#
# SYNTAX:
# GenRdriverConf <mode>
# <mode> - if set to VERBOSE, display regenerating message, otherwise work
#          silently
#
# NOTES:
# ROOT is an environment variable defined for testing purposes - it should
# normally be set to NULL.
#
# RETURNS:
# Nothing
#
GenRdriverConf()
{
	if [ "$1" = "VERBOSE" ]
	then
		echo "Re-generating rdriver.conf file ..."
	fi
	
	
	if [ -z "`modinfo | grep rdriver`" ]
	then
		cd /kernel/drv
		modload rdriver
	fi
	MODNUM=`modinfo | grep rdriver | cut -c1-3`
	$RM_BOOT_HOME/symconf >/kernel/drv/rdriver.conf 2> /dev/null
	SYMCONF_STATUS=$?

	if [ -n "$HAS_SPARCV9" ]
	then
		cp  /kernel/drv/rdriver.conf /kernel/drv/sparcv9/rdriver.conf
	fi

	

	if [ "$SYMCONF_STATUS" != 0 ]
	then
		$LOGGER -p user.err "Warning: rdriver.conf re-generation failed"
	fi
	
	if [ -s /kernel/drv/rdriver.conf  ]
	then
		chmod 644 /kernel/drv/rdriver.conf
		chown root /kernel/drv/rdriver.conf
		chgrp sys  /kernel/drv/rdriver.conf
	fi

	if [ -n "$HAS_SPARCV9" -a -s /tmp/rdriver64.conf ]
	then

		chmod 644 /kernel/drv/sparcv9/rdriver.conf
		chown root /kernel/drv/sparcv9/rdriver.conf
		chgrp sys  /kernel/drv/sparcv9/rdriver.conf
	fi
}

#*******************************************************************************
# PROCEDURE:	MakeRmdevroot	
# SUMMARY:	Create the private device directory for SYMplicity storage
#		manager
#
# DESCRIPTION:
# MakeRmdevroot creates a dev directory for the private use of SYMplicity
# storage manager.
#
# SYNTAX:
# MakeRmdevroot
#
# NOTES:
#
# RETURNS:
# Nothing
#
MakeRmdevroot()
{
	echo "Setting up RAID device access ..."
	mkdir $RMDEVROOT > /dev/null 2>&1
	chmod 775 $RMDEVROOT
	chgrp sys $RMDEVROOT
	ln -s /devices $RMDEVROOT/devices >/dev/null 2>&1
	find /dev/rdsk /dev/dsk -print | cpio -pdum $RMDEVROOT >/dev/null 2>&1;
}

#*******************************************************************************
# PROCEDURE:	rdacctrl (main)
# SUMMARY:	Control RDAC startup/shutdown operations
#
# DESCRIPTION:
# rdacctrl conforms to the standard rc script "start/stop" interface.  The
# "start" processing carries out the steps needed to initialize RDAC; the
# "stop processing carries out the steps needed to shut down RDAC.  rdacctrl
# handles two main situations in different ways:  (1) when RDAC is NOT the
# root device, and (2) when RDAC IS controlling the root device.  For the
# non-root case, RDAC reconfiguration occurs as part of "start" processing;
# for the root case, reconfiguration is done as part of "stop" processing, since
# since there is no opportunity in the root case to present a new configuration
# to the RDAC driver via reloading it during bootup.
#
# SYNTAX:
# rdacctrl <action>
# <action> = start | stop | config
# start -> initialize RDAC
# stop -> shutdonw RDAC
# config -> regenerate RDAC config files
#
# NOTES:
# There is also "vendor-unique" argument, "config" which can be used
# (e.g., "rdacctrl config") to regenerate the rdriver .conf file.
#
# RETURNS:
# Nothing


# R D A C C T R L   M A I N   P R O C E D U R E
#

rm -f /S55rdac.msg

if [ -f /var/adm/messages ]
then
	output_file=/var/adm/messages
else
	output_file=/tmp/S55rdac.msg
fi

(
PATH=/sbin:/usr/sbin:/bin:/usr/bin
WARNING="\nWARNING:  It is possible that VxVM is not bound to the RDAC device nodes.You\nneed to reboot or reset the configuration daemon (vxconfigd -k -r reset) to\nensure proper binding.\n"

RUNNING_DRVCONFIG_MSG="\nCreating /devices entries for the arrays - this is necessary in order to load\nRDAC early and may take up to a few minutes.\n"

RMPARAMS_FILE=/etc/raid/rmparams
LUNLOCKS=`grep -v "^#" $RMPARAMS_FILE | grep System_LunlocksDirPath | cut -d= -f2`
RM_BOOT_HOME=`grep -v "^#" $RMPARAMS_FILE | grep System_RmBootHomeDirectory | cut -d= -f2`
RDACCONFIG=$RM_BOOT_HOME/rdacconfig

RMDEVROOT=`grep -v "^#" $RMPARAMS_FILE | grep "System_AltDevDirRoot" | cut -d= -f2 | awk -F/ '{ ORS = "/"; for (i = NF; i > 1; --i) print $i; ORS = "\n"; print $1 }' | cut -d"/" -f3-32 |  awk -F/ '{ ORS = "/"; for (i = NF; i > 1; --i) print $i; ORS = "\n"; print $1 }'`

# safety catch - added because the devfsadm changes are causing this link to be deleted
ln -s /devices $RMDEVROOT/devices >/dev/null 2>&1

if grep -v "^#" $RMPARAMS_FILE | grep "Rdac_SupportDisabled.*=.*TRUE" >/dev/null 2>&1
then
	RDAC_DISABLED=TRUE
fi

if [ ! -d $RMDEVROOT/dev ]
then
	FRESH_INSTALL=TRUE
fi

#
# set up access to "logger" program
#
if [ -x "/usr/ucb/logger" ]
then
	LOGGER=/usr/ucb/logger
elif [ -x "/usr/bin/logger" ]
then
	LOGGER=/usr/bin/logger
else
	LOGGER=/bin/echo
fi

umask 0002
case $1 in


'start')

	# get rid of any lurking lun locks and semaphores
	rm $LUNLOCKS 2>/dev/null
	rm /etc/raid/locks/* 2>/dev/null
	rm /tmp/mutex.add_disk /tmp/mutex.hot_add /tmp/mutex.disksh 2>/dev/null

	if [ -n "${_INIT_RECONFIG}" ]
	then
		if [ -n "${FRESH_INSTALL}" ]
		then
			MakeRmdevroot
		fi
	fi

	if [ -x /usr/bin/isalist ]
	then
		HAS_SPARCV9=`/usr/bin/isalist | grep sparcv9`
	fi
	
	if [ -n "${RDAC_DISABLED}" ]
	then
		echo "RDAC support disabled"

		# make sure rdriver.conf attributes are as they should be
		chmod 644 /kernel/drv/rdriver.conf
		chown root /kernel/drv/rdriver.conf
		chgrp sys  /kernel/drv/rdriver.conf

		if [ -n "$HAS_SPARCV9" ]
		then
			# make sure 64 bit rdriver.conf attributes are as they should be
			chmod 644 /kernel/drv/sparcv9/rdriver.conf
			chown root /kernel/drv/sparcv9/rdriver.conf
			chgrp sys  /kernel/drv/sparcv9/rdriver.conf
		fi

		exit
	fi

	#
	# Proceeding with RDAC initialization
	#

	if [ -n "${_INIT_RECONFIG}" ]
	then
		# generate new rdriver.conf
		if  [ ! -c $RMDEVROOT/dev/rdsk/rdac ]
		then
			RDAC_MAJOR=`cat /etc/name_to_major | grep rdriver | cut -d" " -f2`
			mknod $RMDEVROOT/dev/rdsk/rdac c $RDAC_MAJOR 3327
		fi
		/etc/raid/bin/rdac_disks

		GenRdriverConf VERBOSE
		cat /kernel/drv/rdriver.conf | grep mname >/tmp/rdacctrl.$$

		cat /tmp/rdacctrl.$$ |
		while read MODULE_LUN_INFO
		do
			MODULE_NAME=`echo $MODULE_LUN_INFO | cut -d= -f7 | cut -d\" -f2`
			MODULE_NUMBER=`echo $MODULE_LUN_INFO | cut -d= -f3 | cut -d" " -f1`
			NEXUS_BUS=`echo $MODULE_LUN_INFO | cut -d= -f8 | cut -d" " -f1`
			TARGET=`echo $MODULE_LUN_INFO | cut -d= -f5 | cut -d" " -f1`
			LUN=`echo $MODULE_LUN_INFO | cut -d= -f4 | cut -d" " -f1`
			C_PATH=`echo $MODULE_LUN_INFO | cut -d= -f9 | cut -d" " -f1 | grep A`
			if [ -n "${C_PATH}"  ]
			then
				$RDACCONFIG $RMDEVROOT/dev/rdsk/rdac "$MODULE_NAME" $MODULE_NUMBER $NEXUS_BUS $TARGET $LUN 0 >/dev/null $2>$1
			else
				$RDACCONFIG $RMDEVROOT/dev/rdsk/rdac "$MODULE_NAME" $MODULE_NUMBER $NEXUS_BUS $TARGET $LUN 1  >/dev/null $2>$1
			fi
		done
		rm /tmp/rdacctrl.$$  2>/dev/null
		RDAC_LOADED=`modinfo | grep rdriver`
		if [ -n "${RDAC_LOADED}" ]
		then
			drvconfig -i rdriver
		fi
	fi

	
	VXCONFIGD_ALIVE=`ps -ef | grep vxconfigd 2>/dev/null | grep -v grep 2>/dev/null`
	if [ -n "${VXCONFIGD_ALIVE}" ]
	then
		VX_BOOTED=`vxdctl mode 2>/dev/null | grep booted`
		if [ -n "${VX_BOOTED}" -a \( -n "${FRESH_INSTALL}" -o -f /tmp/sdDeleted.$$ \) ]
		then
			echo $WARNING
			sleep 3
		fi
	fi

	# make sure rdriver.conf attributes are as they should be
	
	chmod 644 /kernel/drv/rdriver.conf
	chown root /kernel/drv/rdriver.conf
	chgrp sys  /kernel/drv/rdriver.conf

	if [ -n "$HAS_SPARCV9" ]
	then
		# make sure 64 bit rdriver.conf attributes are as they should be
		chmod 644 /kernel/drv/sparcv9/rdriver.conf
		chown root /kernel/drv/sparcv9/rdriver.conf
		chgrp sys  /kernel/drv/sparcv9/rdriver.conf
	fi
	;;


'stop')

	# nothing to do here, really
	;;


'config')

	if [ -n "${RDAC_DISABLED}" ]
	then
		echo "RDAC disabled - NOT configuring"
		exit
	fi
	if [ -n "${FRESH_INSTALL}" ]
	then
		MakeRmdevroot
	fi

	$RM_BOOT_HOME/hot_add
	;;

*)
        echo "usage: rdacctrl {start|stop|config}"
	;;
esac
) 2>&1 |
while read line
do
	echo "$line"

	string=`date '+%b %d %H:%M:%S'`" "`uname -n`
	echo "$string $line" >>$output_file
done
