#! /bin/sh # Copyright (c) 1996 - 2007 SuSE GmbH Nuernberg, Germany. All rights reserved. # # Author: Florian La Roche , 1996 # Werner Fink , 1996,98 # Burchard Steinbild , 1997 # Thorsten Kukuk , 2000,01 # # /etc/init.d/nfsserver # ### BEGIN INIT INFO # Provides: nfsserver # Required-Start: $network $named $portmap # Required-Stop: $network $portmap # Should-Start: ypbind krb5kdc # Should-Stop: ypbind krb5kdc # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: Start the kernel based NFS daemon ### END INIT INFO . /etc/sysconfig/nfs # Shell functions sourced from /etc/rc.status: # rc_check check and set local and overall rc status # rc_status check and set local and overall rc status # rc_status -v ditto but be verbose in local rc status # rc_status -v -r ditto and clear the local rc status # rc_failed set local and overall rc status to failed # rc_failed set local and overall rc status to # rc_reset clear local rc status (overall remains) # rc_exit exit appropriate to overall rc status . /etc/rc.status # First reset status of this service rc_reset # Return values acc. to LSB for all commands but status: # 0 - success # 1 - generic or unspecified error # 2 - invalid or excess argument(s) # 3 - unimplemented feature (e.g. "reload") # 4 - insufficient privilege # 5 - program is not installed # 6 - program is not configured # 7 - program is not running # # Note that starting an already running service, stopping # or restarting a not-running service as well as the restart # with force-reload (in case signalling is not supported) are # considered a success. # XXX: there should be separate init scripts for these really SVCGSSD_BIN=/usr/sbin/rpc.svcgssd GSSD_BIN=/usr/sbin/rpc.gssd IDMAPD_BIN=/usr/sbin/rpc.idmapd NFSD_BIN=/usr/sbin/rpc.nfsd IDMAPD_CLIENT_STATE=/run/nfs/nfs-rpc.idmapd IDMAPD_SERVER_STATE=/run/nfs/nfsserver-rpc.idmapd NFSD_BIND_MOUNTS=/run/nfs/bind.mounts GSSD_CLIENT_STATE=/run/nfs/nfs-rpc.gssd GSSD_SERVER_STATE=/run/nfs/nfsserver-rpc.gssd NEED_SVCGSSD=no NEED_IDMPAPD=no case `uname -r` in 0.*|1.*|2.0.*) exit 3 esac case $NFS_SECURITY_GSS in [Nn]*) flavors="";; [Yy]*) flavors=krb5;; *) flavors="$NFS_SECURITY_GSS";; esac if [ "$flavors" ]; then NEED_SVCGSSD=yes fi if [ "$NFS4_SUPPORT" = yes ]; then NEED_IDMAPD=yes fi if [ -z "$RPC_PIPEFS_DIR" ]; then RPC_PIPEFS_DIR=/var/lib/nfs/rpc_pipefs fi case "$NFS4_SERVER_MINOR_VERSION" in [0123456789] ) ;; * ) NFS4_SERVER_MINOR_VERSION=0 esac check_for_nfsdfs() { HAVE_NFSDFS="no" while read dummy type ; do if [ "$type" = "nfsd" ] ; then HAVE_NFSDFS="yes" fi done < /proc/filesystems } nfs4_bind_mounts() { [ -d /run/nfs ] || mkdir /run/nfs warned=no # In case of doubt, try "man sed" :-) cat /etc/exports | sed -n 'H;g;s/\\$//;h;t;s/^\n//;s/\n[[:space:]]*//g;s/#.*//;p;s/.*//;h' | sed 's/^\([^[:space:]]*\).*bind=\([^,)]*\).*/\1 \2/;t;d' | sort | while read export dir; do if [ $warned = no ] ; then echo echo "NFS: The usage of 'bind=' in /etc/exports is deprecated." echo "NFS: Is it no longer needed and may cease to work." echo "NFS: Please remove these settings." warned=yes fi >&2 test -d "$export" || mkdir -p "$export" mount -o bind "$dir" "$export" echo "$dir" "$export" done > $NFSD_BIND_MOUNTS } nfs4_unbind_mounts() { sort -r -k2 $NFSD_BIND_MOUNTS | while read src mountpoint crap; do [ -n "$mountpoint" ] && umount -l "$mountpoint" done > $NFSD_BIND_MOUNTS } mount_rpc_pipefs() { # See if the file system is there yet case `stat -c "%t" -f "$RPC_PIPEFS_DIR"` in *67596969*) return 0;; esac mount -t rpc_pipefs rpc_pipefs "$RPC_PIPEFS_DIR" } umount_rpc_pipefs() { case `stat -c "%t" -f "$RPC_PIPEFS_DIR"` in *67596969*) umount "$RPC_PIPEFS_DIR";; esac } do_start_svcgssd() { for flavor in $flavors; do /sbin/modprobe rpcsec_gss_$flavor done mount_rpc_pipefs startproc $SVCGSSD_BIN $SVCGSSD_OPTIONS return $? } do_start_gssd() { if ! checkproc $GSSD_BIN; then case $NFS_GSSD_AVOID_DNS in [Nn]*) ignore_dns=-D ;; [Yy]*) ignore_dns= ;; * ) ignore_dns=-D esac mount_rpc_pipefs startproc $GSSD_BIN $ignore_dns $GSSD_OPTIONS -p $RPC_PIPEFS_DIR return $? fi } do_start_idmapd() { mount_rpc_pipefs if checkproc $IDMAPD_BIN && test -f $IDMAPD_CLIENT_STATE; then killproc -HUP $IDMAPD_BIN else startproc $IDMAPD_BIN -p $RPC_PIPEFS_DIR return $? fi } case "$1" in start) PARAMS=3 test "$USE_KERNEL_NFSD_NUMBER" -gt 0 && PARAMS="$USE_KERNEL_NFSD_NUMBER" echo -n "Starting kernel based NFS server:" modprobe nfsd # this can be removed when modprobe allows the sysctl to be # moved to modprobe.d without breaking --show-depends grep '^fs.nfs.n[sl]m' /etc/sysctl.conf | sysctl -q -e -n -p - # mount nfsd filesystem check_for_nfsdfs if [ "$HAVE_NFSDFS" = "yes" -a ! -f /proc/fs/nfsd/exports ] ; then mount -t nfsd nfsd /proc/fs/nfsd rc_status fi VERSION_PARAMS= if [ "$NFS3_SERVER_SUPPORT" == "no" ]; then VERSION_PARAMS="--no-nfs-version 2 --no-nfs-version 3" fi if [ "$NFS4_SUPPORT" != "yes" ]; then VERSION_PARAMS="--no-nfs-version 4" fi if [ "$NFS4_SERVER_MINOR_VERSION" != "0" ]; then VERSION_PARAMS="$VERSION_PARAMS --nfs-version 4 --nfs-version 4.$NFS4_SERVER_MINOR_VERSION" fi if [ -n "$NFSV4LEASETIME" -a -f /proc/fs/nfsd/nfsv4leasetime ]; then echo "$NFSV4LEASETIME" > /proc/fs/nfsd/nfsv4leasetime fi nfs4_bind_mounts # svcgssd; gssd; idmapd if [ "$NEED_SVCGSSD" = yes ]; then echo -n " svcgssd" do_start_svcgssd || { rc_status -v rc_exit } echo -n " gssd" do_start_gssd || { rc_status -v rc_exit } echo $GSSD_BIN > $GSSD_SERVER_STATE fi if [ "$NEED_IDMAPD" = yes ]; then echo -n " idmapd" do_start_idmapd || { rc_status -v rc_exit } [ -d /run/nfs ] || mkdir /run/nfs echo $IDMAPD_BIN > $IDMAPD_SERVER_STATE fi # exportfs /usr/sbin/exportfs -r # rpc.mountd echo -n " mountd" if [ -n "$MOUNTD_PORT" ] ; then startproc /usr/sbin/rpc.mountd -p $MOUNTD_PORT $MOUNTD_OPTIONS $VERSION_PARAMS else startproc /usr/sbin/rpc.mountd $MOUNTD_OPTIONS $VERSION_PARAMS fi || { rc_status -v rc_exit } # rpc.statd if [ "$NFS3_SERVER_SUPPORT" != "no" ]; then echo -n " statd" startproc /usr/sbin/rpc.statd --no-notify $STATD_OPTIONS || { rc_status -v rc_exit } fi # rpc.nfsd echo -n " nfsd" $NFSD_BIN $NFSD_OPTIONS $PARAMS $VERSION_PARAMS || { rc_status -v rc_exit } # sm-notify needs to be run last echo -n " sm-notify" /usr/sbin/sm-notify $SM_NOTIFY_OPTIONS # rc_status -v ;; stop) echo -n "Shutting down kernel based NFS server:" # rpc.nfsd echo -n " nfsd" killproc -n -KILL nfsd || { rc_status -v rc_exit } # rpc.statd if ! checkproc -n lockd; then echo -n " statd" killproc rpc.statd else # tell lockd to drop all client locks killproc -n -KILL lockd fi # make sure sm-notify is run on restart, as we have dropped some locks rm -f /run/sm-notify.pid # # rpc.mountd echo -n " mountd" killproc -TERM /usr/sbin/rpc.mountd || { rc_status -v rc_exit } # svcgssd if [ "$NEED_SVCGSSD" = yes ]; then echo -n " svcgssd" killproc $SVCGSSD_BIN || { rc_status -v rc_exit } # kill only if not needed by client anymore if [ ! -f $GSSD_CLIENT_STATE ]; then echo -n " gssd" killproc $GSSD_BIN || { rc_status -v rc_exit } fi rm -f $GSSD_SERVER_STATE fi # idmap if [ "$NEED_IDMAPD" = yes ]; then # kill only if not needed by client anymore if [ ! -f $IDMAPD_CLIENT_STATE ]; then echo -n " idmapd" killproc $IDMAPD_BIN fi rm -f $IDMAPD_SERVER_STATE fi # umount rpc_pipefs only if not needed by client if [ ! -f $GSSD_CLIENT_STATE -a ! -f $IDMAPD_CLIENT_STATE ] ; then umount_rpc_pipefs fi # umount nfsd fs check_for_nfsdfs if [ "$HAVE_NFSDFS" = "yes" -a -f /proc/fs/nfsd/exports ] ; then umount /proc/fs/nfsd rc_status fi nfs4_unbind_mounts # rc_status -v ;; try-restart) ## Stop the service and if this succeeds (i.e. the ## service was running before), start it again. $0 status >/dev/null && $0 restart # Remember status and be quiet rc_status ;; restart) ## Stop the service and regardless of whether it was ## running or not, start it again. $0 stop $0 start # Remember status and be quiet rc_status ;; reload|force-reload) echo -n "Reload kernel based NFS server" # Unfortunately, there's no sane way of doing this: nfs4_unbind_mounts; nfs4_bind_mounts /usr/sbin/exportfs -r rc_status -v ;; status) echo -n "Checking for kernel based NFS server:" ## Check status with checkproc(8), if process is running ## checkproc will return with exit status 0. # Status has a slightly different for the status command: # 0 - service running # 1 - service dead, but /run/ pid file exists # 2 - service dead, but /var/lock/ lock file exists # 3 - service not running # NOTE: checkproc returns LSB compliant status values. if [ "$NEED_SVCGSSD" = yes ]; then echo -n " svcgssd" checkproc $SVCGSSD_BIN rc_status -v echo -n " gssd" checkproc $GSSD_BIN rc_status -v fi if [ "$NEED_IDMAPD" = yes ]; then echo -n " idmapd" checkproc $IDMAPD_BIN rc_status -v fi echo -n " mountd" checkproc /usr/sbin/rpc.mountd rc_status -v echo -n " statd" checkproc /usr/sbin/rpc.statd rc_status -v echo -n " nfsd" checkproc -n nfsd rc_status -v ;; *) echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}" exit 1 ;; esac rc_exit