#!/sbin/sh
#
# Copyright (c) 1999 by Sun Microsystems, Inc.
# All rights reserved.
#
#ident	"@(#)sv	1.11	00/06/21 SMI"

[ ! -d /usr/sbin -o ! -d /usr/bin ] && exit

#
# Start/stop Storage Volume driver
#

# constants

svadm=/usr/opt/SUNWesm/sbin/svadm
svcf=/etc/opt/SUNWspsv/sv.cf

# functions

umount_list()
{
	# <stdin> - list of special devices
	#
	# find all filesystems that need to be unmounted in order to
	# unmount these special devices, sorted in the correct order to
	# pass to umount

	tmp1=/tmp/um.1.$$
	tmp2=/tmp/um.2.$$

	rm -f $tmp1 $tmp2

	# read list from <stdin> and convert to mount points

	cat >$tmp1

	while read special mountp junk
	do
		if fgrep -s -- "$special" $tmp1 >/dev/null 2>&1
		then
			echo $mountp
		fi
	done </etc/mnttab >$tmp2

	# get the special devices for every mount point whose name
	# begins with that of a mount point that we need to unmount
	# eg. if we want to unmount /sv0, and there is also a /sv0/sv2
	# mount point, then the list of special devices must include
	# both (we cannot unmount /sv0 without first unmounting
	# /sv0/sv2)

	while read mountp
	do
		grep "[ 	]$mountp" /etc/mnttab
	done <$tmp2 | awk '{ print $1 }' >$tmp1

	# sort the list into reverse mnttab order to give to umount,
	# and display on <stdout>

	tail -r /etc/mnttab |
		while read special junk
		do
			if fgrep -s -- "$special" $tmp1 >/dev/null 2>&1
			then
				echo $special
			fi
		done

	rm -f $tmp1 $tmp2
}

# main program

if [ ! -x $svadm ]
then
	echo "$0: cannot find $svadm"
	exit 1
fi

case "$1" in
'start')
	if [ -f $svcf -a -x $svadm ]
	then
		echo 'starting SV layering'
		$svadm -e -f $svcf
	fi
	;;

'stop')
	if [ -x $svadm -a -r /dev/sv ]
	then
		#
		# Unmount all filesystems using the sv devices
		#

		# grab list of configured sv devices

		svfiles=`$svadm 2>/dev/null | \
				awk '{print $1}' - | \
				sed -e 's!/rdsk/!/dsk/!'`

		# get list of the special devices for the filesystems
		# mounted on the sv devices that need to be unmounted
		# (ie. ii and rdc devices)

		tmpfile=/tmp/k$$
		splist=

		rm -f $tmpfile

		while read special junk
		do
			if [ `echo "$svfiles" | \
				fgrep -c -- "$special"` -gt 0 ]
			then
				echo $special
			fi

		done </etc/mnttab >$tmpfile

		# if there are filesystems that need to be unmounted, then
		# kill all procs using them and unmount them.

		if [ -s $tmpfile ]
		then
			splist=`umount_list <$tmpfile`

			rm -f $tmpfile

			echo 'unmounting filesystems mounted on SV devices'

			# polite kill of procs using the filesystems

			pids=`/usr/sbin/fuser $splist 2>/dev/null`
			if [ -n "$pids" ]
			then
				/usr/bin/kill -15 $pids
				/usr/bin/sleep 5
			fi

			# hard kill of everyone using the filesystems

			/usr/sbin/fuser -k $splist >/dev/null 2>&1
			/usr/bin/sleep 10

			# umount filesystems in the correct order

			/sbin/sync ; /sbin/sync ; /sbin/sync
			for s in $splist
			do
				/sbin/umount $s
			done
		fi

		echo 'stopping SV layering'

		$svadm -d
	fi
	;;

*)
	echo "Usage: $0 { start | stop }"
	exit 1
	;;
esac
