#!/bin/sh
. /etc/profile
bsname=${0##/*/}

psax="ps"
NICE_VALUE="20"

if [ ! -r /etc/exports ]; then
	echo "/etc/exports does not exist, create a bare-bones version and continue" >> /tmp/michael.txt
	touch /etc/exports
	chmod u+rw,g+r,o+r /etc/exports
fi

start_nfs() {
	runportmap=`${psax}|grep -v grep|grep portmap`
	if [ "${runportmap}" == "" ]; then
		nice -n ${NICE_VALUE} portmap
	fi

	#Use the build-in modules to instead of nfsd.ko and exportfs.ko
	#lsmod_out=`lsmod`
	#for i in exportfs nfsd; do
	#	needins=`echo "${lsmod_out}"|grep ${i}`
	#	if [ "${needins}" == "" ]; then
	#		insmod /usr/local/zy-pkgs/lib/modules/${i}.ko
	#	fi
	#done

	mountnfsd=`cat /proc/mounts|grep /proc/fs/nfsd`
	if [ "${mountnfsd}" == "" ]; then
		mount -t nfsd nfsd /proc/fs/nfsd
	fi
	echo -n "Starting NFS:"
	#Start Steps from README

	#A/  mount -t nfsd nfsd /proc/fs/nfsd
	#I do it in rcS

	#B/ svcgssd ; idmapd
	#svcgssd is only needed if exportfs NFS filesystem with crypto-security (Kerberos or SPKM3).
	#echo -n " rpc.svcgssd"; rpc.svcgssd
	#idmapd is only needed for NFSv4 support
	#echo -n " rpc.idmapd"; rpc.idmapd

	#C/ exportfs -av ; rpc.mountd
	#It is important that exportfs be run before mountd so that mountd is working from current information (in /var/lib/nfs/etab)
	echo " exportfs"; exportfs -arv
	#any NFS requests that arrive before mountd is started will get replied to with a 'Stale NFS File handle' error.
	echo -n " rpc.mountd"; nice -n ${NICE_VALUE} rpc.mountd

	#D/ rpc.statd --no-notify
	#If notify requests are sent out before nfsd start, clients may try to reclaim locks and, on finding that lockd isn't running
	#, they will give up and never reclaim the lock. rpc.statd is only needed for NFSv2 and NFSv3 support.
	#Michael: prevent rpc.statd take port 2049, I start it after nfsd
	#	rpc.statd 1246   nobody    8u  IPv4   2189       UDP *:2049
	#echo -n " rpc.statd"; rpc.statd --no-notify

	#E/ rpc.nfsd
	#When nfsd starts it will start lockd. If lockd then receives a lock request it will communicate with statd.
	echo -n " rpc.nfsd"; nice -n ${NICE_VALUE} rpc.nfsd
	echo -n " rpc.statd"; nice -n ${NICE_VALUE} rpc.statd --no-notify

	#F/ sm-notify
	#This will notify any client which might have locks from before a reboot to try to reclaim their locks.
	#sm-notify is only needed for NFSv2 and NFSv3 support.
	echo -n " sm-notify"; nice -n ${NICE_VALUE} sm-notify

	result=`${psax}|grep nfsd|grep -v grep`
	if [ "${result}" == "" ]; then
		rm -f /etc/zyxel/storage/enable_nfs.flag
		echo ": failed"
	else
		echo ": done"
	fi
}
stop_nfs() {
	echo -n "Shutting down NFS:"
	killall sm-notify 2>/dev/null
	killall rpc.statd 2>/dev/null
	echo -n " rpc.mountd"; killall rpc.mountd
	echo -n " nfsd"; kill `${psax}|grep nfsd|grep -v grep|awk '{print $1}'`
	echo -n " exportfs"; exportfs -auv
	#killall rpc.idmapd 2>/dev/null
	#killall rpc.svcgssd 2>/dev/null

	mountdpid=`${psax}|grep mountd|grep -v grep|awk '{print $1}'`
	nfsdpid=`${psax}|grep nfsd|grep -v grep|awk '{print $1}'`
	killcount=1
	if [ "${mountdpid}" != "" ] || [ "${nfsdpid}" != "" ]; then
		busy=1
		kill -9 ${mountdpid} ${nfsdpid} 2>/dev/null
	else
		busy=0
	fi
	#while [ ${killcount} -le 9 ] && [ "${busy}" == "1" ]; do
	while [ ${killcount} -le 2 ] && [ "${busy}" == "1" ]; do
		sleep ${killcount}
		killcount=$(($killcount + 1))
		mountdpid=`${psax}|grep mountd|grep -v grep|awk '{print $1}'`
		nfsdpid=`${psax}|grep nfsd|grep -v grep|awk '{print $1}'`
		if [ "${mountdpid}" != "" ]; then
			busy=1
			sleep 1
			echo -n [mountd busy] kill -9 ${mountdpid}; kill -9 ${mountdpid} 2>/dev/null
		else
			if [ "${nfsdpid}" != "" ]; then
				busy=1
				sleep 1
				echo -n [nfsd busy] kill -9 ${nfsdpid}; kill -9 ${nfsdpid} 2>/dev/null
			else
				busy=0
			fi
		fi
	done

	checkportmap=`${psax}|grep portmap|grep -v grep`
	checkportcount=1
	
	while [ "${checkportmap}" != "" ] && [ ${checkportcount} -le 3 ];do
		killall portmap 2>/dev/null
		sleep ${checkportcount}
	        checkportcount=$(($checkportcount + 1))
	        checkportmap=`${psax}|grep portmap|grep -v grep`
	done

	if [ "${checkportmap}" == "" ];then
	        echo ": done"
	else
	        echo ": failed"
	fi
}

case "$1" in
	startup)
		NICE_VALUE="17"
		#zyshclient -p 150 -e "nfs start"
		if [ -e /etc/zyxel/storage/enable_nfs.flag ]; then
			start_nfs
		else
			echo "${bsname}:no action"
		fi
		;;
	shutdown)
		#zyshclient -p 150 -e "nfs stop"
		stop_nfs
		;;
	enable)
		NICE_VALUE="20"
		#zyshclient -p 150 -e "nfs enable"
		start_nfs
		touch /etc/zyxel/storage/enable_nfs.flag
		;;
	disable)
		#zyshclient -p 150 -e "nfs disable"
		stop_nfs
		rm -f /etc/zyxel/storage/enable_nfs.flag
		;;
	status)
		echo "Built-in"
		;;
	getlink)
		echo "NFS/NFS.html"
		;;
	start)
		NICE_VALUE="20"
		mountdpid=`${psax}|grep mountd|grep -v grep|awk '{print $1}'`
		nfsdpid=`${psax}|grep nfsd|grep -v grep|awk '{print $1}'`
		if [ "${mountdpid}" != "" ] || [ "${nfsdpid}" != "" ]; then
			stop_nfs
			start_nfs
		else
			start_nfs
		fi
		;;
	stop)
		stop_nfs
		;;
	restart)
		NICE_VALUE="20"
		stop_nfs
		start_nfs
		;;
	*)
		echo $"Usage: nfs {start|stop|restart}"
		exit 1
		;;
esac

exit 0
