#!/bin/ksh -p
#*******************************************************************************
#
# NAME:		hot_add
# SUMMARY:	%description%
# COMPONENT:	solsysd
# VERSION:	rm6_14
# UPDATE DATE:	%date_modified: Tue May 28 14:16:35 2002 %
# PROGRAMMER:	%created_by:    shankara %
# 
#		Copyright 1998, 1999 by LSI Logic Inc.
#
# DESCRIPTION:
# hot_add carries out those operations needed for SYMplicity storage manager
# to be able to see a new array module.  
#
# NOTES:
#
# REFERENCE:
#
# CODING STANDARD WAIVERS:
#
#*******************************************************************************


trap 'rm -f /tmp/mutex.hot_add /tmp/hot_add.$$ /tmp/logme.$$ /tmp/mnf* /tmp/ps_data exit 0' 0 1 2 3 14 15

#*******************************************************************************
# PROCEDURE:	MutexAcquire
# SUMMARY:	get exclusive ownership of mutex file
#
# DESCRIPTION:
# MutexAcquire will try repeatedly to acquire a "mutex file" - success means
# the thread has been admitted to a "critical region"
#
# SYNTAX:
# MutexAcquire <mutex file>
# <mutex file> - name of the mutex guarding the critical region
#
# NOTES:
# MutexAcquire and the program it calls, rm_mutex_acquire, rely on O_CREAT
# semantics
#
# RETURNS:
# Nothing

MutexAcquire()
{
	while true
	do
		$RM_HOME/bin/rm_mutex_acquire $1
		if [ $? = 0 ]
		then
			break;
		fi
		sleep 1
	done;
}

#*******************************************************************************
# PROCEDURE:	MutexRelease
# SUMMARY:	relenquish mutex file ownership
#
# DESCRIPTION:
# MutexRelease releases mutex file ownership, so another thread can enter the
# critical region
#
# SYNTAX:
# MutexRelease <mutex file>
# <mutex file> - name of the mutex guarding the critical region
#
# NOTES:
#
# RETURNS:
# Nothing

MutexRelease()
{
	/bin/rm $1;
}

#*******************************************************************************
# PROCEDURE:	Editmnf
# SUMMARY:	Remove old or duplicate mnf entries

Editmnf()
{

RMPARAMS_FILE=/etc/raid/rmparams
RM_BOOT_HOME=`grep -v "^#" $RMPARAMS_FILE | grep System_RmBootHomeDirectory | cut -d= -f2`
RM_NAME_FILE=`grep -v "^#" $RMPARAMS_FILE | grep System_NamefileDirPath | cut -d= -f2`
LAD=$RM_BOOT_HOME/lad

if [ ! -f $RM_NAME_FILE ]
then
	return
fi
cat $RM_NAME_FILE >/tmp/mnf.ori.$$ 2>/dev/null
if [ $? -ne 0 ]
then
	echo "Error while updating the Module Name file: Unable to read $RM_NAME_FILE or create /tmp/mnf.ori.$$"
	return
fi

rm $RM_NAME_FILE 1>/dev/null 2>/dev/null 
$LAD -y 1>/dev/null 2>/dev/null

if [ ! -f $RM_NAME_FILE ]
then
	> $RM_NAME_FILE
	return
fi

cat $RM_NAME_FILE >/tmp/mnf.current.$$ 2>/dev/null
if [ $? -ne 0 ]
then
	echo "Error while updating the Module Name file: Unable to read $RM_NAME_FILE or create /tmp/mnf.current.$$"
	return
fi

cat /tmp/mnf.ori.$$ |
while read ORI_MNF_ENTRY
do
	if [ $? -ne 0 ]
	then
		echo "Error while updating the Module Name file: Unable to read /tmp/mnf.ori.$$"
		return
	fi

	MODULE_NAME=`echo $ORI_MNF_ENTRY | cut -d~ -f1`

	CURRENT_MNF_ENTRY=`grep "^${MODULE_NAME}~" /tmp/mnf.current.$$`

	if  [ -n "${CURRENT_MNF_ENTRY}" ]
	then
		ORI_A_PATH=`echo $ORI_MNF_ENTRY | cut -d~ -f9`
		
		ORI_B_PATH=`echo $ORI_MNF_ENTRY | cut -d~ -f10`

		CURRENT_A_PATH=`echo $CURRENT_MNF_ENTRY | cut -d~ -f9`
		
		CURRENT_B_PATH=`echo $CURRENT_MNF_ENTRY | cut -d~ -f10`

		if [ -n "${CURRENT_A_PATH}" ] && [ -n "${CURRENT_B_PATH}" ]
		then
			echo $CURRENT_MNF_ENTRY >>/tmp/mnf.new.$$
			continue	
		fi

		if [ -n "${ORI_A_PATH}" ] && [ -n "${ORI_B_PATH}" ]
		then
			echo $ORI_MNF_ENTRY >>/tmp/mnf.new.$$
			continue	
		fi

		echo $CURRENT_MNF_ENTRY >>/tmp/mnf.new.$$
	fi
done
mv /tmp/mnf.new.$$ $RM_NAME_FILE 1>/dev/null 2>/dev/null
rm /tmp/mnf.ori.$$ /tmp/mnf.current.$$ 1>/dev/null 2>/dev/null

}

#*******************************************************************************
# PROCEDURE:	hot_add (main)
# SUMMARY:	Make RAID Modules visible
#
# DESCRIPTION:
# hot_add calls "drvconfig" for the Native SCSI drivers defined in rmparams.
# It generates a new rdriver.conf, uses rdacconfig to notify the RDAC driver of the
# new module(s). It then calls "rdac_disks" which is the RDAC replacement
# script for "disks".
#
# SYNTAX:
# hot_add
#
# NOTES:
#
# RETURNS:
# 0     - success
# non-0 - failure (currently not returned)


# H O T A D D   M A I N   P R O C E D U R E
#
RMPARAMS_FILE=/etc/raid/rmparams
RM_HOME=`grep -v "^#" $RMPARAMS_FILE | grep System_RmHomeDirectory | cut -d= -f2`
RM_BOOT_HOME=`grep -v "^#" $RMPARAMS_FILE | grep System_RmBootHomeDirectory | cut -d= -f2`
RM_NAME_FILE=`grep -v "^#" $RMPARAMS_FILE | grep System_NamefileDirPath | cut -d= -f2`
NATIVE_DRIVERS=`grep -v "^#" $RMPARAMS_FILE | grep Rdac_NativeScsiDrivers`

RDAC_DR_TO=`grep -v "^#" $RMPARAMS_FILE | grep "Rdac_DR_Timeout" | cut -d= -f2`
if [ -z "${RDAC_DR_TO}" ]
then
	RDAC_DR_TO=15
fi

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 }'`
RDACCONFIG=$RM_BOOT_HOME/rdacconfig

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

_INIT_RECONFIG=YES; export _INIT_RECONFIG

MutexAcquire /tmp/mutex.hot_add	# Begin critical region

OSrel=`grep VERSION /var/sadm/system/admin/INST_RELEASE | cut -d= -f2`
if [ $OSrel = "2.6" -o $OSrel = "2.5.1" ]
then
	# Drivers don't autoload on ancient OSes
	modload /kernel/drv/sd 2>/dev/null
	modload /kernel/drv/ssd 2>/dev/null
fi

if [ ! -f $RM_NAME_FILE ]
then
	> $RM_NAME_FILE
fi

for DRIVER in 2 3 4 5 6 7 8 9
do
	NATIVE=`echo $NATIVE_DRIVERS | cut -d: -f$DRIVER`
	if [ -z "${NATIVE}" ]
	then
		break
	fi

	if [ "${NATIVE}" = "ssd" ]
	then
		/etc/raid/bin/lad -y >/dev/null 2>/dev/null
		drvconfig -i $NATIVE
	else
		drvconfig -i $NATIVE
	fi
done

RDAC_LOADED=`modinfo | grep rdriver`
if [ -n "${RDAC_LOADED}" ] && [ -c $RMDEVROOT/dev/rdsk/rdac ]
then
	/etc/raid/bin/hide_sd off
fi

disks -r $RMDEVROOT

Editmnf

/etc/raid/bin/rdac_disks -r $RMDEVROOT

RDAC_LOADED=`modinfo | grep rdriver`
if [ -n "${RDAC_LOADED}" ] && [ -c $RMDEVROOT/dev/rdsk/rdac ]
then
	/etc/raid/bin/hide_sd on
fi

$RM_BOOT_HOME/symconf >/kernel/drv/rdriver.conf 
sc_err=$?
if [ $sc_err -ne 0 ]
then
	if [ $sc_err -eq 10 ]
	then
		echo "Array Hot Add warning: /kernel/drv/rdnexus.conf has run out of pseudo-busses."
		echo "Some disk array controllers may not be accessible."
		echo "View /tmp/symconf.err to see which entries are missing."
		# Now we gotta dump a warning to the rmlog, and possibly the system log.
		sys=`uname -n`
		datime=`date +%m/%e/%Y~%H:%M:%S`
		echo "${sys}~~Unknown~${datime}~90~Array Hot Add warning: /kernel/drv/rdnexus.conf has run out of pseudo-busses. Some disk array controllers may not be accessible. View the file /tmp/symconf.err to see which entries are missing.~0~FFFFFFFF~0~00000000~" >/tmp/logme.$$
		/etc/raid/bin/rmscript /tmp/logme.$$
		# .. and rmscript automatically deletes the file.
	else
		echo "Array Hot Add error: Unable to build the RDAC Driver rdriver.conf file"
		MutexRelease /tmp/mutex.hot_add	# End of critical region
		exit 1
	fi
fi

RDAC_LOADED=`modinfo | grep rdriver`
if [ -n "${RDAC_LOADED}" ] && [ -c $RMDEVROOT/dev/rdsk/rdac ]
then
	/etc/raid/bin/hide_sd off
fi

drvconfig -i rdriver 2>/dev/null

RDAC_LOADED=`modinfo | grep rdriver`
if [ -n "${RDAC_LOADED}" ] && [ -c $RMDEVROOT/dev/rdsk/rdac ]
then
	/etc/raid/bin/hide_sd on
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 [ -c $RMDEVROOT/dev/rdsk/rdac ]
then
	cat /kernel/drv/rdriver.conf | grep "mname" >/tmp/hot_add.$$

	# for each "specific" entry in rdriver.conf, call rdacconfig to ask rdriver
	# to match it to the underlying controllers. If this fails, it's because there
	# is no underlying device -- either the LUN's not configured, or the native
	# disk driver can't see that LUN. Gee, it would sure be nice if we could tell
	# those two cases apart...
	cat /tmp/hot_add.$$ |
	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
fi

RDAC_LOADED=`modinfo | grep rdriver`
if [ -n "${RDAC_LOADED}" ] && [ -c $RMDEVROOT/dev/rdsk/rdac ]
then
	/etc/raid/bin/hide_sd off
fi

drvconfig -i rdriver

RDAC_LOADED=`modinfo | grep rdriver`
if [ -n "${RDAC_LOADED}" ] && [ -c $RMDEVROOT/dev/rdsk/rdac ]
then
	/etc/raid/bin/hide_sd on
fi

# Check if there are any 'candidate' arrays that couldn't be bound
$RDACCONFIG $RMDEVROOT/dev/rdsk/rdac >/dev/null 2>&1
config_err=$?

# nonzero config_err indicates rdriver failed to attach to at least one array node,
# and it will need to be reloaded.
if [ $config_err -ne 0 ]
then
	echo "Array Hot Add warning: The array driver was unable to attach to one or more"
	echo "array devices, and needs to be re-loaded. This may require a system reboot."
	# Now we gotta dump a warning to the rmlog, and possibly the system log.
	sys=`uname -n`
	datime=`date +%m/%e/%Y~%H:%M:%S`
		echo "${sys}~~Unknown~${datime}~90~Array Hot Add warning: The array driver was unable to attach to one or more array devices, and needs to be re-loaded. This may require a system reboot.~0~FFFFFFFF~0~00000000~" >/tmp/logme.$$
		/etc/raid/bin/rmscript /tmp/logme.$$
		# .. and rmscript automatically deletes the file.
fi

##########################
# start the RDAC daemons #
##########################

if [ -z "${RDAC_DISABLED}" ] # if RDAC *not* disabled ...
then
	nbr_dmns=`/bin/ps -e | grep rdaemon | grep -v grep | wc -l`
	if [ $nbr_dmns -ne 2 ]
	then
		if [ $nbr_dmns -lt 2 ]
		then
			modnum=`modinfo | grep rdriver | cut -c1-3`
			majnum=`modinfo | grep rdriver | cut -c20-23`
			if [ -n "`isalist 2>/dev/null | grep sparcv9`" ]
			then
				priocntl -e -c RT $RM_BOOT_HOME/sparcv9/rdaemon $modnum $majnum $RDAC_DR_TO &
			else
				priocntl -e -c RT $RM_BOOT_HOME/rdaemon $modnum $majnum $RDAC_DR_TO &
			fi
			sleep 3
			nbr_dmns=`/bin/ps -e | grep rdaemon | grep -v grep | wc -l`
		fi
		if [ $nbr_dmns -eq 2 ]
		then
			echo "RDAC daemons initiated" 
		elif [ $nbr_dmns -eq 1 ]
		then
			echo "Warning: There is $nbr_dmns RDAC daemon running (should be 2)."
		else
			echo "Warning: There are $nbr_dmns RDAC daemons running (should be 2)."
		fi
	fi
fi

/etc/raid/bin/rdac_disks

/etc/raid/bin/set_drivers

if [ $OSrel = "2.6" -o $OSrel = "2.5.1" ]
then
	# Try to unload drivers. If they're attached to something, they won't unload.
	sd_number=`modinfo | grep " sd" | cut -c1-3` 2>/dev/null
	modunload -i $sd_number 2>/dev/null
	ssd_number=`modinfo | grep " ssd" | cut -c1-3` 2>/dev/null
	modunload -i $ssd_number 2>/dev/null
fi

MutexRelease /tmp/mutex.hot_add	# End of critical region



exit 0
