#! /bin/bash
# Copyright (c) 1996-2002 SuSE Linux AG, Nuernberg, Germany.
# All rights reserved.
#
# Author: Florian La Roche, 1996
#      Werner Fink <werner@suse.de>, 1996
#      Burchard Steinbild, 1996
#
# Please send feedback to http://www.suse.de/feedback
#
# /etc/init.d/nfs
#
### BEGIN INIT INFO
# Provides:       nfs
# Required-Start: $network $portmap
# Required-Stop:
# Default-Start:  3 5
# Default-Stop:
# Short-Description: NFS client services 
# Description:    All necessary services for NFS clients
### END INIT INFO

. /etc/rc.status
. /etc/sysconfig/nfs

IDMAPD_BIN=/usr/sbin/rpc.idmapd
GSSD_BIN=/usr/sbin/rpc.gssd

IDMAPD_CLIENT_STATE=/var/lock/subsys/nfs-rpc.idmapd
IDMAPD_SERVER_STATE=/var/lock/subsys/nfsserver-rpc.idmapd

NEED_IDMAPD=no
NEED_GSSD=no
nfs=no
NEED_LDCONFIG=no

while read  where what type options rest  ; do
    case "$where" in
	\#*|"") ;;
	*) case "$options" in
	    *noauto*) ;;
	    *) if test "$type" = "nfs" -o "$type" = "nfs4" ; then
		    nfs=yes
		    case "$where" in
			/usr*|/opt*)
				NEED_LDCONFIG=yes
				break
				;;
			*)
				if grep -q "^$where" /etc/ld.so.conf; then
				    NEED_LDCONFIG=yes
				    break;
				fi
				;;
		    esac
		fi ;;
	    esac
    esac
done < /etc/fstab

case $NFS_SECURITY_GSS in
  [Nn]*)        flavors="";;
  [Yy]*)        flavors=krb5;;
  *)            flavors="$NFS_SECURITY_GSS";;
esac

if [ "$flavors" ]; then
    NEED_GSSD=yes
fi

if [ "$NFS4_SUPPORT" = yes ]; then
    NEED_IDMAPD=yes
fi

mount_rpc_pipefs() {
    # See if the file system is there yet
    case `stat -c "%t" -f /var/lib/nfs/rpc_pipefs` in
    *67596969*)
        return 0;;
    esac

    mount -t rpc_pipefs rpc_pipefs /var/lib/nfs/rpc_pipefs
}

mount_usr() {
	while read  where what type options rest  ; do
	    case "$where" in
		\#*|"") ;;
		*) case "$options" in
		    *noauto*) ;;
		    *) if test "$type" = "nfs" -o "$type" = "nfs4" ; then
			    case "$where" in
				/usr*)
					mount -o nolock $where	
					break
					;;
			    esac
			fi ;;
		    esac
	    esac
	done < /etc/fstab
}

do_start_gssd() {
    for flavor in $flavors; do
        /sbin/modprobe rpcsec_gss_$flavor
    done

    mount_rpc_pipefs
    startproc $GSSD_BIN
    return $?
}

do_start_idmapd() {
    mount_rpc_pipefs

    # as idmapd needs to be run be server and client
    # check if there is already a idmapd running
    if checkproc $IDMAPD_BIN && test -f $IDMAPD_SERVER_STATE; then
        killproc -HUP $IDMAPD_BIN
    else
        startproc $IDMAPD_BIN
    fi
    return $?
}

rc_reset
case "$1" in
    start|reload)
	echo -n "Starting NFS client services:"
	# in case we need /usr via nfs 
	mount_usr
	# sm-notify
	echo -n " sm-notify"
	/usr/sbin/sm-notify
	# gssd
	if [ "$NEED_GSSD" = yes ]; then
 	    echo -n " gssd"
	    do_start_gssd
	    if [ $? != 0 ]; then
	        rc_status -v
	        rc_exit
	    fi
	fi
	# idmapd
	if [ "$NEED_IDMAPD" = yes ]; then
	    echo -n " idmapd"
	    do_start_idmapd
	    if [ $? != 0 ]; then
	        rc_status -v
	        rc_exit
	    fi
            echo $IDMAPD_BIN > $IDMAPD_CLIENT_STATE
	fi
	# statd is started when needed by mount.nfs
	#
	if test "$nfs" = yes ; then
	# Mount all auto NFS devices (-> nfs(5) and mount(8) )
	#  NFS-Server sometime not reachable during boot phase.
	#  It's sometime usefull to mount NFS devices in
	#  background with an ampersand (&) and a sleep time of
	#  two or more seconds, e.g:
	#  
	#   sleep 2 && mount -at nfs,nfs4 &
	#   sleep 2 
	#  
	#  Note: Some people importing the /usr partition.
	#        Therefore we do _NOT_ use an ampersand!
	#
          mount -at nfs,nfs4 > /dev/null 2>&1
	#
    	# generate new list of available shared libraries
	#
	  if test "$NEED_LDCONFIG" = yes; then
	      rc_status
	      sleep 1
	      # check if ld.so.cache needs to be refreshed
	      /etc/init.d/boot.ldconfig start > /dev/null 2>&1
	  fi
	fi
	#
	rc_status -v
	;;
    stop)
	echo -n "Shutting down NFS client services:"
	if test "$nfs" = "yes" ; then
	  #
	  # Unmount in background because during long timeouts
	  #
	  umount -at nfs,nfs4 &
	  sleep 2
	fi
	#
	if [ "$NEED_GSSD" = yes ]; then
	    echo -n " gssd"
	    killproc $GSSD_BIN
	    if [ $? != 0 ]; then
	        rc_status -v
	        rc_exit
	    fi
	fi
	#
	if [ "$NEED_IDMAPD" = yes ]; then
	    # only stop idmapd if it is not needed by server
	    if [ ! -f $IDMAPD_SERVER_STATE ]; then
	        echo -n " idmapd"
	        killproc $IDMAPD_BIN
	        if [ $? != 0 ]; then
	            rc_status -v
	            rc_exit
	        fi
	    fi
	    rm -f $IDMAPD_CLIENT_STATE
	fi 
	#
	rc_status -v
	;;
    restart|force-reload)
        ## Stop the service and regardless of whether it was
	## running or not, start it again.
	$0 stop
	$0 start
	rc_status
	;;
    status)
	echo -n "Checking for mounted nfs shares (from /etc/fstab):"
	if test "$nfs" = "yes" ; then
	  while read  where what type options rest  ; do
	    case "$where" in
	      \#*|"") ;;
	      *) case "$options" in
		   *noauto*) ;;
		   *) if test "$type" = "nfs" -o "$type" = "nfs4" ; then
			grep -q "$where $what nfs" /proc/mounts || rc_failed 3
		      fi ;;
		 esac
	    esac
          done < /etc/fstab
        else
	  rc_failed 3
	fi
	#
	if [ "$NEED_GSSD" = yes ] && ! checkproc $GSSD_BIN; then
	   echo "gssd not running"
	   rc_failed 3
	fi
	# 
	if [ "$NEED_IDMAPD" = yes ] && ! checkproc $IDMAPD_BIN; then
	    echo "idmapd not running"
	    rc_failed 3
	fi
        rc_status -v
	;;
    try-restart|condrestart)
	$0 status
	if test $? = 0; then
	    $0 restart
	else
	    rc_reset
	fi
	rc_status
	;;
    *)
	echo "Usage: $0 {start|stop|status|reload|force-reload|restart|try-restart}"
	exit 1
esac
rc_exit
