#!/bin/bash
#*****************************************************************************
# Copyright 2007 LSI Logic Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation,  version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#*****************************************************************************
#
#  Script %name:	mppiscsi_umountall %
#  Instance:		WIC_1
#  %version:		6 %
#  Description:		kill processes and umount mpp file systems before iscsi 
#  %created_by:		shebsur %
#  %date_created:	Fri Jan 25 16:05:08 2008 %

function usage ()
{
	echo "usage: `basename $0` [-t] [-k] [-u] [-rN] [-h] [-v]" >&2
	echo "       where t=terminate processes politely, k=kill processes rudely" >&2
	echo "             u=unload mppVhba driver, rN=retry N times" >&2
	echo "             h=show this help, v=verbose" >&2
	echo "" >&2
}

# defaults
terminate=
kill=
unload=
retries=2
verbose=
noniscsiarray=0

# get arguments
while getopts :tkur:vh c
do
	case $c in
	t) terminate="yes";;
	r) retries=$OPTARG;;
	u) unload="yes";;
	k) kill="yes";;
	v) verbose="yes";;
	h) usage; 
	   exit 2;;
	*) usage;
	   exit 2;;
	esac
done
shift $((OPTIND-1))

function ismppiscsi()
{
	# returns 0 if mpp is using iscsi, 1 if it is not
	for array in /proc/mpp/* ; do 
		if [ -d $array ] ; then
			noniscsiarray=`ls -l /proc/mpp/*/controller* 2> /dev/null | grep "^d" | grep -v -c iscsi`
			iscsiarray=`ls -l /proc/mpp/*/controller* 2> /dev/null | grep "^d" | grep -c iscsi`
		fi
	done

	#if we have both iscsi and noniscsi array return no iscsi
	if [ $iscsiarray -eq 0 ] || [ $noniscsiarray != 0 ]; then
		return 1 #no iscsi found
	else
		return 0
	fi
}

#Main MAIN main

if lsmod | grep -q mppVhba ; then
	if ! ismppiscsi ; then
		[ "$verbose" ] && echo "No mpp iscsi arrays found"
		exit 0
	else
		[ "$verbose" ] && echo "mpp iscsi arrays found"
	fi
else
	[ "$verbose" ] && echo "mppVhba driver module is not loaded"
	exit 0
fi

retval=0
tries=0
while [ $tries -le $retries ]
do

	mppdevs=$(/opt/mpp/lsvdev 2>/dev/null | awk '{ if (/\/dev\//) printf("%s\n",$4) }')

	if [ "$terminate" ] || [ "$kill" ] ; then
	[ "$verbose" ] && echo -n "Stopping mpp-iscsi processes: "


	for i in $mppdevs; do
		for slice in $i $i[0-9]* ; do
			if fuser -m $slice >/dev/null 2>/dev/null ; then
				# Someone is using the file system
				if [ "$terminate" ] || [ "$kill" ] ; then # send SIGTERM
					[ "$verbose" ] && echo -n "$slice "
					if fuser -k -TERM -m $slice > /dev/null 2> /dev/null ; then
						[ "$verbose" ] && echo -n "T "
						sleep 5
					fi
					if [ "$kill" ]; then # send SIGKILL
						if fuser -k -m $slice > /dev/null 2> /dev/null ; then
							[ "$verbose" ] && echo -n "K "
							sleep 2
						fi
					fi
					#Is it dead?
					if fuser -m $slice >/dev/null 2>/dev/null ; then
						[ "$verbose" ] && echo -n "failed "
						retval=$((retval|1))
					else
						[ "$verbose" ] && echo -n "success "
					fi
				fi
			fi
			if fuser $slice >/dev/null 2>/dev/null ; then
				# someone is using the raw device
				if [ "$terminate" ] || [ "$kill" ] ; then # send SIGTERM
					[ "$verbose" ] && echo -n "$slice "
					if fuser -k -TERM $slice > /dev/null 2> /dev/null ; then
						[ "$verbose" ] && echo -n "T "
						sleep 5
					fi
					if [ "$kill" ]; then # SIGKILL
						if fuser -k $slice > /dev/null 2> /dev/null ; then
							[ "$verbose" ] && echo -n "K "
							sleep 2
						fi
					fi
					#did it work?
					if fuser $slice >/dev/null 2>/dev/null ; then
						[ "$verbose" ] && echo -n "failed "
						retval=$((retval|2))
					else
						[ "$verbose" ] && echo -n "success "
					fi
				fi
			fi
		done
	done
	[ "$verbose" ] && echo "done"
	fi

	[ "$verbose" ] && echo -n "issuing sync: "
	sync
	[ "$verbose" ] && echo "done"

	[ "$verbose" ] && echo -n "Umounting mppiscsi file systems: "
	for i in $mppdevs; do
		for slice in $i $i[0-9]* ; do
			if grep -q "^$slice " /etc/mtab ; then
				[ "$verbose" ] && echo -n " $slice "
				if umount $slice > /dev/null 2>/dev/null ; then
					[ "$verbose" ] && echo -n "success "
				else
					[ "$verbose" ] && echo -n "failed "
					retval=$((retval|4))
				fi
			fi
		done 
	done
	sleep 4
	[ "$verbose" ] && echo "done"

	[ "$verbose" ] && echo -n "issuing sync: "
	sync
	[ "$verbose" ] && echo "done"


	if [ "$unload" ] ; then # Try to unload the mppVhba driver
		[ "$verbose" ] && echo -n "Unloading mppVhba driver: "
		if rmmod mppVhba 2>/dev/null ; then
			[ "$verbose" ] && echo "success on retry $tries."
			exit 0
		else
			[ "$verbose" ] && echo "failed"
			retval=$((retval|8))
		fi
	else
		#Just trying to get usage count down to zero
		mppusecount=$(lsmod | awk '{if (/^mppVhba/) printf("%d\n",$3)}')
		if [ $mppusecount -eq 0 ] ; then
			[ "$verbose" ] && echo "success on retry $tries."
			exit 0
		fi
	fi

	tries=$((tries+1))
done


exit $retval

