#!/bin/sh
#
# nfs           This shell script takes care of starting and stopping
#               the NFS services.
#
# chkconfig:    345 60 20
# description:  NFS is a popular protocol for file sharing across TCP/IP \
#               networks. This service provides NFS server functionality, \
#               which is configured via the /etc/exports and /etc/sysconfig/nfs files.

WITHOUT_RC_COMPAT=1

# Source function library.
. /etc/init.d/functions

# Source networking configuration.
# Check that networking is up.
SourceIfNotEmpty /etc/sysconfig/network && [ "$NETWORKING" != no ] || exit

NFSD=/usr/sbin/rpc.nfsd
MOUNTD=/usr/sbin/rpc.mountd
SVCGSSD=/usr/sbin/rpc.svcgssd
RQUOTAD=/usr/sbin/rpc.rquotad
EXPORTFS=/usr/sbin/exportfs

NFSDFS=/proc/fs/nfsd
RPCPIPEFS=/var/lib/nfs/rpc_pipefs

EXPORTS=/etc/exports
KEYTAB=/etc/krb5.keytab
GSSAPI_MECH=/etc/gssapi_mech.conf

[ -x "$NFSD" -a -x "$MOUNTD" -a -x "$EXPORTFS" -a -f "$EXPORTS" ] || exit

SourceIfNotEmpty /etc/sysconfig/nfs

LOCKFILE=/var/lock/subsys/nfs
RETVAL=0

start_mountd()
{
    [ -n "$MOUNTD_PORT" ] && \
	MOUNTD_OPTIONS="$MOUNTD_OPTIONS -p $MOUNTD_PORT"
    is_no "$MOUNTD_TCP" && \
	MOUNTD_OPTIONS="$MOUNTD_OPTIONS -n"
    is_no "$MOUNTD_NFS_V2" && \
	MOUNTD_OPTIONS="$MOUNTD_OPTIONS -N 2"
    is_no "$MOUNTD_NFS_V3" && \
	MOUNTD_OPTIONS="$MOUNTD_OPTIONS -N 3"

    msg_starting $"NFS mount"
    start_daemon --no-announce -- $MOUNTD $MOUNTD_OPTIONS
}

start_rquotad()
{
    [ -x "$RQUOTAD" ] || return 0
    msg_starting $"NFS quotas"
    start_daemon --no-announce -- $RQUOTAD
}

start_svcgssd()
{
    [ -d /sys/class ] || return 0
    [ -x "$SVCGSSD" ] || return 0
    is_yes "$SECURE_NFS" || return 0

    [ -f "$KEYTAB" -a -f "$GSSAPI_MECH" ] || return 1

    [ -d "$RPCPIPEFS/nfs" ] || {
	modprobe sunrpc ||:
	mount -t rpc_pipefs rpc_pipefs "$RPCPIPEFS"
	RETVAL=$?
	[ $RETVAL -eq 0 ] || return $RETVAL
    }

    [ -f /proc/net/rpc/auth.rpcsec.context/channel ] || {
	modprobe des ||:
	modprobe auth_rpcgss ||:
	modprobe rpcsec_gss_krb5 ||:
    }
    msg_starting $"NFS svcgssd"
    start_daemon --no-announce -- $SVCGSSD
}

start_nfsd()
{
    action $"Starting NFS daemon:" $NFSD ${NFSD_OPTIONS} ${NFSDCOUNT:-8}
}

stop_mountd()
{
    msg_stopping $"NFS mount"
    stop_daemon --no-announce -- $MOUNTD
}

stop_rquotad()
{
    [ -x "$RQUOTAD" ] || return 0
    msg_stopping $"NFS quotas"
    stop_daemon --no-announce -- $RQUOTAD
}

stop_svcgssd()
{
    [ -d /sys/class ] || return 0
    [ -x "$SVCGSSD" ] || return 0
    is_yes "$SECURE_NFS" || return 0
    
    msg_stopping $"NFS svcgssd"
    stop_daemon --no-announce -- $SVCGSSD
}

stop_nfsd()
{
    action $"Stopping NFS daemon:" start-stop-daemon -qoK -s2 -u0 -n nfsd
}

start()
{
    # Don't start anything when exports is empty
    [ -s "$EXPORTS" ] || return

    [ -f "$NFSDFS/exports" ] || mount -t nfsd nfsd "$NFSDFS"
    action $"Exporting NFS file systems:" $EXPORTFS -r

    start_rquotad
    RETVAL=$?
    [ $RETVAL -eq 0 ] || return

    start_svcgssd
    RETVAL=$?
    [ $RETVAL -eq 0 ] || return

    start_nfsd
    RETVAL=$?
    [ $RETVAL -eq 0 ] || return
	
    start_mountd
    RETVAL=$?
    [ $RETVAL -eq 0 ] || return

    service idmapd condreload
    RETVAL=$?
    [ $RETVAL -eq 0 ] || return

    touch "$LOCKFILE"
    return $RETVAL
}

stop()
{
    stop_mountd

    stop_nfsd

    stop_svcgssd

    stop_rquotad

    # Do it the last so that clients can still access the server
    # when the server is running.
    action $"Unexporting NFS file systems:" $EXPORTFS -au
    RETVAL=$?
    [ $RETVAL -eq 0 ] && rm -f "$LOCKFILE"
    return $RETVAL
}

restart()
{
    stop
    start
}

reload()
{
    action $"Reexporting NFS file systems:" $EXPORTFS -r
    RETVAL=$?
    [ $RETVAL -eq 0 ] && touch "$LOCKFILE"
    return $RETVAL
}

statuses()
{
    status $MOUNTD

    [ -x "$RQUOTAD" ] && status $RQUOTAD

    status $SVCGSSD

    # FIXME better way ?
    start-stop-daemon -Ktq -n nfsd > /dev/null && echo nfsd is running || echo nfsd is stopped

    RETVAL=$?
}

# See how we were called.
case "$1" in
    start)
	start
	;;
    stop)
	stop
	;;
    restart)
	restart
	;;
    reload)
	reload
	;;
    condstop)
	if [ -e "$LOCKFILE" ]; then
	    stop
	fi
	;;
    condrestart)
	if [ -e "$LOCKFILE" ]; then
	    restart
	fi
	;;
    status)
	statuses
	;;
    *)
	msg_usage "${0##*/} {start|stop|reload|restart|condstop|condrestart|status}"
	RETVAL=1
esac

exit $RETVAL
